aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-07-23 18:28:05 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-07-23 18:28:05 +0000
commit7731e84e7ec203bea2bf07a273354b78ff853ba0 (patch)
tree0ca33f701cbac984f561bacd9fef3701d8c76eda
parent0baa9d1d59bf17177e80838ebe66df10a7a909c0 (diff)
parent40768ee0bc9965d109692f884f8588626e01e3fe (diff)
downloadgcc-7731e84e7ec203bea2bf07a273354b78ff853ba0.zip
gcc-7731e84e7ec203bea2bf07a273354b78ff853ba0.tar.gz
gcc-7731e84e7ec203bea2bf07a273354b78ff853ba0.tar.bz2
Merge from trunk revision 273743.
From-SVN: r273744
-rw-r--r--ChangeLog13
-rw-r--r--config/ChangeLog4
-rw-r--r--config/bootstrap-Og.mk1
-rw-r--r--gcc/ChangeLog3641
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog2171
-rw-r--r--gcc/ada/Makefile.rtl42
-rw-r--r--gcc/ada/adabkend.adb23
-rw-r--r--gcc/ada/adadecode.c10
-rw-r--r--gcc/ada/adaint.c18
-rw-r--r--gcc/ada/adaint.h2
-rw-r--r--gcc/ada/ali.adb595
-rw-r--r--gcc/ada/ali.ads329
-rw-r--r--gcc/ada/alloc.ads3
-rw-r--r--gcc/ada/argv.c5
-rw-r--r--gcc/ada/aspects.adb5
-rw-r--r--gcc/ada/aspects.ads14
-rw-r--r--gcc/ada/aux-io.c5
-rw-r--r--gcc/ada/bindgen.adb36
-rw-r--r--gcc/ada/bindo-augmentors.adb264
-rw-r--r--gcc/ada/bindo-augmentors.ads8
-rw-r--r--gcc/ada/bindo-builders.adb285
-rw-r--r--gcc/ada/bindo-diagnostics.adb1543
-rw-r--r--gcc/ada/bindo-diagnostics.ads20
-rw-r--r--gcc/ada/bindo-elaborators.adb2028
-rw-r--r--gcc/ada/bindo-graphs.adb4206
-rw-r--r--gcc/ada/bindo-graphs.ads859
-rw-r--r--gcc/ada/bindo-units.adb86
-rw-r--r--gcc/ada/bindo-units.ads36
-rw-r--r--gcc/ada/bindo-validators.adb493
-rw-r--r--gcc/ada/bindo-validators.ads20
-rw-r--r--gcc/ada/bindo-writers.adb775
-rw-r--r--gcc/ada/bindo-writers.ads38
-rw-r--r--gcc/ada/bindo.adb301
-rw-r--r--gcc/ada/bindo.ads26
-rw-r--r--gcc/ada/bindusg.adb11
-rw-r--r--gcc/ada/checks.adb160
-rw-r--r--gcc/ada/cio.c3
-rw-r--r--gcc/ada/clean.adb2
-rw-r--r--gcc/ada/contracts.adb495
-rw-r--r--gcc/ada/cstreams.c4
-rw-r--r--gcc/ada/ctrl_c.c6
-rw-r--r--gcc/ada/debug.adb94
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst29
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst132
-rw-r--r--gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst6
-rw-r--r--gcc/ada/doc/gnat_rm/the_gnat_library.rst13
-rw-r--r--gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst102
-rw-r--r--gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst1416
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst17
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst176
-rw-r--r--gcc/ada/doc/gnat_ugn/platform_specific_information.rst73
-rw-r--r--gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst7
-rw-r--r--gcc/ada/einfo.adb16
-rw-r--r--gcc/ada/einfo.ads17
-rw-r--r--gcc/ada/env.c140
-rw-r--r--gcc/ada/errno.c15
-rw-r--r--gcc/ada/erroutc.adb3
-rw-r--r--gcc/ada/exit.c15
-rw-r--r--gcc/ada/exp_aggr.adb590
-rw-r--r--gcc/ada/exp_attr.adb131
-rw-r--r--gcc/ada/exp_ch11.adb4
-rw-r--r--gcc/ada/exp_ch13.adb4
-rw-r--r--gcc/ada/exp_ch3.adb101
-rw-r--r--gcc/ada/exp_ch4.adb620
-rw-r--r--gcc/ada/exp_ch4.ads17
-rw-r--r--gcc/ada/exp_ch5.adb49
-rw-r--r--gcc/ada/exp_ch6.adb244
-rw-r--r--gcc/ada/exp_ch7.adb22
-rw-r--r--gcc/ada/exp_ch9.adb122
-rw-r--r--gcc/ada/exp_dbug.adb8
-rw-r--r--gcc/ada/exp_disp.adb18
-rw-r--r--gcc/ada/exp_imgv.adb38
-rw-r--r--gcc/ada/exp_pakd.adb36
-rw-r--r--gcc/ada/exp_spark.adb13
-rw-r--r--gcc/ada/exp_tss.adb16
-rw-r--r--gcc/ada/exp_unst.adb27
-rw-r--r--gcc/ada/exp_util.adb142
-rw-r--r--gcc/ada/exp_util.ads4
-rw-r--r--gcc/ada/expander.adb7
-rw-r--r--gcc/ada/expect.c9
-rw-r--r--gcc/ada/fname-uf.ads2
-rw-r--r--gcc/ada/freeze.adb31
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in1
-rw-r--r--gcc/ada/gcc-interface/trans.c10
-rw-r--r--gcc/ada/get_scos.adb6
-rw-r--r--gcc/ada/gnat1drv.adb87
-rw-r--r--gcc/ada/gnat_rm.texi524
-rw-r--r--gcc/ada/gnat_ugn.texi1599
-rw-r--r--gcc/ada/gnatbind.adb21
-rw-r--r--gcc/ada/gnatlink.adb4
-rw-r--r--gcc/ada/gsocket.h1
-rw-r--r--gcc/ada/init.c10
-rw-r--r--gcc/ada/initialize.c3
-rw-r--r--gcc/ada/inline.adb12
-rw-r--r--gcc/ada/lib-writ.adb552
-rw-r--r--gcc/ada/lib-writ.ads20
-rw-r--r--gcc/ada/lib-xref-spark_specific.adb1
-rw-r--r--gcc/ada/lib.ads2
-rw-r--r--gcc/ada/libgnarl/a-taside.ads9
-rw-r--r--gcc/ada/libgnarl/g-thread.adb9
-rw-r--r--gcc/ada/libgnarl/g-thread.ads4
-rw-r--r--gcc/ada/libgnarl/s-linux.ads2
-rw-r--r--gcc/ada/libgnarl/s-linux__alpha.ads2
-rw-r--r--gcc/ada/libgnarl/s-linux__android.ads2
-rw-r--r--gcc/ada/libgnarl/s-linux__hppa.ads2
-rw-r--r--gcc/ada/libgnarl/s-linux__mips.ads2
-rw-r--r--gcc/ada/libgnarl/s-linux__riscv.ads2
-rw-r--r--gcc/ada/libgnarl/s-linux__sparc.ads2
-rw-r--r--gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads8
-rw-r--r--gcc/ada/libgnarl/s-osinte__linux.ads3
-rw-r--r--gcc/ada/libgnarl/s-osinte__mingw.ads2
-rw-r--r--gcc/ada/libgnat/a-cfhama.adb7
-rw-r--r--gcc/ada/libgnat/a-cfhase.adb7
-rw-r--r--gcc/ada/libgnat/a-cofove.adb183
-rw-r--r--gcc/ada/libgnat/a-cofove.ads59
-rw-r--r--gcc/ada/libgnat/a-strbou.ads521
-rw-r--r--gcc/ada/libgnat/a-strfix.adb10
-rw-r--r--gcc/ada/libgnat/a-strfix.ads455
-rw-r--r--gcc/ada/libgnat/a-strunb.ads485
-rw-r--r--gcc/ada/libgnat/a-strunb__shared.ads405
-rw-r--r--gcc/ada/libgnat/a-textio.adb13
-rw-r--r--gcc/ada/libgnat/a-textio.ads466
-rw-r--r--gcc/ada/libgnat/a-tideio.ads35
-rw-r--r--gcc/ada/libgnat/a-tienio.ads33
-rw-r--r--gcc/ada/libgnat/a-tifiio.ads35
-rw-r--r--gcc/ada/libgnat/a-tiflio.ads35
-rw-r--r--gcc/ada/libgnat/a-tiinio.ads35
-rw-r--r--gcc/ada/libgnat/a-timoio.ads35
-rw-r--r--gcc/ada/libgnat/a-wichha.ads30
-rw-r--r--gcc/ada/libgnat/g-brapre.ads68
-rw-r--r--gcc/ada/libgnat/g-comlin.adb2
-rw-r--r--gcc/ada/libgnat/g-comlin.ads6
-rw-r--r--gcc/ada/libgnat/g-encstr.adb8
-rw-r--r--gcc/ada/libgnat/g-exptty.adb51
-rw-r--r--gcc/ada/libgnat/g-exptty.ads14
-rw-r--r--gcc/ada/libgnat/g-lists.adb51
-rw-r--r--gcc/ada/libgnat/g-lists.ads6
-rw-r--r--gcc/ada/libgnat/g-regexp.ads2
-rw-r--r--gcc/ada/libgnat/g-regpat.ads2
-rw-r--r--gcc/ada/libgnat/g-sercom.adb9
-rw-r--r--gcc/ada/libgnat/g-sercom.ads73
-rw-r--r--gcc/ada/libgnat/g-sercom__linux.adb88
-rw-r--r--gcc/ada/libgnat/g-sercom__mingw.adb57
-rw-r--r--gcc/ada/libgnat/g-socket.adb38
-rw-r--r--gcc/ada/libgnat/g-socket.ads147
-rw-r--r--gcc/ada/libgnat/g-sothco.ads7
-rw-r--r--gcc/ada/libgnat/g-spipat.ads2
-rw-r--r--gcc/ada/libgnat/g-traceb.adb12
-rw-r--r--gcc/ada/libgnat/g-traceb.ads10
-rw-r--r--gcc/ada/libgnat/s-imenne.adb9
-rw-r--r--gcc/ada/libgnat/s-memory.adb17
-rw-r--r--gcc/ada/libgnat/s-os_lib.adb10
-rw-r--r--gcc/ada/libgnat/s-os_lib.ads2
-rw-r--r--gcc/ada/libgnat/s-regexp.ads2
-rw-r--r--gcc/ada/libgnat/s-stratt.ads2
-rw-r--r--gcc/ada/libgnat/s-ststop.adb2
-rw-r--r--gcc/ada/libgnat/s-valboo.ads2
-rw-r--r--gcc/ada/libgnat/s-valcha.ads2
-rw-r--r--gcc/ada/libgnat/s-valdec.ads2
-rw-r--r--gcc/ada/libgnat/s-valenu.ads2
-rw-r--r--gcc/ada/libgnat/s-valint.ads2
-rw-r--r--gcc/ada/libgnat/s-vallld.ads2
-rw-r--r--gcc/ada/libgnat/s-vallli.ads2
-rw-r--r--gcc/ada/libgnat/s-valllu.ads2
-rw-r--r--gcc/ada/libgnat/s-valrea.adb98
-rw-r--r--gcc/ada/libgnat/s-valrea.ads2
-rw-r--r--gcc/ada/libgnat/s-valuns.ads2
-rw-r--r--gcc/ada/libgnat/s-valwch.ads2
-rw-r--r--gcc/ada/make.adb2
-rw-r--r--gcc/ada/mkdir.c3
-rw-r--r--gcc/ada/namet.ads2
-rw-r--r--gcc/ada/opt.adb9
-rw-r--r--gcc/ada/opt.ads13
-rw-r--r--gcc/ada/osint-c.adb30
-rw-r--r--gcc/ada/par-ch4.adb2
-rw-r--r--gcc/ada/par-ch6.adb2
-rw-r--r--gcc/ada/par-labl.adb2
-rw-r--r--gcc/ada/par-load.adb16
-rw-r--r--gcc/ada/prep.adb2
-rw-r--r--gcc/ada/raise-gcc.c8
-rw-r--r--gcc/ada/raise.c13
-rw-r--r--gcc/ada/repinfo-input.adb1350
-rw-r--r--gcc/ada/repinfo-input.ads78
-rw-r--r--gcc/ada/repinfo.adb678
-rw-r--r--gcc/ada/repinfo.ads2
-rw-r--r--gcc/ada/rtinit.c202
-rw-r--r--gcc/ada/rtsfind.ads34
-rw-r--r--gcc/ada/runtime.h44
-rw-r--r--gcc/ada/s-oscons-tmplt.c128
-rw-r--r--gcc/ada/scil_ll.adb67
-rw-r--r--gcc/ada/scil_ll.ads14
-rw-r--r--gcc/ada/seh_init.c4
-rw-r--r--gcc/ada/sem.adb2
-rw-r--r--gcc/ada/sem_aggr.adb45
-rw-r--r--gcc/ada/sem_attr.adb22
-rw-r--r--gcc/ada/sem_aux.adb13
-rw-r--r--gcc/ada/sem_aux.ads6
-rw-r--r--gcc/ada/sem_ch10.adb32
-rw-r--r--gcc/ada/sem_ch12.adb81
-rw-r--r--gcc/ada/sem_ch13.adb201
-rw-r--r--gcc/ada/sem_ch13.ads12
-rw-r--r--gcc/ada/sem_ch2.adb18
-rw-r--r--gcc/ada/sem_ch3.adb259
-rw-r--r--gcc/ada/sem_ch4.adb79
-rw-r--r--gcc/ada/sem_ch5.adb19
-rw-r--r--gcc/ada/sem_ch6.adb19
-rw-r--r--gcc/ada/sem_ch6.ads2
-rw-r--r--gcc/ada/sem_ch7.adb12
-rw-r--r--gcc/ada/sem_ch8.adb71
-rw-r--r--gcc/ada/sem_ch9.adb56
-rw-r--r--gcc/ada/sem_dim.adb29
-rw-r--r--gcc/ada/sem_disp.adb11
-rw-r--r--gcc/ada/sem_elab.adb494
-rw-r--r--gcc/ada/sem_eval.adb63
-rw-r--r--gcc/ada/sem_prag.adb147
-rw-r--r--gcc/ada/sem_prag.ads6
-rw-r--r--gcc/ada/sem_res.adb610
-rw-r--r--gcc/ada/sem_spark.adb1439
-rw-r--r--gcc/ada/sem_spark.ads26
-rw-r--r--gcc/ada/sem_util.adb284
-rw-r--r--gcc/ada/sem_util.ads21
-rw-r--r--gcc/ada/sem_warn.adb15
-rw-r--r--gcc/ada/sfn_scan.adb1
-rw-r--r--gcc/ada/sinfo.ads47
-rw-r--r--gcc/ada/snames.ads-tmpl5
-rw-r--r--gcc/ada/socket.c11
-rw-r--r--gcc/ada/sprint.adb91
-rw-r--r--gcc/ada/sprint.ads2
-rw-r--r--gcc/ada/switch-b.adb6
-rw-r--r--gcc/ada/sysdep.c46
-rw-r--r--gcc/ada/targext.c7
-rw-r--r--gcc/ada/terminals.c45
-rw-r--r--gcc/ada/tracebak.c8
-rw-r--r--gcc/ada/usage.adb2
-rw-r--r--gcc/ada/validsw.adb9
-rw-r--r--gcc/ada/validsw.ads48
-rw-r--r--gcc/ada/warnsw.adb12
-rw-r--r--gcc/ada/warnsw.ads7
-rw-r--r--gcc/ada/xoscons.adb3
-rw-r--r--gcc/ada/xref_lib.adb2
-rw-r--r--gcc/alias.c87
-rw-r--r--gcc/align.h3
-rw-r--r--gcc/alloc-pool.h3
-rw-r--r--gcc/asan.c3
-rw-r--r--gcc/attribs.c14
-rw-r--r--gcc/auto-profile.c5
-rw-r--r--gcc/basic-block.h7
-rw-r--r--gcc/bitmap.c2
-rw-r--r--gcc/bitmap.h8
-rw-r--r--gcc/builtins.c18
-rw-r--r--gcc/c-family/ChangeLog35
-rw-r--r--gcc/c-family/c-common.h3
-rw-r--r--gcc/c-family/c-format.c6
-rw-r--r--gcc/c-family/c-omp.c74
-rw-r--r--gcc/c-family/c-opts.c2
-rw-r--r--gcc/c-family/c-pragma.c1
-rw-r--r--gcc/c-family/c-pragma.h3
-rw-r--r--gcc/c-family/c-pretty-print.h5
-rw-r--r--gcc/c/ChangeLog60
-rw-r--r--gcc/c/c-decl.c10
-rw-r--r--gcc/c/c-parser.c195
-rw-r--r--gcc/c/c-tree.h6
-rw-r--r--gcc/c/c-typeck.c29
-rw-r--r--gcc/c/gimple-parser.c79
-rw-r--r--gcc/caller-save.c24
-rw-r--r--gcc/cfg.c6
-rw-r--r--gcc/cfg.h4
-rw-r--r--gcc/cfganal.h4
-rw-r--r--gcc/cfgcleanup.c17
-rw-r--r--gcc/cfgexpand.c34
-rw-r--r--gcc/cfghooks.c18
-rw-r--r--gcc/cfghooks.h9
-rw-r--r--gcc/cfgloop.c134
-rw-r--r--gcc/cfgloop.h161
-rw-r--r--gcc/cfgloopanal.c20
-rw-r--r--gcc/cfgloopmanip.c90
-rw-r--r--gcc/cfgloopmanip.h32
-rw-r--r--gcc/cfgrtl.c45
-rw-r--r--gcc/cgraph.c18
-rw-r--r--gcc/cgraph.h42
-rw-r--r--gcc/cgraphbuild.c2
-rw-r--r--gcc/cgraphunit.c2
-rw-r--r--gcc/collect2.c22
-rw-r--r--gcc/combine.c2
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/common/config/i386/i386-common.c2
-rw-r--r--gcc/common/config/rs6000/rs6000-common.c2
-rw-r--r--gcc/config.gcc10
-rw-r--r--gcc/config/aarch64/aarch64-option-extensions.def18
-rw-r--r--gcc/config/aarch64/aarch64-simd.md116
-rw-r--r--gcc/config/aarch64/aarch64-sve.md2
-rw-r--r--gcc/config/aarch64/aarch64.c7
-rw-r--r--gcc/config/aarch64/aarch64.md29
-rw-r--r--gcc/config/aarch64/iterators.md5
-rw-r--r--gcc/config/arc/arc.c2
-rw-r--r--gcc/config/arm/aarch-common-protos.h1
-rw-r--r--gcc/config/arm/aarch-common.c40
-rw-r--r--gcc/config/arm/arm-builtins.c36
-rw-r--r--gcc/config/arm/arm.c39
-rw-r--r--gcc/config/arm/arm.md99
-rw-r--r--gcc/config/arm/arm_neon.h21
-rw-r--r--gcc/config/arm/cortex-a53.md6
-rw-r--r--gcc/config/arm/cortex-a57.md6
-rw-r--r--gcc/config/arm/crypto.md134
-rw-r--r--gcc/config/arm/exynos-m1.md5
-rw-r--r--gcc/config/arm/iterators.md10
-rw-r--r--gcc/config/arm/neon.md14
-rw-r--r--gcc/config/arm/predicates.md21
-rw-r--r--gcc/config/arm/sync.md6
-rw-r--r--gcc/config/avr/avr.c2
-rw-r--r--gcc/config/c6x/c6x.c8
-rw-r--r--gcc/config/darwin.c10
-rw-r--r--gcc/config/darwin.h28
-rw-r--r--gcc/config/gcn/gcn-valu.md32
-rw-r--r--gcc/config/h8300/h8300.md2
-rw-r--r--gcc/config/i386/avx512fintrin.h28
-rw-r--r--gcc/config/i386/avx512vlintrin.h28
-rw-r--r--gcc/config/i386/i386-builtin-types.def9
-rw-r--r--gcc/config/i386/i386-builtin.def120
-rw-r--r--gcc/config/i386/i386-expand.c30
-rw-r--r--gcc/config/i386/i386-features.c2
-rw-r--r--gcc/config/i386/i386-features.h2
-rw-r--r--gcc/config/i386/i386-options.c6
-rw-r--r--gcc/config/i386/i386.c10
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/i386.md401
-rw-r--r--gcc/config/i386/mmx.md8
-rw-r--r--gcc/config/i386/sse.md287
-rw-r--r--gcc/config/i386/x86-tune-costs.h12
-rw-r--r--gcc/config/i386/x86-tune.def4
-rw-r--r--gcc/config/i386/znver1.md579
-rw-r--r--gcc/config/mips/micromips.md2
-rw-r--r--gcc/config/mips/mips.c4
-rw-r--r--gcc/config/mips/mips.md12
-rw-r--r--gcc/config/msp430/msp430.c18
-rw-r--r--gcc/config/or1k/constraints.md4
-rw-r--r--gcc/config/or1k/elf.opt6
-rw-r--r--gcc/config/or1k/or1k.c50
-rw-r--r--gcc/config/or1k/or1k.h3
-rw-r--r--gcc/config/or1k/or1k.md131
-rw-r--r--gcc/config/or1k/or1k.opt78
-rw-r--r--gcc/config/or1k/predicates.md30
-rw-r--r--gcc/config/pa/pa-protos.h1
-rw-r--r--gcc/config/pa/pa.c35
-rw-r--r--gcc/config/pa/pa.h1
-rw-r--r--gcc/config/riscv/pic.md4
-rw-r--r--gcc/config/riscv/riscv-opts.h5
-rw-r--r--gcc/config/riscv/riscv.c3
-rw-r--r--gcc/config/riscv/riscv.h17
-rw-r--r--gcc/config/riscv/riscv.md11
-rw-r--r--gcc/config/riscv/riscv.opt14
-rw-r--r--gcc/config/rs6000/aix.h3
-rw-r--r--gcc/config/rs6000/darwin.h21
-rw-r--r--gcc/config/rs6000/darwin7.h12
-rw-r--r--gcc/config/rs6000/darwin8.h14
-rw-r--r--gcc/config/rs6000/linux64.h4
-rw-r--r--gcc/config/rs6000/predicates.md30
-rw-r--r--gcc/config/rs6000/rs6000-c.c3
-rw-r--r--gcc/config/rs6000/rs6000-call.c8134
-rw-r--r--gcc/config/rs6000/rs6000-internal.h74
-rw-r--r--gcc/config/rs6000/rs6000-logue.c62
-rw-r--r--gcc/config/rs6000/rs6000-protos.h2
-rw-r--r--gcc/config/rs6000/rs6000.c8204
-rw-r--r--gcc/config/rs6000/rs6000.h34
-rw-r--r--gcc/config/rs6000/rs6000.md39
-rw-r--r--gcc/config/rs6000/smmintrin.h20
-rw-r--r--gcc/config/rs6000/sysv4.h3
-rw-r--r--gcc/config/rs6000/t-rs60004
-rw-r--r--gcc/config/rs6000/vsx.md4
-rw-r--r--gcc/config/s390/constraints.md12
-rw-r--r--gcc/config/s390/predicates.md29
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c74
-rw-r--r--gcc/config/s390/s390.md47
-rw-r--r--gcc/config/s390/subst.md72
-rw-r--r--gcc/config/s390/vector.md14
-rw-r--r--gcc/config/s390/vx-builtins.md2
-rw-r--r--gcc/coretypes.h46
-rw-r--r--gcc/cp/ChangeLog139
-rw-r--r--gcc/cp/call.c32
-rw-r--r--gcc/cp/class.c16
-rw-r--r--gcc/cp/constexpr.c3
-rw-r--r--gcc/cp/constraint.cc3
-rw-r--r--gcc/cp/cp-tree.h27
-rw-r--r--gcc/cp/cxx-pretty-print.h3
-rw-r--r--gcc/cp/decl.c59
-rw-r--r--gcc/cp/decl2.c54
-rw-r--r--gcc/cp/error.c3
-rw-r--r--gcc/cp/logic.cc9
-rw-r--r--gcc/cp/name-lookup.c16
-rw-r--r--gcc/cp/parser.c359
-rw-r--r--gcc/cp/pt.c28
-rw-r--r--gcc/cp/search.c5
-rw-r--r--gcc/cp/semantics.c31
-rw-r--r--gcc/data-streamer-in.c22
-rw-r--r--gcc/data-streamer.h30
-rw-r--r--gcc/ddg.c8
-rw-r--r--gcc/df-core.c16
-rw-r--r--gcc/df-problems.c159
-rw-r--r--gcc/df-scan.c63
-rw-r--r--gcc/df.h53
-rw-r--r--gcc/diagnostic-show-locus.c18
-rw-r--r--gcc/doc/extend.texi11
-rw-r--r--gcc/doc/generic.texi5
-rw-r--r--gcc/doc/install.texi1
-rw-r--r--gcc/doc/invoke.texi117
-rw-r--r--gcc/doc/md.texi9
-rw-r--r--gcc/doc/tm.texi10
-rw-r--r--gcc/dojump.h3
-rw-r--r--gcc/dse.c19
-rw-r--r--gcc/dump-context.h3
-rw-r--r--gcc/dumpfile.h5
-rw-r--r--gcc/dwarf2out.c10
-rw-r--r--gcc/edit-context.c3
-rw-r--r--gcc/emit-rtl.c22
-rw-r--r--gcc/emit-rtl.h10
-rw-r--r--gcc/except.c31
-rw-r--r--gcc/explow.c17
-rw-r--r--gcc/expmed.c14
-rw-r--r--gcc/expr.c33
-rw-r--r--gcc/fibonacci_heap.c3
-rw-r--r--gcc/flags.h7
-rw-r--r--gcc/fold-const.c50
-rw-r--r--gcc/fold-const.h3
-rw-r--r--gcc/fortran/ChangeLog43
-rw-r--r--gcc/fortran/expr.c10
-rw-r--r--gcc/fortran/gfortran.texi19
-rw-r--r--gcc/fortran/invoke.texi7
-rw-r--r--gcc/fortran/libgfortran.h4
-rw-r--r--gcc/fortran/openmp.c17
-rw-r--r--gcc/fortran/options.c4
-rw-r--r--gcc/fortran/trans-array.c17
-rw-r--r--gcc/fortran/trans-intrinsic.c167
-rw-r--r--gcc/function.c58
-rw-r--r--gcc/function.h10
-rw-r--r--gcc/fwprop.c134
-rw-r--r--gcc/gcc-rich-location.h2
-rw-r--r--gcc/gcc.c4
-rw-r--r--gcc/gcov.c29
-rw-r--r--gcc/gdbhooks.py13
-rw-r--r--gcc/gdbinit.in10
-rw-r--r--gcc/genattrtab.c145
-rw-r--r--gcc/genemit.c65
-rw-r--r--gcc/genextract.c11
-rw-r--r--gcc/genmatch.c87
-rw-r--r--gcc/genopinit.c62
-rw-r--r--gcc/genoutput.c52
-rw-r--r--gcc/genpreds.c33
-rw-r--r--gcc/genrecog.c60
-rw-r--r--gcc/gensupport.c115
-rw-r--r--gcc/gensupport.h3
-rw-r--r--gcc/ggc-common.c3
-rw-r--r--gcc/ggc-page.c2
-rw-r--r--gcc/ggc-tests.c3
-rw-r--r--gcc/gimple-fold.c91
-rw-r--r--gcc/gimple-loop-interchange.cc65
-rw-r--r--gcc/gimple-loop-jam.c20
-rw-r--r--gcc/gimple-loop-versioning.cc70
-rw-r--r--gcc/gimple-match-head.c44
-rw-r--r--gcc/gimple-match.h13
-rw-r--r--gcc/gimple-pretty-print.c20
-rw-r--r--gcc/gimple-ssa-backprop.c3
-rw-r--r--gcc/gimple-ssa-evrp-analyze.c2
-rw-r--r--gcc/gimple-ssa-isolate-paths.c488
-rw-r--r--gcc/gimple-ssa-sprintf.c3
-rw-r--r--gcc/gimple-ssa-store-merging.c35
-rw-r--r--gcc/gimple-ssa-strength-reduction.c14
-rw-r--r--gcc/gimple-ssa-warn-alloca.c11
-rw-r--r--gcc/gimple-ssa-warn-restrict.c3
-rw-r--r--gcc/gimple-streamer-in.c8
-rw-r--r--gcc/gimple-streamer.h2
-rw-r--r--gcc/gimple.h18
-rw-r--r--gcc/gimplify.c380
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/export.cc77
-rw-r--r--gcc/go/gofrontend/export.h3
-rw-r--r--gcc/go/gofrontend/expressions.h4
-rw-r--r--gcc/go/gofrontend/gogo.cc67
-rw-r--r--gcc/go/gofrontend/gogo.h26
-rw-r--r--gcc/go/gofrontend/import.cc61
-rw-r--r--gcc/go/gofrontend/import.h33
-rw-r--r--gcc/go/gofrontend/runtime.def16
-rw-r--r--gcc/go/gofrontend/statements.cc241
-rw-r--r--gcc/go/gofrontend/statements.h40
-rw-r--r--gcc/go/gofrontend/types.cc4
-rw-r--r--gcc/godump.c19
-rw-r--r--gcc/graph.c4
-rw-r--r--gcc/hard-reg-set.h4
-rw-r--r--gcc/hash-map-tests.c3
-rw-r--r--gcc/hash-map.h3
-rw-r--r--gcc/hash-set-tests.c3
-rw-r--r--gcc/hsa-brig.c8
-rw-r--r--gcc/hsa-common.h16
-rw-r--r--gcc/hsa-dump.c2
-rw-r--r--gcc/hsa-gen.c7
-rw-r--r--gcc/hsa-regalloc.c2
-rw-r--r--gcc/ifcvt.c7
-rw-r--r--gcc/input.c20
-rw-r--r--gcc/input.h7
-rw-r--r--gcc/internal-fn.c34
-rw-r--r--gcc/ipa-cp.c183
-rw-r--r--gcc/ipa-devirt.c8
-rw-r--r--gcc/ipa-fnsummary.c227
-rw-r--r--gcc/ipa-fnsummary.h22
-rw-r--r--gcc/ipa-hsa.c2
-rw-r--r--gcc/ipa-icf-gimple.c4
-rw-r--r--gcc/ipa-icf.c2
-rw-r--r--gcc/ipa-inline-analysis.c6
-rw-r--r--gcc/ipa-inline.c9
-rw-r--r--gcc/ipa-inline.h3
-rw-r--r--gcc/ipa-polymorphic-call.c4
-rw-r--r--gcc/ipa-predicate.c8
-rw-r--r--gcc/ipa-predicate.h8
-rw-r--r--gcc/ipa-profile.c2
-rw-r--r--gcc/ipa-prop.c107
-rw-r--r--gcc/ipa-prop.h51
-rw-r--r--gcc/ipa-pure-const.c8
-rw-r--r--gcc/ipa-ref.h4
-rw-r--r--gcc/ipa-reference.c2
-rw-r--r--gcc/ipa-split.c23
-rw-r--r--gcc/ira-build.c8
-rw-r--r--gcc/ira-color.c4
-rw-r--r--gcc/ira-emit.c15
-rw-r--r--gcc/ira-int.h14
-rw-r--r--gcc/ira.c22
-rw-r--r--gcc/jit/ChangeLog47
-rw-r--r--gcc/jit/docs/topics/compatibility.rst5
-rw-r--r--gcc/jit/docs/topics/types.rst24
-rw-r--r--gcc/jit/jit-common.h1
-rw-r--r--gcc/jit/jit-playback.c91
-rw-r--r--gcc/jit/jit-playback.h11
-rw-r--r--gcc/jit/jit-recording.c84
-rw-r--r--gcc/jit/jit-recording.h44
-rw-r--r--gcc/jit/libgccjit++.h14
-rw-r--r--gcc/jit/libgccjit.c54
-rw-r--r--gcc/jit/libgccjit.h15
-rw-r--r--gcc/jit/libgccjit.map7
-rw-r--r--gcc/loop-doloop.c10
-rw-r--r--gcc/loop-init.c6
-rw-r--r--gcc/loop-invariant.c45
-rw-r--r--gcc/loop-iv.c103
-rw-r--r--gcc/loop-unroll.c62
-rw-r--r--gcc/lower-subreg.c46
-rw-r--r--gcc/lra-constraints.c17
-rw-r--r--gcc/lra-eliminations.c39
-rw-r--r--gcc/lra-int.h10
-rw-r--r--gcc/lra-lives.c7
-rw-r--r--gcc/lra-remat.c7
-rw-r--r--gcc/lra-spills.c7
-rw-r--r--gcc/lra.c8
-rw-r--r--gcc/lto-cgraph.c30
-rw-r--r--gcc/lto-compress.c11
-rw-r--r--gcc/lto-section-in.c9
-rw-r--r--gcc/lto-streamer-in.c66
-rw-r--r--gcc/lto-streamer-out.c5
-rw-r--r--gcc/lto-streamer.h52
-rw-r--r--gcc/lto/ChangeLog37
-rw-r--r--gcc/lto/lang.opt3
-rw-r--r--gcc/lto/lto-common.c43
-rw-r--r--gcc/lto/lto-dump.c61
-rw-r--r--gcc/mem-stats.h9
-rw-r--r--gcc/modulo-sched.c14
-rw-r--r--gcc/omp-expand.c49
-rw-r--r--gcc/omp-general.c2
-rw-r--r--gcc/omp-grid.c9
-rw-r--r--gcc/omp-low.c661
-rw-r--r--gcc/omp-offload.c4
-rw-r--r--gcc/omp-simd-clone.c2
-rw-r--r--gcc/optabs-query.c2
-rw-r--r--gcc/optabs-query.h3
-rw-r--r--gcc/optabs.c99
-rw-r--r--gcc/optabs.h33
-rw-r--r--gcc/optinfo.h2
-rw-r--r--gcc/opts-common.c20
-rw-r--r--gcc/opts-global.c6
-rw-r--r--gcc/opts.c6
-rw-r--r--gcc/params.def12
-rw-r--r--gcc/passes.c9
-rw-r--r--gcc/passes.def3
-rw-r--r--gcc/poly-int.h4
-rw-r--r--gcc/predict.c44
-rw-r--r--gcc/predict.h8
-rw-r--r--gcc/pretty-print.h6
-rw-r--r--gcc/profile-count.c4
-rw-r--r--gcc/profile-count.h10
-rw-r--r--gcc/profile.c2
-rw-r--r--gcc/read-md.c27
-rw-r--r--gcc/read-md.h16
-rw-r--r--gcc/read-rtl-function.c3
-rw-r--r--gcc/read-rtl.c67
-rw-r--r--gcc/recog.h17
-rw-r--r--gcc/ree.c3
-rw-r--r--gcc/reg-stack.c1
-rw-r--r--gcc/reginfo.c3
-rw-r--r--gcc/regrename.c73
-rw-r--r--gcc/regrename.h11
-rw-r--r--gcc/reload.h11
-rw-r--r--gcc/reload1.c76
-rw-r--r--gcc/resource.c4
-rw-r--r--gcc/rtl-iter.h3
-rw-r--r--gcc/rtl.h47
-rw-r--r--gcc/sanopt.c13
-rw-r--r--gcc/sched-deps.c44
-rw-r--r--gcc/sched-ebb.c2
-rw-r--r--gcc/sched-int.h21
-rw-r--r--gcc/sched-rgn.c12
-rw-r--r--gcc/sel-sched-ir.c28
-rw-r--r--gcc/sel-sched-ir.h19
-rw-r--r--gcc/selftest.h5
-rw-r--r--gcc/sese.c6
-rw-r--r--gcc/sese.h12
-rw-r--r--gcc/simplify-rtx.c19
-rw-r--r--gcc/sreal.c2
-rw-r--r--gcc/sreal.h4
-rw-r--r--gcc/stmt.c3
-rw-r--r--gcc/streamer-hooks.h8
-rw-r--r--gcc/symtab.c17
-rw-r--r--gcc/target-globals.c14
-rw-r--r--gcc/target-globals.h19
-rw-r--r--gcc/target.def10
-rw-r--r--gcc/target.h10
-rw-r--r--gcc/targhooks.c6
-rw-r--r--gcc/targhooks.h8
-rw-r--r--gcc/testsuite/ChangeLog1223
-rw-r--r--gcc/testsuite/c-c++-common/gomp/cancel-1.c16
-rw-r--r--gcc/testsuite/c-c++-common/gomp/clauses-1.c133
-rw-r--r--gcc/testsuite/c-c++-common/gomp/loop-1.c271
-rw-r--r--gcc/testsuite/c-c++-common/gomp/loop-2.c294
-rw-r--r--gcc/testsuite/c-c++-common/gomp/loop-3.c145
-rw-r--r--gcc/testsuite/c-c++-common/gomp/loop-4.c46
-rw-r--r--gcc/testsuite/c-c++-common/gomp/loop-5.c56
-rw-r--r--gcc/testsuite/c-c++-common/gomp/order-1.c53
-rw-r--r--gcc/testsuite/c-c++-common/gomp/order-2.c57
-rw-r--r--gcc/testsuite/c-c++-common/gomp/order-3.c212
-rw-r--r--gcc/testsuite/c-c++-common/gomp/order-4.c29
-rw-r--r--gcc/testsuite/c-c++-common/gomp/reduction-task-3.c12
-rw-r--r--gcc/testsuite/c-c++-common/gomp/scan-4.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/simd-setjmp-1.c68
-rw-r--r--gcc/testsuite/c-c++-common/gomp/teams-2.c44
-rw-r--r--gcc/testsuite/c-c++-common/pr53633-2.c19
-rw-r--r--gcc/testsuite/g++.dg/Wmissing-attributes-1.C66
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype72.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-list6.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/class-deduction67.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class18.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class19.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class20.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class21.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class22.C21
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/complex-invalid-1.C1
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/static-cdtor-1.C5
-rw-r--r--gcc/testsuite/g++.dg/ext/is_std_layout3.C18
-rw-r--r--gcc/testsuite/g++.dg/ext/is_std_layout4.C11
-rw-r--r--gcc/testsuite/g++.dg/gomp/pr91110.C11
-rw-r--r--gcc/testsuite/g++.dg/gomp/unmappable-1.C20
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-1_0.C2
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-2_0.C2
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-3_0.C29
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-3_1.c18
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-4_0.C31
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-5_0.C35
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-5_1.C9
-rw-r--r--gcc/testsuite/g++.dg/lto/alias-5_2.c7
-rw-r--r--gcc/testsuite/g++.dg/opt/pr91164.C89
-rw-r--r--gcc/testsuite/g++.dg/other/anon-union3.C4
-rw-r--r--gcc/testsuite/g++.dg/other/final4.C16
-rw-r--r--gcc/testsuite/g++.dg/parse/error8.C2
-rw-r--r--gcc/testsuite/g++.dg/pr91173.C45
-rw-r--r--gcc/testsuite/g++.dg/pr91221.C13
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/final2.C35
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/final3.C23
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr83518.C27
-rw-r--r--gcc/testsuite/g++.dg/vect/simd-6.cc2
-rw-r--r--gcc/testsuite/g++.dg/vect/simd-9.cc2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr91190.c31
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr91204.c11
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr91137.c34
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/return-addr.c122
-rw-r--r--gcc/testsuite/gcc.dg/Walloca-4.c7
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-43.c133
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-10.c56
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c293
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c248
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c370
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-5.c40
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c203
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-7.c50
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-8.c88
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-9.c73
-rw-r--r--gcc/testsuite/gcc.dg/autopar/pr91162.c25
-rw-r--r--gcc/testsuite/gcc.dg/gimplefe-43.c25
-rw-r--r--gcc/testsuite/gcc.dg/gimplefe-44.c33
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr78884.c16
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr91063.c17
-rw-r--r--gcc/testsuite/gcc.dg/guality/guality.h7
-rw-r--r--gcc/testsuite/gcc.dg/pr41551.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr57438-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/pr59523.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr90756.c26
-rw-r--r--gcc/testsuite/gcc.dg/pr91069.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr91172.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr91181.c21
-rw-r--r--gcc/testsuite/gcc.dg/predict-17.c4
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-26.c3
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-67.c52
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91126.c28
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91145.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91178.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91180.c13
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91200.c32
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91207.c25
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91211.c19
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-5.c27
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-6.c27
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-7.c29
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-37.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c44
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr84512.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88497-1.c60
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88497-2.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88497-3.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88497-4.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88497-5.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88497-6.c65
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88497-7.c77
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88775-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c60
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-70.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-71.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-72.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-73.c14
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-74.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-75.c34
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-76.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-79.c29
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vector-7.c39
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr91114.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-sad.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-10.c10
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-14.c10
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-16.c61
-rw-r--r--gcc/testsuite/gcc.dg/winline-7.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/aes-fuse-1.c (renamed from gcc/testsuite/gcc.target/aarch64/crypto-fuse-1.c)45
-rw-r--r--gcc/testsuite/gcc.target/aarch64/aes-fuse-2.c65
-rw-r--r--gcc/testsuite/gcc.target/aarch64/crypto-fuse-2.c45
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr91102.c26
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/ssra.c36
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/usra.c36
-rw-r--r--gcc/testsuite/gcc.target/arc/tls-2.c14
-rw-r--r--gcc/testsuite/gcc.target/arc/tls-3.c19
-rw-r--r--gcc/testsuite/gcc.target/arm/aes-fuse-1.c66
-rw-r--r--gcc/testsuite/gcc.target/arm/aes-fuse-2.c66
-rw-r--r--gcc/testsuite/gcc.target/arm/aes_xor_combine.c43
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/struct-1.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c23
-rw-r--r--gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c23
-rw-r--r--gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c23
-rw-r--r--gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c23
-rw-r--r--gcc/testsuite/gcc.target/arm/pr89190.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-pr91157.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/pr90980-1.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr90980-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr90980-3.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91131.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91188-1a.c63
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91188-1b.c65
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91188-1c.c113
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91188-2a.c62
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91188-2b.c64
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91188-2c.c112
-rw-r--r--gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c19
-rw-r--r--gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c23
-rw-r--r--gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c23
-rw-r--r--gcc/testsuite/gcc.target/mips/msa-fmadd-n64.c101
-rw-r--r--gcc/testsuite/gcc.target/mips/msa-fmadd-o32.c (renamed from gcc/testsuite/gcc.target/mips/msa-fmadd.c)2
-rw-r--r--gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430.c13
-rw-r--r--gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430x.c12
-rw-r--r--gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430.c27
-rw-r--r--gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430x.c24
-rw-r--r--gcc/testsuite/gcc.target/msp430/isr-push-pop-main.c120
-rw-r--r--gcc/testsuite/gcc.target/or1k/shftimm-1.c8
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-4.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-5.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-6.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/byte-in-either-range-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/byte-in-range-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/byte-in-set-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/byte-in-set-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/cmpb-3.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c14
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr88233.c13
-rw-r--r--gcc/testsuite/gcc.target/powerpc/sse4_1-check.h27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/sse4_1-pblendvb.c71
-rw-r--r--gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw-2.c80
-rw-r--r--gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw.c89
-rw-r--r--gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/volatile-mem.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-cmpnez-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-12.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-13.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-xlx-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-xrx-7.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-13.c2
-rw-r--r--gcc/testsuite/gcc.target/riscv/shift-shift-2.c16
-rw-r--r--gcc/testsuite/gcc.target/s390/combine-rotate-modulo.c36
-rw-r--r--gcc/testsuite/gcc.target/s390/combine-shift-rotate-add-mod.c29
-rw-r--r--gcc/testsuite/gcc.target/s390/rotate-truncation-mask.c11
-rw-r--r--gcc/testsuite/gcc.target/s390/vector/combine-shift-vec.c107
-rw-r--r--gcc/testsuite/gfortran.dg/check_bits_1.f9049
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_14.f906
-rw-r--r--gcc/testsuite/gfortran.dg/initialization_30.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_array_11.f9090
-rw-r--r--gcc/testsuite/gfortran.dg/pr88833.f909
-rw-r--r--gcc/testsuite/gnat.dg/access6.adb28
-rw-r--r--gcc/testsuite/gnat.dg/access7.adb79
-rw-r--r--gcc/testsuite/gnat.dg/addr13.adb9
-rw-r--r--gcc/testsuite/gnat.dg/addr13.ads5
-rw-r--r--gcc/testsuite/gnat.dg/aggr25.adb7
-rw-r--r--gcc/testsuite/gnat.dg/aggr25.ads23
-rw-r--r--gcc/testsuite/gnat.dg/allocator.adb11
-rw-r--r--gcc/testsuite/gnat.dg/aspect2.adb5
-rw-r--r--gcc/testsuite/gnat.dg/aspect2.ads30
-rw-r--r--gcc/testsuite/gnat.dg/bip_export.adb15
-rw-r--r--gcc/testsuite/gnat.dg/bip_export.ads6
-rw-r--r--gcc/testsuite/gnat.dg/class_wide5.adb11
-rw-r--r--gcc/testsuite/gnat.dg/cpp_constructor.adb12
-rw-r--r--gcc/testsuite/gnat.dg/cpp_constructor2.adb19
-rw-r--r--gcc/testsuite/gnat.dg/cpp_constructor_fp.ads10
-rw-r--r--gcc/testsuite/gnat.dg/cpp_constructor_useit.ads8
-rw-r--r--gcc/testsuite/gnat.dg/default_initial_condition.adb12
-rw-r--r--gcc/testsuite/gnat.dg/default_initial_condition_pack.adb7
-rw-r--r--gcc/testsuite/gnat.dg/default_initial_condition_pack.ads12
-rw-r--r--gcc/testsuite/gnat.dg/dimensions2.adb20
-rw-r--r--gcc/testsuite/gnat.dg/dimensions2_phys.ads80
-rw-r--r--gcc/testsuite/gnat.dg/dimensions2_real_numbers.ads3
-rw-r--r--gcc/testsuite/gnat.dg/encode_string1.adb48
-rw-r--r--gcc/testsuite/gnat.dg/encode_string1_pkg.adb15
-rw-r--r--gcc/testsuite/gnat.dg/encode_string1_pkg.ads6
-rw-r--r--gcc/testsuite/gnat.dg/entry1.adb75
-rw-r--r--gcc/testsuite/gnat.dg/entry1.ads4
-rw-r--r--gcc/testsuite/gnat.dg/enum_val1.adb22
-rw-r--r--gcc/testsuite/gnat.dg/equal6.adb29
-rw-r--r--gcc/testsuite/gnat.dg/equal6_types.adb15
-rw-r--r--gcc/testsuite/gnat.dg/equal6_types.ads49
-rw-r--r--gcc/testsuite/gnat.dg/equal7.adb15
-rw-r--r--gcc/testsuite/gnat.dg/equal7_pkg.adb14
-rw-r--r--gcc/testsuite/gnat.dg/equal7_pkg.ads16
-rw-r--r--gcc/testsuite/gnat.dg/equal8.adb6
-rw-r--r--gcc/testsuite/gnat.dg/equal8.ads36
-rw-r--r--gcc/testsuite/gnat.dg/equal8_pkg.ads58
-rw-r--r--gcc/testsuite/gnat.dg/equal9.adb26
-rw-r--r--gcc/testsuite/gnat.dg/fixed_delete.adb17
-rw-r--r--gcc/testsuite/gnat.dg/fixedpnt6.adb21
-rw-r--r--gcc/testsuite/gnat.dg/float_value1.adb46
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst4.adb7
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst4_gen.ads3
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst4_inst.ads5
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst4_typ.ads7
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst5.adb20
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst6.adb9
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst6_g1-c.adb6
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst6_g1-c.ads3
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst6_g1.ads3
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst6_i1.ads2
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst6_i2.ads2
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst6_x.ads7
-rw-r--r--gcc/testsuite/gnat.dg/ghost5.adb5
-rw-r--r--gcc/testsuite/gnat.dg/ghost5.ads5
-rw-r--r--gcc/testsuite/gnat.dg/ghost5_parent.ads14
-rw-r--r--gcc/testsuite/gnat.dg/ghost6.adb10
-rw-r--r--gcc/testsuite/gnat.dg/ghost6_pkg.ads7
-rw-r--r--gcc/testsuite/gnat.dg/image1.adb12
-rw-r--r--gcc/testsuite/gnat.dg/incomplete7.adb5
-rw-r--r--gcc/testsuite/gnat.dg/incomplete7.ads31
-rw-r--r--gcc/testsuite/gnat.dg/inline17.adb10
-rw-r--r--gcc/testsuite/gnat.dg/inline17_pkg1.adb15
-rw-r--r--gcc/testsuite/gnat.dg/inline17_pkg1.ads7
-rw-r--r--gcc/testsuite/gnat.dg/inline17_pkg2.ads10
-rw-r--r--gcc/testsuite/gnat.dg/inline17_pkg3.adb14
-rw-r--r--gcc/testsuite/gnat.dg/inline17_pkg3.ads16
-rw-r--r--gcc/testsuite/gnat.dg/interface10.adb22
-rw-r--r--gcc/testsuite/gnat.dg/interface9.adb10
-rw-r--r--gcc/testsuite/gnat.dg/interface9_root-child.ads7
-rw-r--r--gcc/testsuite/gnat.dg/interface9_root.ads10
-rw-r--r--gcc/testsuite/gnat.dg/iter5.adb10
-rw-r--r--gcc/testsuite/gnat.dg/iter5_pkg.ads127
-rw-r--r--gcc/testsuite/gnat.dg/iter6.adb40
-rw-r--r--gcc/testsuite/gnat.dg/limited2.adb8
-rw-r--r--gcc/testsuite/gnat.dg/limited2_pack_1.adb5
-rw-r--r--gcc/testsuite/gnat.dg/limited2_pack_1.ads8
-rw-r--r--gcc/testsuite/gnat.dg/limited2_pack_2.adb21
-rw-r--r--gcc/testsuite/gnat.dg/limited2_pack_2.ads5
-rw-r--r--gcc/testsuite/gnat.dg/limited3.adb11
-rw-r--r--gcc/testsuite/gnat.dg/limited3_pkg.adb20
-rw-r--r--gcc/testsuite/gnat.dg/limited3_pkg.ads30
-rw-r--r--gcc/testsuite/gnat.dg/loop_entry1.adb13
-rw-r--r--gcc/testsuite/gnat.dg/loop_invariant1.adb15
-rw-r--r--gcc/testsuite/gnat.dg/loop_invariant1.ads7
-rw-r--r--gcc/testsuite/gnat.dg/modular5.adb26
-rw-r--r--gcc/testsuite/gnat.dg/opt80.adb15
-rw-r--r--gcc/testsuite/gnat.dg/pack23.adb14
-rw-r--r--gcc/testsuite/gnat.dg/pack23_pkg.ads5
-rw-r--r--gcc/testsuite/gnat.dg/predicate10.adb9
-rw-r--r--gcc/testsuite/gnat.dg/predicate10_pkg.adb10
-rw-r--r--gcc/testsuite/gnat.dg/predicate10_pkg.ads13
-rw-r--r--gcc/testsuite/gnat.dg/predicate11.adb19
-rw-r--r--gcc/testsuite/gnat.dg/predicate7.adb6
-rw-r--r--gcc/testsuite/gnat.dg/predicate7.ads13
-rw-r--r--gcc/testsuite/gnat.dg/predicate7_pkg.ads3
-rw-r--r--gcc/testsuite/gnat.dg/predicate8.adb15
-rw-r--r--gcc/testsuite/gnat.dg/predicate8_pkg.adb64
-rw-r--r--gcc/testsuite/gnat.dg/predicate8_pkg.ads81
-rw-r--r--gcc/testsuite/gnat.dg/predicate9.adb21
-rw-r--r--gcc/testsuite/gnat.dg/prot8.adb8
-rw-r--r--gcc/testsuite/gnat.dg/prot8.ads10
-rw-r--r--gcc/testsuite/gnat.dg/range_check3.adb13
-rw-r--r--gcc/testsuite/gnat.dg/range_check3_pkg.adb18
-rw-r--r--gcc/testsuite/gnat.dg/range_check3_pkg.ads9
-rw-r--r--gcc/testsuite/gnat.dg/range_check5.adb21
-rw-r--r--gcc/testsuite/gnat.dg/rep_clause8.adb19
-rw-r--r--gcc/testsuite/gnat.dg/scos1.adb26
-rw-r--r--gcc/testsuite/gnat.dg/self_ref1.adb11
-rw-r--r--gcc/testsuite/gnat.dg/spark3.adb20
-rw-r--r--gcc/testsuite/gnat.dg/sso16.adb55
-rw-r--r--gcc/testsuite/gnat.dg/synchronized2.adb5
-rw-r--r--gcc/testsuite/gnat.dg/synchronized2.ads4
-rw-r--r--gcc/testsuite/gnat.dg/synchronized2_pkg.ads5
-rw-r--r--gcc/testsuite/gnat.dg/tagged2.adb9
-rw-r--r--gcc/testsuite/gnat.dg/tagged2.ads9
-rw-r--r--gcc/testsuite/gnat.dg/task3.adb11
-rw-r--r--gcc/testsuite/gnat.dg/task3.ads12
-rw-r--r--gcc/testsuite/gnat.dg/task3_pkg1.ads11
-rw-r--r--gcc/testsuite/gnat.dg/task3_pkg2.ads7
-rw-r--r--gcc/testsuite/gnat.dg/task4.adb19
-rw-r--r--gcc/testsuite/gnat.dg/unreferenced2.adb34
-rw-r--r--gcc/testsuite/gnat.dg/warn21.adb6
-rw-r--r--gcc/testsuite/gnat.dg/warn21.ads18
-rw-r--r--gcc/testsuite/gnat.dg/warn22.adb34
-rw-r--r--gcc/testsuite/gnat.dg/warn23.adb17
-rw-r--r--gcc/testsuite/gnat.dg/warn24.adb15
-rw-r--r--gcc/testsuite/gnat.dg/warn25.adb23
-rw-r--r--gcc/testsuite/gnat.dg/warn26.adb20
-rw-r--r--gcc/testsuite/jit.dg/all-non-failing-tests.h10
-rw-r--r--gcc/testsuite/jit.dg/test-accessing-bitfield.c130
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_binary_op-bad-res-type.c41
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c53
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c44
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_unary_op-bad-res-type.c38
-rw-r--r--gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c66
-rw-r--r--gcc/toplev.c25
-rw-r--r--gcc/tree-affine.c11
-rw-r--r--gcc/tree-affine.h10
-rw-r--r--gcc/tree-cfg.c103
-rw-r--r--gcc/tree-cfg.h10
-rw-r--r--gcc/tree-chrec.c26
-rw-r--r--gcc/tree-chrec.h4
-rw-r--r--gcc/tree-core.h17
-rw-r--r--gcc/tree-data-ref.c95
-rw-r--r--gcc/tree-data-ref.h26
-rw-r--r--gcc/tree-dump.c1
-rw-r--r--gcc/tree-eh.c48
-rw-r--r--gcc/tree-if-conv.c50
-rw-r--r--gcc/tree-if-conv.h2
-rw-r--r--gcc/tree-inline.c6
-rw-r--r--gcc/tree-loop-distribution.c48
-rw-r--r--gcc/tree-nested.c2
-rw-r--r--gcc/tree-outof-ssa.c42
-rw-r--r--gcc/tree-parloops.c42
-rw-r--r--gcc/tree-pass.h7
-rw-r--r--gcc/tree-predcom.c67
-rw-r--r--gcc/tree-pretty-print.c55
-rw-r--r--gcc/tree-scalar-evolution.c107
-rw-r--r--gcc/tree-scalar-evolution.h24
-rw-r--r--gcc/tree-ssa-address.c14
-rw-r--r--gcc/tree-ssa-address.h4
-rw-r--r--gcc/tree-ssa-alias.c568
-rw-r--r--gcc/tree-ssa-alias.h7
-rw-r--r--gcc/tree-ssa-ccp.c3
-rw-r--r--gcc/tree-ssa-coalesce.c3
-rw-r--r--gcc/tree-ssa-dce.c2
-rw-r--r--gcc/tree-ssa-dom.c17
-rw-r--r--gcc/tree-ssa-dse.c165
-rw-r--r--gcc/tree-ssa-live.c4
-rw-r--r--gcc/tree-ssa-live.h2
-rw-r--r--gcc/tree-ssa-loop-ch.c16
-rw-r--r--gcc/tree-ssa-loop-im.c141
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c36
-rw-r--r--gcc/tree-ssa-loop-ivopts.c312
-rw-r--r--gcc/tree-ssa-loop-ivopts.h8
-rw-r--r--gcc/tree-ssa-loop-manip.c75
-rw-r--r--gcc/tree-ssa-loop-manip.h36
-rw-r--r--gcc/tree-ssa-loop-niter.c212
-rw-r--r--gcc/tree-ssa-loop-niter.h52
-rw-r--r--gcc/tree-ssa-loop-prefetch.c36
-rw-r--r--gcc/tree-ssa-loop-split.c24
-rw-r--r--gcc/tree-ssa-loop-unswitch.c50
-rw-r--r--gcc/tree-ssa-loop.c6
-rw-r--r--gcc/tree-ssa-loop.h7
-rw-r--r--gcc/tree-ssa-phiopt.c29
-rw-r--r--gcc/tree-ssa-pre.c7
-rw-r--r--gcc/tree-ssa-reassoc.c301
-rw-r--r--gcc/tree-ssa-sccvn.c658
-rw-r--r--gcc/tree-ssa-sccvn.h3
-rw-r--r--gcc/tree-ssa-scopedtables.c6
-rw-r--r--gcc/tree-ssa-scopedtables.h2
-rw-r--r--gcc/tree-ssa-strlen.c52
-rw-r--r--gcc/tree-ssa-structalias.c19
-rw-r--r--gcc/tree-ssa-threadupdate.c8
-rw-r--r--gcc/tree-ssa-threadupdate.h2
-rw-r--r--gcc/tree-ssa.c36
-rw-r--r--gcc/tree-streamer-in.c98
-rw-r--r--gcc/tree-streamer.h16
-rw-r--r--gcc/tree-switch-conversion.c6
-rw-r--r--gcc/tree-switch-conversion.h30
-rw-r--r--gcc/tree-vect-data-refs.c38
-rw-r--r--gcc/tree-vect-generic.c72
-rw-r--r--gcc/tree-vect-loop-manip.c85
-rw-r--r--gcc/tree-vect-loop.c91
-rw-r--r--gcc/tree-vect-patterns.c9
-rw-r--r--gcc/tree-vect-slp.c7
-rw-r--r--gcc/tree-vect-stmts.c154
-rw-r--r--gcc/tree-vectorizer.c19
-rw-r--r--gcc/tree-vectorizer.h80
-rw-r--r--gcc/tree-vrp.c8
-rw-r--r--gcc/tree.c44
-rw-r--r--gcc/tree.def13
-rw-r--r--gcc/tree.h25
-rw-r--r--gcc/unique-ptr-tests.cc6
-rw-r--r--gcc/value-prof.c2
-rw-r--r--gcc/value-prof.h2
-rw-r--r--gcc/var-tracking.c22
-rw-r--r--gcc/varasm.c40
-rw-r--r--gcc/vec.c3
-rw-r--r--gcc/vector-builder.h7
-rw-r--r--gcc/vr-values.c4
-rw-r--r--gcc/vr-values.h2
-rw-r--r--gcc/web.c2
-rw-r--r--gcc/wide-int-bitmask.h3
-rw-r--r--gcc/wide-int.h15
-rw-r--r--include/ChangeLog5
-rw-r--r--include/demangle.h18
-rw-r--r--libcpp/ChangeLog6
-rw-r--r--libcpp/directives-only.c2
-rw-r--r--libcpp/directives.c6
-rw-r--r--libcpp/files.c2
-rw-r--r--libcpp/include/cpplib.h6
-rw-r--r--libcpp/include/line-map.h76
-rw-r--r--libcpp/include/mkdeps.h20
-rw-r--r--libcpp/init.c4
-rw-r--r--libcpp/internal.h12
-rw-r--r--libcpp/line-map.c90
-rw-r--r--libcpp/mkdeps.c24
-rw-r--r--libgcc/ChangeLog17
-rw-r--r--libgcc/config.host4
-rw-r--r--libgcc/config/or1k/lib1funcs.S6
-rw-r--r--libgcc/config/pa/stublib.c4
-rw-r--r--libgcc/config/pa/t-stublib6
-rw-r--r--libgcc/generic-morestack.c2
-rw-r--r--libgfortran/ChangeLog18
-rw-r--r--libgfortran/io/unix.c47
-rw-r--r--libgfortran/libgfortran.h1
-rw-r--r--libgfortran/runtime/environ.c8
-rw-r--r--libgo/go/runtime/chan.go3
-rw-r--r--libgo/go/runtime/select.go1
-rw-r--r--libgo/runtime/proc.c4
-rw-r--r--libgomp/ChangeLog36
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-10.C119
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-11.C122
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-12.C153
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-13.C161
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-14.C123
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-15.C121
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-16.C153
-rw-r--r--libgomp/testsuite/libgomp.c++/scan-9.C154
-rw-r--r--libgomp/testsuite/libgomp.c-c++-common/loop-1.c127
-rw-r--r--libgomp/testsuite/libgomp.c/scan-10.c116
-rw-r--r--libgomp/testsuite/libgomp.c/scan-11.c118
-rw-r--r--libgomp/testsuite/libgomp.c/scan-12.c120
-rw-r--r--libgomp/testsuite/libgomp.c/scan-13.c91
-rw-r--r--libgomp/testsuite/libgomp.c/scan-14.c182
-rw-r--r--libgomp/testsuite/libgomp.c/scan-15.c118
-rw-r--r--libgomp/testsuite/libgomp.c/scan-16.c120
-rw-r--r--libgomp/testsuite/libgomp.c/scan-17.c89
-rw-r--r--libgomp/testsuite/libgomp.c/scan-18.c182
-rw-r--r--libgomp/testsuite/libgomp.c/scan-19.c119
-rw-r--r--libgomp/testsuite/libgomp.c/scan-20.c119
-rw-r--r--libgomp/testsuite/libgomp.c/scan-9.c116
-rw-r--r--libiberty/ChangeLog16
-rw-r--r--libiberty/cplus-dem.c1
-rw-r--r--libiberty/rust-demangle.c1
-rw-r--r--libiberty/rust-demangle.h45
-rw-r--r--libiberty/simple-object-elf.c33
-rw-r--r--libstdc++-v3/ChangeLog103
-rw-r--r--libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt441
-rw-r--r--libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt441
-rw-r--r--libstdc++-v3/doc/xml/manual/configure.xml20
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2020.xml8
-rw-r--r--libstdc++-v3/include/bits/atomic_base.h871
-rw-r--r--libstdc++-v3/include/bits/stl_tempbuf.h51
-rw-r--r--libstdc++-v3/include/experimental/string_view42
-rw-r--r--libstdc++-v3/include/ext/atomicity.h41
-rw-r--r--libstdc++-v3/include/std/atomic66
-rw-r--r--libstdc++-v3/include/std/bit62
-rw-r--r--libstdc++-v3/include/std/memory2
-rw-r--r--libstdc++-v3/include/std/string_view42
-rw-r--r--libstdc++-v3/include/std/type_traits8
-rw-r--r--libstdc++-v3/include/std/version1
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_one.cc (renamed from libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countl_one.cc)0
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_zero.cc (renamed from libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countl_zero.cc)0
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_one.cc (renamed from libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countr_one.cc)0
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_zero.cc (renamed from libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countr_zero.cc)0
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.count/popcount.cc (renamed from libstdc++-v3/testsuite/26_numerics/bit/bitops.count/popcount.cc)0
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc32
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc74
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotl.cc (renamed from libstdc++-v3/testsuite/26_numerics/bit/bitops.rot/rotl.cc)21
-rw-r--r--libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotr.cc (renamed from libstdc++-v3/testsuite/26_numerics/bit/bitops.rot/rotr.cc)21
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/60695.cc2
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_float/1.cc573
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_float/requirements.cc69
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc41
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/float.cc320
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/generic.cc122
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/integral.cc331
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/pointer.cc225
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic_ref/requirements.cc74
1199 files changed, 65424 insertions, 24248 deletions
diff --git a/ChangeLog b/ChangeLog
index 0ed333d..9693c62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2019-07-08 Kito Cheng <kito.cheng@sifive.com>
+
+ * MAINTAINERS (Write After Approval): Remove myself, already listed in
+ RISC-V port maitainer.
+
+2019-07-08 Kito Cheng <kito.cheng@sifive.com>
+
+ * MAINTAINERS (Write After Approval): Fix the list sorted by surname.
+
+2019-07-08 Kito Cheng <kito.cheng@sifive.com>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
2019-07-03 Andrea Corallo <andrea.corallo@arm.com>
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/config/ChangeLog b/config/ChangeLog
index 63f4325..5a06cde 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2019-07-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * bootstrap-Og.mk: New file.
+
2019-06-25 Kwok Cheung Yeung <kcy@codesourcery.com>
Andrew Stubbs <ams@codesourcery.com>
diff --git a/config/bootstrap-Og.mk b/config/bootstrap-Og.mk
new file mode 100644
index 0000000..9057afb
--- /dev/null
+++ b/config/bootstrap-Og.mk
@@ -0,0 +1 @@
+BOOT_CFLAGS := -Og $(filter-out -O%, $(BOOT_CFLAGS))
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2d6758d..d405921 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,3345 @@
+2019-07-23 Martin Sebor <msebor@redhat.com>
+
+ * configure.ac (ACX_PROG_CXX_WARNING_OPTS): Revert r273311.
+
+2019-07-23 Vladislav Ivanishin <vlad@ispras.ru>
+
+ * gdbinit.in (reload-gdbhooks): New command with an attached doc string.
+ (rh): New alias for it.
+
+2019-07-23 Vladislav Ivanishin <vlad@ispras.ru>
+
+ * gdbhooks.py: Pass replace=True to
+ gdb.printing.register_pretty_printer.
+
+2019-07-23 Richard Biener <rguenther@suse.de>
+
+ PR debug/91231
+ * lto-streamer-in.c (input_function): Drop inline-entry markers
+ that ended up with an unknown location block.
+
+2019-07-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/83518
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Handle aggregate
+ init from a constant even when partial defs are already recorded.
+
+2019-07-23 Jan Hubicka <hubicka@ucw.cz>
+
+ * i386-common.c: Use PROCESSOR_ZNVER2 scheduler for znver2.
+ * config/i386/znver1.md: Enable patterns for znver2 and add store
+ variants which use extra AGU unit.
+
+2019-07-23 Jan Hubicka <hubicka@ucw.cz>
+
+ * config/i386/i386-options.c (ix86_option_override_internal): Default
+ PARAM_AVOID_FMA_MAX_BITS to 256 for znver2.
+ * config/i386/x86-tune.def (X86_TUNE_AVOID_256FMA_CHAINS): Set
+ for ZNVER2.
+
+2019-07-23 Jan Hubicka <hubicka@ucw.cz>
+
+ * config/i386/x86-tune-costs.h (znver2_memcpy): Update.
+ (znver2_costs): Update 256 bit SSE costs and multiplication.
+
+2019-07-23 Jan Beulich <jbeulich@suse.com>
+
+ * config/i386/sse.md (<avx512>_cvtmask2<ssemodesuffix><mode>):
+ Require only AVX512F.
+ (*<avx512>_cvtmask2<ssemodesuffix><mode>): Likewise. Add
+ alternative expanding to vpternlog.
+
+2019-07-23 Martin Liska <mliska@suse.cz>
+
+ * dwarf2out.c (gen_producer_string): Canonize -flto=N
+ to -flto in dwarf producer string.
+
+2019-07-23 Richard Biener <rguenther@suse.de>
+
+ * tree-cfg.c (label_for_bb): Remove global var.
+ (main_block_label): Take label_for_bb as argument.
+ (cleanup_dead_labels_eh): Likewise, adjust.
+ (cleanup_dead_labels): Adjust.
+
+2019-07-22 Paul A. Clarke <pc@us.ibm.com>
+
+ * doc/extend.texi (Basic PowerPC Built-in Functions Available on all
+ Configurations): Add documentation for __builtin_mtfsf.
+
+2019-07-22 Ilia Diachkov <ilia.diachkov@optimitech.com>
+
+ * config/riscv/riscv-opts.h (struct riscv_align_data): New.
+ * config/riscv/riscv.c (riscv_constant_alignment): Use
+ riscv_align_data_type.
+ * config/riscv/riscv.h (RISCV_EXPAND_ALIGNMENT): New.
+ (DATA_ALIGNMENT): Use RISCV_EXPAND_ALIGNMENT.
+ (LOCAL_ALIGNMENT): Use RISCV_EXPAND_ALIGNMENT.
+ * config/riscv/riscv.opt (malign-data): New.
+ * doc/invoke.texi (RISC-V Options): Document -malign-data=.
+
+2019-07-02 Giuliano Belinassi <giuliano.belinassi@usp.br>
+
+ * cgraph.c (dump_graphviz): New function.
+ * cgraph.h (dump_graphviz): New function.
+ * symtab.c (dump_graphviz): New function.
+
+2019-07-22 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ * config/aarch64/aarch64-simd.md
+ (*aarch64_simd_sra<mode>): New.
+ * config/aarch64/iterators.md
+ (SHIFTRT): New iterator.
+ (sra_op): New attribute.
+
+2019-07-22 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.c (msp430_preserve_reg_p): Don't save
+ callee-saved regs R4->R10 in an interrupt function that calls another
+ function.
+
+2019-07-22 Paul A. Clarke <pc@us.ibm.com>
+
+ * config/rs6000/smmintrin.h (_mm_blend_epi16): New.
+ (_mm_blendv_epi8): New.
+
+2019-07-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91221
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Appropriately
+ restrict partial-def handling of empty constructors and
+ memset to refs with known offset.
+
+2019-07-22 Jan Beulich <jbeulich@suse.com>
+
+ * config/i386/sse.md (ternlogsuffix): New.
+ (one_cmpl<mode>2): Don't force CONSTM1_RTX into a register when
+ AVX512F is in use.
+ (<mask_codefor>one_cmpl<mode>2<mask_name>): New.
+
+2019-07-22 Martin Liska <mliska@suse.cz>
+
+ * config/avr/avr.c (avr_asm_output_aligned_decl_common): Update
+ comment.
+ * toplev.c (compile_file): Do not emit __gnu_lto_v1 symbol.
+
+2019-07-22 Martin Liska <mliska@suse.cz>
+
+ * lto-section-in.c (lto_get_section_data):
+ Use new function get_compression.
+ * lto-streamer-out.c (produce_lto_section): Use
+ set_compression to encode compression algorithm.
+ * lto-streamer.h (struct lto_section): Do not
+ use bitfields in the format.
+
+2019-07-22 Martin Liska <mliska@suse.cz>
+
+ PR driver/91172
+ * opts-common.c (decode_cmdline_option): Decode
+ argument of -Werror and check it for a wrong language.
+ * opts-global.c (complain_wrong_lang): Remove such case.
+
+2019-07-22 Claudiu Zissulescu <claziss@synopsys.com>
+
+ * config/arc/arc.c (prepare_move_operands): Always use an
+ intermediate register when storing a TLS symbols.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ * config/or1k/or1k.c (or1k_expand_compare): Check for int before
+ force_reg.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ * config.gcc (or1k*-*-*): Add mhard-float, mdouble-float, msoft-float
+ and munordered-float validations.
+ * config/or1k/constraints.md (d): New register constraint.
+ * config/or1k/predicates.md (fp_comparison_operator): New.
+ * config/or1k/or1k.c (or1k_print_operand): Add support for printing 'd'
+ operands.
+ (or1k_expand_compare): Normalize unordered comparisons.
+ * config/or1k/or1k.h (reg_class): Define DOUBLE_REGS.
+ (REG_CLASS_NAMES): Add "DOUBLE_REGS".
+ (REG_CLASS_CONTENTS): Add contents for DOUBLE_REGS.
+ * config/or1k/or1k.md (type): Add fpu.
+ (fpu): New instruction reservation.
+ (F, f, fr, fi, FI, FOP, fop): New.
+ (<fop><F:mode>3): New ALU instruction definition.
+ (float<fi><F:mode>2): New conversion instruction definition.
+ (fix_trunc<F:mode><fi>2): New conversion instruction definition.
+ (fpcmpcc): New code iterator.
+ (*sf_fp_insn): New instruction definition.
+ (cstore<F:mode>4): New expand definition.
+ (cbranch<F:mode>4): New expand definition.
+ * config/or1k/or1k.opt (msoft-float, mhard-float, mdouble-float,
+ munordered-float): New options.
+ * doc/invoke.texi: Document msoft-float, mhard-float, mdouble-float and
+ munordered-float.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ * config.gcc (or1k*-*-*): Add mrori and mror to validation.
+ * doc/invoke.texi (OpenRISC Options): Add mrori option, rewrite all
+ documenation to be more clear.
+ * config/or1k/elf.opt (mboard=, mnewlib): Rewrite documentation to be
+ more clear.
+ * config/or1k/or1k.opt (mrori): New option.
+ (mhard-div, msoft-div, mhard-mul, msoft-mul, mcmov, mror, msext,
+ msfimm, mshftimm): Rewrite documentation to be more clear.
+ * config/or1k/or1k.md (insn_support): Add ror and rori.
+ (enabled): Add conditions for ror and rori.
+ (rotrsi3): Replace condition for shftimm with ror and rori.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ PR target/90363
+ * config/or1k/or1k.md (zero_extend<mode>si2): Update predicate.
+ (extend<mode>si2): Update predicate.
+ * gcc/config/or1k/predicates.md (volatile_mem_operand): New.
+ (reg_or_mem_operand): New.
+
+2019-07-21 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/rs6000/rs6000.c (TARGET_NO_PROTOTYPE): Move from here...
+ * config/rs6000/rs6000-call.c: ... to here.
+
+2019-07-20 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/predicates.md (offsettable_mem_operand): Allow volatile
+ memory.
+
+2019-07-20 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/predicates.md (input_operand): Allow volatile memory.
+
+2019-07-20 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/predicates.md (lwa_operand): Allow volatile memory.
+
+2019-07-20 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/predicates.md (volatile_mem_operand): Modernize syntax.
+ (any_memory_operand): New predicate.
+ (reg_or_mem_operand): Use it.
+
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/91204
+ * optabs.c (expand_unop): As fallback, expand ~op0 as op0 ^ -1.
+
+2019-07-20 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/pa.h (hppa_profile_hook): Delete declaration.
+ * config/pa/pa-protos.h (hppa_profile_hook): Add declaration.
+
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.def (OMP_LOOP): New tree code.
+ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_BIND.
+ (enum omp_clause_bind_kind): New enum.
+ (struct tree_omp_clause): Add subcode.bind_kind.
+ * tree.h (OMP_LOOP_CHECK): Rename to ...
+ (OMP_LOOPING_CHECK): ... this.
+ (OMP_FOR_BODY, OMP_FOR_CLAUSES, OMP_FOR_INIT, OMP_FOR_COND,
+ OMP_FOR_INCR, OMP_FOR_PRE_BODY, OMP_FOR_ORIG_DECLS): Use
+ OMP_LOOPING_CHECK instead of OMP_LOOP_CHECK.
+ (OMP_CLAUSE_BIND_KIND): Define.
+ * tree.c (omp_clause_num_ops, omp_clause_code_name): Add
+ bind clause entries.
+ (walk_tree_1): Handle OMP_CLAUSE_BIND.
+ * tree-pretty-print.c (dump_omp_clause): Likewise.
+ (dump_generic_node): Handle OMP_LOOP.
+ * gimplify.c (enum omp_region_type): Add ORT_IMPLICIT_TARGET.
+ (in_omp_construct): New variable.
+ (is_gimple_stmt): Handle OMP_LOOP.
+ (gimplify_scan_omp_clauses): For lastprivate don't set
+ check_non_private if code == OMP_LOOP. For reduction clause
+ on OMP_LOOP combined with parallel or teams propagate as shared
+ on the combined construct. Handle OMP_CLAUSE_BIND.
+ (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_BIND.
+ (gimplify_omp_for): Pass OMP_LOOP instead of OMP_{FOR,DISTRIBUTE}
+ for constructs from a loop construct to gimplify_scan_omp_clauses.
+ Don't predetermine iterator linear on OMP_SIMD from loop construct.
+ (replace_reduction_placeholders, gimplify_omp_loop): New functions.
+ (gimplify_omp_workshare): Use ORT_IMPLICIT_TARGET instead of trying
+ to match the implicit ORT_TARGET construct around whole body.
+ Temporarily clear in_omp_construct when processing body.
+ (gimplify_expr): Handle OMP_LOOP. For OMP_MASTER, OMP_TASKGROUP
+ etc. temporarily set in_omp_construct when processing body.
+ (gimplify_body): Create ORT_IMPLICIT_TARGET instead of ORT_TARGET.
+ * omp-low.c (struct omp_context): Add loop_p.
+ (build_outer_var_ref): Treat ctx->loop_p similarly to simd construct
+ in that the original var might be private.
+ (scan_sharing_clauses): Handle OMP_CLAUSE_BIND.
+ (check_omp_nesting_restrictions): Adjust nesting restrictions for
+ addition of loop construct.
+ (scan_omp_1_stmt): Allow setjmp inside of loop construct.
+
+ * omp-low.c (lower_rec_input_clauses): Don't force simd arrays for
+ lastprivate non-addressable iterator of a collapse(1) simd.
+
+2019-07-17 Bill Seurer <seurer@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-call.c (HAVE_AS_GNU_ATTRIBUTE): define value
+ as in rs6000.c.
+
+2019-07-19 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.h (DRIVER_SELF_SPECS): Ignore X and Mach specs which
+ refer to default conditions. Warn for the 'y' spec which is ignored
+ by current linkers.
+
+2019-07-19 Bill Seurer <seurer@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (builtin_description, cpu_is_info,
+ cpu_supports_info, builtin_hash_struct, builtin_hasher,
+ builtin_hash_table, rs6000_builtin_info_type, rs6000_builtin_info,
+ rs6000_aggregate_candidate, rs6000_discover_homogeneous_aggregate,
+ rs6000_return_in_memory, rs6000_return_in_msb, call_ABI_of_interest,
+ init_cumulative_args, rs6000_promote_function_mode,
+ rs6000_must_pass_in_stack, is_complex_IBM_long_double,
+ abi_v4_pass_in_fpr, rs6000_function_arg_padding,
+ rs6000_function_arg_boundary, rs6000_parm_offset,
+ rs6000_parm_start, rs6000_arg_size,
+ rs6000_darwin64_record_arg_advance_flush,
+ rs6000_darwin64_record_arg_advance_recurse,
+ rs6000_darwin64_struct_check_p, rs6000_function_arg_advance_1,
+ rs6000_function_arg_advance, rs6000_darwin64_record_arg_flush,
+ rs6000_darwin64_record_arg_recurse, rs6000_darwin64_record_arg,
+ rs6000_mixed_function_arg, rs6000_psave_function_arg,
+ rs6000_finish_function_arg, rs6000_function_arg,
+ rs6000_arg_partial_bytes, rs6000_pass_by_reference,
+ rs6000_parm_needs_stack, rs6000_function_parms_need_stack,
+ rs6000_reg_parm_stack_space, rs6000_move_block_from_reg,
+ setup_incoming_varargs, rs6000_build_builtin_va_list, rs6000_va_start,
+ rs6000_gimplify_va_arg, def_builtin, bdesc_3arg, bdesc_dst,
+ bdesc_2arg, bdesc_altivec_preds, bdesc_abs, bdesc_1arg, bdesc_0arg,
+ bdesc_htm, rs6000_overloaded_builtin_p, rs6000_overloaded_builtin_name,
+ rs6000_expand_zeroop_builtin, rs6000_expand_mtfsf_builtin,
+ rs6000_expand_mtfsb_builtin, rs6000_expand_set_fpscr_rn_builtin,
+ rs6000_expand_set_fpscr_drn_builtin, rs6000_expand_unop_builtin,
+ altivec_expand_abs_builtin, rs6000_expand_binop_builtin,
+ altivec_expand_predicate_builtin, swap_endian_selector_for_mode,
+ altivec_expand_lv_builtin, altivec_expand_stxvl_builtin,
+ altivec_expand_stv_builtin, htm_spr_num, rs6000_htm_spr_icode,
+ htm_expand_builtin, cpu_expand_builtin, rs6000_expand_ternop_builtin,
+ altivec_expand_dst_builtin, altivec_expand_vec_init_builtin,
+ get_element_number, altivec_expand_vec_set_builtin,
+ altivec_expand_vec_ext_builtin, altivec_expand_builtin,
+ rs6000_builtin_is_supported_p, rs6000_invalid_builtin,
+ rs6000_fold_builtin, rs6000_builtin_valid_without_lhs,
+ fold_build_vec_cmp, fold_compare_helper, fold_mergehl_helper,
+ fold_mergeeo_helper, rs6000_gimple_fold_builtin,
+ rs6000_expand_builtin, rs6000_vector_type,
+ rs6000_init_builtins, rs6000_builtin_decl, altivec_init_builtins,
+ htm_init_builtins, builtin_function_type, rs6000_common_init_builtins,
+ rs6000_internal_arg_pointer, rs6000_output_mi_thunk): Move
+ to rs6000-call.c.
+ * config/rs6000/rs6000-call.c (builtin_description, cpu_is_info,
+ cpu_supports_info, builtin_hash_struct, builtin_hasher,
+ builtin_hash_table, rs6000_builtin_info_type, rs6000_builtin_info,
+ rs6000_aggregate_candidate, rs6000_discover_homogeneous_aggregate,
+ rs6000_return_in_memory, rs6000_return_in_msb, call_ABI_of_interest,
+ init_cumulative_args, rs6000_promote_function_mode,
+ rs6000_must_pass_in_stack, is_complex_IBM_long_double,
+ abi_v4_pass_in_fpr, rs6000_function_arg_padding,
+ rs6000_function_arg_boundary, rs6000_parm_offset,
+ rs6000_parm_start, rs6000_arg_size,
+ rs6000_darwin64_record_arg_advance_flush,
+ rs6000_darwin64_record_arg_advance_recurse,
+ rs6000_darwin64_struct_check_p, rs6000_function_arg_advance_1,
+ rs6000_function_arg_advance, rs6000_darwin64_record_arg_flush,
+ rs6000_darwin64_record_arg_recurse, rs6000_darwin64_record_arg,
+ rs6000_mixed_function_arg, rs6000_psave_function_arg,
+ rs6000_finish_function_arg, rs6000_function_arg,
+ rs6000_arg_partial_bytes, rs6000_pass_by_reference,
+ rs6000_parm_needs_stack, rs6000_function_parms_need_stack,
+ rs6000_reg_parm_stack_space, rs6000_move_block_from_reg,
+ setup_incoming_varargs, rs6000_build_builtin_va_list, rs6000_va_start,
+ rs6000_gimplify_va_arg, def_builtin, bdesc_3arg, bdesc_dst,
+ bdesc_2arg, bdesc_altivec_preds, bdesc_abs, bdesc_1arg, bdesc_0arg,
+ bdesc_htm, rs6000_overloaded_builtin_p, rs6000_overloaded_builtin_name,
+ rs6000_expand_zeroop_builtin, rs6000_expand_mtfsf_builtin,
+ rs6000_expand_mtfsb_builtin, rs6000_expand_set_fpscr_rn_builtin,
+ rs6000_expand_set_fpscr_drn_builtin, rs6000_expand_unop_builtin,
+ altivec_expand_abs_builtin, rs6000_expand_binop_builtin,
+ altivec_expand_predicate_builtin, swap_endian_selector_for_mode,
+ altivec_expand_lv_builtin, altivec_expand_stxvl_builtin,
+ altivec_expand_stv_builtin, htm_spr_num, rs6000_htm_spr_icode,
+ htm_expand_builtin, cpu_expand_builtin, rs6000_expand_ternop_builtin,
+ altivec_expand_dst_builtin, altivec_expand_vec_init_builtin,
+ get_element_number, altivec_expand_vec_set_builtin,
+ altivec_expand_vec_ext_builtin, altivec_expand_builtin,
+ rs6000_builtin_is_supported_p, rs6000_invalid_builtin,
+ rs6000_fold_builtin, rs6000_builtin_valid_without_lhs,
+ fold_build_vec_cmp, fold_compare_helper, fold_mergehl_helper,
+ fold_mergeeo_helper, rs6000_gimple_fold_builtin,
+ rs6000_expand_builtin, rs6000_vector_type,
+ rs6000_init_builtins, rs6000_builtin_decl, altivec_init_builtins,
+ htm_init_builtins, builtin_function_type, rs6000_common_init_builtins,
+ rs6000_internal_arg_pointer, rs6000_output_mi_thunk: Move
+ to here from rs6000.c.
+ * config/rs6000/rs6000-internal.h: (rs6000_darwin64_struct_check_p,
+ rs6000_discover_homogeneous_aggregate, rs6000_output_mi_thunk,
+ rs6000_output_addr_const_extra, rs6000_gimple_fold_builtin,
+ rs6000_invalid_builtin, rs6000_build_builtin_va_list, rs6000_va_start,
+ rs6000_gimplify_va_arg, rs6000_promote_function_mode,
+ rs6000_return_in_memory, rs6000_return_in_msb,
+ rs6000_pass_by_reference, setup_incoming_varargs,
+ rs6000_function_arg_boundary, rs6000_must_pass_in_stack,
+ rs6000_arg_partial_bytes, rs6000_function_arg_advance,
+ rs6000_function_arg_padding, rs6000_function_arg,
+ rs6000_darwin64_record_arg, rs6000_internal_arg_pointer,
+ rs6000_init_builtins, rs6000_builtin_decl, rs6000_expand_builtin,
+ rs6000_fold_builtin, rs6000_passes_ieee128, rs6000_passes_float,
+ rs6000_passes_long_double, rs6000_passes_vector,
+ rs6000_returns_struct, cpu_builtin_p, tree builtin_mode_to_type,
+ altivec_builtin_mask_for_load) Add declarations.
+ * config/rs6000/t-rs6000: Add new source file rs6000-call.c.
+ * config/config.gcc: Add new source file rs6000-call.c to garbage
+ collector and extra_objs.
+
+2019-07-19 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dse.c (initialize_ao_ref_for_dse): Handle
+ strncpy. Drop some trivial dead code.
+ (maybe_trim_memstar_call): Handle strncpy.
+
+2019-07-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91211
+ * tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Fix
+ memset encoding size.
+
+2019-07-19 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91204
+ * config/i386/mmx.md (one_cmpl<mode>2): New expander.
+
+2019-07-19 Jan Hubicka <hubicka@ucw.cz>
+
+ PR ipa/91194
+ * ipa-inline.c (recursive_inlining): Fix limits check.
+
+2019-07-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91200
+ * tree-ssa-phiopt.c (cond_store_replacement): Check we have
+ no PHI nodes in middle-bb.
+
+2019-07-19 Richard Sandiford <richard.sandiford@arm.com>
+
+ * doc/invoke.texi: Rename the AArch64 +bitperm extension flag
+ to +sve-bitperm.
+ * config/aarch64/aarch64-option-extensions.def: Likewise.
+
+2019-07-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91190
+ * function.c (insert_temp_slot_address): Store into the hash table
+ a copy of address to avoid RTL sharing issues.
+
+2019-07-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91207
+ Revert
+ 2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91178
+ * tree-vect-stmts.c (get_group_load_store_type): For SLP
+ loads with a gap larger than the vector size always use
+ VMAT_STRIDED_SLP.
+ (vectorizable_load): For VMAT_STRIDED_SLP with a permutation
+ avoid loading vectors that are only contained in the gap
+ and thus are not needed.
+
+2019-07-18 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*addqi_2_slp): Remove.
+ (*<code>qi_2_slp): Ditto.
+
+2019-07-18 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/predicates.md (prefixed_mem_operand): Call
+ rs6000_prefixed_address_mode_p instead of rs6000_prefixed_address.
+ * config/rs6000/rs6000-protos.h (rs6000_prefixed_address_mode_p):
+ Rename function from rs6000_prefixed_address.
+ * config/rs6000/aix.h (TARGET_HAS_TOC): Rename TARGET_TOC to
+ TARGET_HAS_TOC.
+ (TARGET_TOC): Likewise.
+ (TARGET_NO_TOC): Delete here, define TARGET_NO_TOC_OR_PCREL in
+ rs6000.h.
+ * config/rs6000/darwin.h (TARGET_HAS_TOC): Rename TARGET_TOC to
+ TARGET_HAS_TOC.
+ (TARGET_TOC): Likewise.
+ (TARGET_NO_TOC): Delete here, define TARGET_NO_TOC_OR_PCREL in
+ rs6000.h.
+ * config/rs6000/linux64.h (TARGET_HAS_TOC): Rename TARGET_TOC to
+ TARGET_HAS_TOC.
+ (TARGET_TOC): Likewise.
+ * config/rs6000/rs6000.c (rs6000_option_override_internal): Add
+ check to require -mcmodel=medium for pc-relative addressing.
+ (create_TOC_reference): Add assertion for TARGET_TOC.
+ (rs6000_legitimize_address): Use TARGET_NO_TOC_OR_PCREL instead of
+ TARGET_NO_TOC.
+ (rs6000_emit_move): Likewise.
+ (TOC_alias_set): Rename TOC alias set static variable from 'set'
+ to 'TOC_alias_set'.
+ (get_TOC_alias_set): Likewise.
+ (output_toc): Use TARGET_NO_TOC_OR_PCREL instead of
+ TARGET_NO_TOC.
+ (rs6000_can_eliminate): Likewise.
+ (rs6000_prefixed_address_mode_p): Rename function from
+ rs6000_prefixed_address.
+ * config/rs6000/rs6000.h (TARGET_TOC): Define in terms of
+ TARGET_HAS_TOC and not pc-relative.
+ (TARGET_NO_TOC_OR_PCREL): New macro to replace TARGET_NO_TOC.
+ * config/rs6000/sysv4.h (TARGET_HAS_TOC): Rename TARGET_TOC to
+ TARGET_HAS_TOC.
+ (TARGET_TOC): Likewise.
+ (TARGET_NO_TOC): Delete here, define TARGET_NO_TOC_OR_PCREL in
+ rs6000.h.
+
+2019-07-18 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91188
+ * config/i386/i386.md (*addqi_1_slp): Use register_operand predicate
+ for operand 0. Do not use (match_dup) to match operand 1 with
+ operand 0. Add check in insn constraint that either input operand
+ matches operand 0. Use SWI12 mode iterator to also handle
+ HImode operands.
+ (*and<mode>_1_slp): Ditto.
+ (*<code>qi_1_slp): Ditto.
+ (*sub<mode>_1_slp): Use register_operand predicate for operand 0.
+ Do not use (match_dup) to match operand 1 with operand 0. Add
+ check in insn constraint that operand 1 matches operand 0.
+ Use SWI12 mode iterator to also handle HImode operands.
+ (*ashl<mode>3_1_slp): Ditto.
+ (*<shift_insn><mode>3_1_slp): Ditto.
+ (*<rotate_insn><mode>3_1_slp): Ditto.
+
+2019-07-18 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ * config/arm/arm-builtins.c
+ (arm_expand_ternop_builtin): Remove explicit sha1 builtin handling.
+ (arm_expand_unop_builtin): Likewise.
+ * config/arm/crypto.md
+ (crypto_sha1h): Convert from define_insn to define_expand.
+ (crypto_<crypto_pattern>): Likewise.
+ (crypto_sha1h_lb): New define_insn.
+ (crypto_<crypto_pattern>_lb): Likewise.
+
+2019-07-18 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ PR target/90317
+ * config/arm/arm_neon.h
+ (vsha1h_u32): Refactor.
+ (vsha1cq_u32): Likewise.
+ (vsha1pq_u32): Likewise.
+ (vsha1mq_u32): Likewise.
+ * config/arm/crypto.md:
+ (crypto_sha1h): Remove zero extend, correct vec select.
+ (crypto_sha1c): Correct vec select.
+ (crypto_sha1m): Likewise.
+ (crypto_sha1p): Likewise.
+
+2019-07-18 Richard Earnshaw <rearnsha@arm.com>
+
+ * config/arm/predicates.md (arm_borrow_operation): New predicate.
+ * config/arm/arm.c (subdi3_compare1): Use CCmode for the split.
+ (arm_subdi3, subdi_di_zesidi, subdi_di_sesidi): Likewise.
+ (subdi_zesidi_zesidi): Likewise.
+ (negdi2_compare, negdi2_insn): Likewise.
+ (negdi_extensidi): Likewise.
+ (negdi_zero_extendsidi): Likewise.
+ (arm_cmpdi_insn): Likewise.
+ (subsi3_carryin): Use arm_borrow_operation.
+ (subsi3_carryin_const): Likewise.
+ (subsi3_carryin_const0): Likewise.
+ (subsi3_carryin_compare): Likewise.
+ (subsi3_carryin_compare_const): Likewise.
+ (subsi3_carryin_compare_const0): Likewise.
+ (subsi3_carryin_shift): Likewise.
+ (rsbsi3_carryin_shift): Likewise.
+ (negsi2_carryin_compare): Likewise.
+
+2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com>
+
+ PR tree-optimization/91137
+ * tree-ssa-loop-ivopts.c (struct ivopts_data): New field.
+ (tree_ssa_iv_optimize_init, alloc_iv, tree_ssa_iv_optimize_finalize):
+ Init, use and fini the above new field.
+ (determine_base_object_1): New function.
+ (determine_base_object): Reimplement using walk_tree.
+
+2019-07-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * basic-block.h (CLEANUP_FORCE_FAST_DCE): New macro.
+ * cfgcleanup.c (cleanup_cfg): Call run_fast_dce if
+ CLEANUP_FORCE_FAST_DCE is set.
+ * ifcvt.c (rest_of_handle_if_conversion): Pass
+ CLEANUP_FORCE_FAST_DCE to the final cleanup_cfg call if
+ if-conversion succeeded.
+
+2019-07-18 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Refactor
+ branches to make code less indented.
+
+2019-07-17 Alexandre Oliva <oliva@adacore.com>
+
+ PR middle-end/81824
+ * attribs.c (decls_mismatched_attributes): Simplify the logic
+ that avoids duplicates and false positives.
+
+2019-07-17 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/pa.c (pa_som_asm_init_sections): Don't force all constant
+ data into data section when generating PIC code.
+ (pa_select_section): Use pa_reloc_rw_mask() to qualify relocs.
+ (pa_reloc_rw_mask): Return 3 when generating PIC code and when
+ generating code for SOM targets earlier than HP-UX 11. Otherwise,
+ return 2 for SOM and 0 for other targets.
+
+2019-07-17 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dse.c (initialize_ao_ref_for_dse): Fix formatting.
+ (dse_walker::dse_optimize_stmt): Likewise. Add missing return to
+ avoid unexpected switch statement fallthru.
+
+2019-07-17 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*add<dwi>3_doubleword):
+ Remove redundant constraints.
+ (*add<mode>_1): Ditto.
+ (*addhi_1): Ditto.
+ (*addqi_1): Ditto.
+ (*addqi_1_slp): Ditto.
+ (*add<mode>_2): Ditto.
+ (*addv<mode>4): Ditto.
+ (*sub<dwi>3_doubleword): Ditto.
+ (*sub<mode>_1): Ditto.
+ (*subqi_1_slp): Ditto.
+ (*sub<mode>_2): Ditto.
+ (*subv<mode>4): Ditto.
+ (*sub<mode>_3): Ditto.
+ (@add<mode>3_carry): Ditto.
+ (@sub<mode>3_carry): Ditto.
+ (*add<mode>3_cc_overflow_1): Ditto.
+ (*add<mode>3_zext_cc_overflow_2): Ditto.
+ (*anddi_1): Ditto.
+ (*and<mode>_1): Ditto.
+ (*andqi_1): Ditto.
+ (*andqi_1_slp): Ditto.
+ (*anddi_2): Ditto.
+ (*andqi_2_maybe_si): Ditto.
+ (*and<mode>_2): Ditto.
+ (*andqi_2_slp): Ditto.
+ (*<code><mode>_1): Ditto.
+ (*<code>qi_1): Ditto.
+ (*<code>qi_1_slp): Ditto.
+ (*<code><mode>_2): Ditto.
+ (*<code>qi_2_slp): Ditto.
+
+2019-07-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * alias.c (record_component_aliases): Do not simplify pointed-to
+ types of ODR types.
+
+2019-07-17 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*andqi_2_maybe_si): Handle potential
+ partial reg stall on alternative 2.
+
+2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91178
+ * tree-ssa.c (release_defs_bitset): Iterate from higher to
+ lower SSA names to avoid quadratic behavior in the common case.
+ * tree-data-ref.c (split_constant_offset): Add limit argument
+ and pass it down. Initialize it from PARAM_SSA_NAME_DEF_CHAIN_LIMIT.
+ (split_constant_offset_1): Add limit argument and use it to
+ limit SSA def walking. Optimize the common plus/minus case.
+
+2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91178
+ * tree-vect-stmts.c (get_group_load_store_type): For SLP
+ loads with a gap larger than the vector size always use
+ VMAT_STRIDED_SLP.
+ (vectorizable_load): For VMAT_STRIDED_SLP with a permutation
+ avoid loading vectors that are only contained in the gap
+ and thus are not needed.
+
+2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91180
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Fix offset
+ computation for memset partial defs.
+
+2019-07-17 Jakub Jelinek <jakub@redhat.com>
+
+ * gimple.h (enum gf_mask): Remove GF_OMP_FOR_SIMD, change
+ GF_OMP_FOR_KIND_SIMD to a value serially after other kinds,
+ divide GF_OMP_FOR_KIND_MASK, GF_OMP_FOR_COMBINED,
+ GF_OMP_FOR_COMBINED_INTO, GF_OMP_FOR_GRID_PHONY,
+ GF_OMP_FOR_GRID_INTRA_GROUP and GF_OMP_FOR_GRID_GROUP_ITER by two.
+ * omp-grid.c (grid_process_grid_body,
+ grid_eliminate_combined_simd_part): Use GF_OMP_FOR_KIND_SIMD instead
+ of GF_OMP_FOR_SIMD, don't test & GF_OMP_FOR_SIMD but
+ == GF_OMP_FOR_KIND_SIMD.
+ * omp-low.c (build_outer_var_ref, scan_sharing_clauses,
+ check_omp_nesting_restrictions, scan_omp_1_stmt,
+ lower_rec_input_clauses, lower_lastprivate_conditional_clauses,
+ lower_lastprivate_clauses, lower_reduction_clauses, lower_omp_scan,
+ omp_find_scan): Likewise.
+ * omp-expand.c (expand_omp_for): Likewise.
+ * omp-general.c (omp_extract_for_data): Likewise.
+
+ PR tree-optimization/91157
+ * tree-vect-generic.c (expand_vector_comparison): Handle lhs being
+ a vector boolean with scalar mode.
+ (expand_vector_condition): Handle first operand being a vector boolean
+ with scalar mode.
+ (expand_vector_operations_1): For comparisons, don't bail out early
+ if the return type is vector boolean with scalar mode, but comparison
+ operand type is not.
+
+2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91181
+ * tree-vect-slp.c (vect_build_slp_tree_1): Do not compare
+ IFN_LOADs as calls.
+
+2019-07-16 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*testdi_1): Match CCZmode for
+ constants that might have the SImode sign bit set.
+ (*testqi_1_maybe_si): Remove "!" constraint modifier.
+ Use correct constraints for pentium pairing.
+ (*test<mode>_1): Ditto.
+
+2019-07-16 Jeff Law <law@redhat.com>
+
+ PR rtl-optimization/91173
+ * tree-ssa-address.c (addr_for_mem_ref): If the base is an
+ SSA_NAME with a constant value, fold its value into the offset
+ and clear the base before calling gen_addr_rtx.
+
+2019-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/91164
+ * dse.c (rest_of_handle_dse): If dead edges have been purged,
+ invalidate dominance info.
+
+2019-07-16 Richard Sandiford <richard.sandiford@arm.com>
+
+ * read-md.h (md_reader::record_potential_iterator_use): Add a
+ file_location parameter.
+ * read-rtl.c (attribute_use::loc): New field.
+ (map_attr_string): Take a file_location parameter. Report cases
+ in which attributes map to multiple distinct values.
+ (apply_attribute_uses): Update call accordingly.
+ (md_reader::handle_overloaded_name): Likewise.
+ (md_reader::apply_iterator_to_string): Likewise. Skip empty
+ nonnull strings.
+ (record_attribute_use): Take a file_location parameter.
+ Initialize attribute_use::loc.
+ (md_reader::record_potential_iterator_use): Take a file_location
+ parameter. Update call to record_attribute_use.
+ (rtx_reader::rtx_alloc_for_name): Update call accordingly.
+ (rtx_reader::read_rtx_code): Likewise.
+ (rtx_reader::read_rtx_operand): Likewise. Record a location
+ for implicitly-expanded empty strings.
+
+2019-07-16 Richard Sandiford <richard.sandiford@arm.com>
+
+ * read-md.h (md_reader::ptr_loc): Moved from read-md.c.
+ Use file_location instead of separate fields.
+ (md_reader::set_md_ptr_loc): Take a file_location instead of a
+ separate filename and line number.
+ * read-md.c (ptr_loc): As above.
+ (md_reader::copy_md_ptr_loc): Update for new ptr_loc layout.
+ (md_reader::fprint_md_ptr_loc): Likewise.
+ (md_reader::set_md_ptr_loc): Likewise. Take a file_location
+ instead of a separate filename and line number.
+ (md_reader::read_string): Update call accordingly.
+
+2019-07-16 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/rs6000/rs6000.md (*mov<mode>_update1): Explicitly
+ use <SFDF:mode>, <SFDF:MODE>, <SFDF:Ff> and <SFDF:bits> rather than
+ leaving the choice between SFDF and P implicit.
+ (*mov<mode>_update2): Likewise.
+ (*cmp<IBM128:mode>_internal2): Explicitly use <IBM128:MODE>
+ rather than leaving the choice betweem IBM128 and GPR implicit.
+ (*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem): Explicitly use
+ <IEEE128:MODE> rather than leaving the choice between IEEE128 and
+ QHSI implicit.
+ (AltiVec define_peephole2s): Explicitly use <ALTIVEC_DFORM:MODE>
+ rather than leaving the choice between ALTIVEC_DFORM and P implicit.
+ * config/rs6000/vsx.md
+ (*vsx_ext_<VSX_EXTRACT_I:VS_scalar>_fl_<FL_CONV:mode>)
+ (*vsx_ext_<VSX_EXTRACT_I:VS_scalar>_ufl_<FL_CONV:mode>): Explicitly
+ use <FL_CONV:VSisa> rather than leaving the choice between FL_CONV
+ and VSX_EXTRACT_I implicit.
+
+2019-07-16 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/mips/micromips.md (*movep<MOVEP1:mode><MOVEP2:mode>):
+ Explicitly use <MOVEP1:MODE> for the mode attribute.
+
+2019-07-16 Jan Hubicka <hubicka@ucw.cz>
+
+ PR bootstrap/91176
+ * ipa-fnsummary.c (analyze_function_body): Skip debug stmts
+
+2019-07-15 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/91050
+ * config/rs6000/rs6000.c (rs6000_file_start): Never skip emitting a
+ .machine directive.
+
+2019-07-15 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (@test<mode>_ccno_1):
+ Rename from test<mode>_ccno_1.
+ (*testdi_1): Remove redundant alternatives. Remove modrm attribute.
+ (*testqi_1_maybe_si): Remove modrm attribute.
+ (*test<mode>_1): Ditto.
+ * config/i386/i386-expand.c (ix86_split_idivmod): Use
+ gen_test_ccno_1 and gen_extend_insn.
+
+2019-07-15 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-ssa-alias.c (aliasing_component_refs_walk): Initialize same_p
+ to 0.
+
+2019-07-15 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91162
+ * tree-cfg.c (move_block_to_fn): When releasing a virtual PHI
+ node make sure to replace all uses with something valid.
+
+2019-07-15 Kewen Lin <linkw@gcc.gnu.org>
+
+ PR tree-optimization/88497
+ * tree-ssa-reassoc.c (reassociate_bb): Swap the positions of
+ GIMPLE_BINARY_RHS check and gimple_visited_p check, call new
+ function undistribute_bitref_for_vector.
+ (undistribute_bitref_for_vector): New function.
+ (cleanup_vinfo_map): Likewise.
+ (sort_by_mach_mode): Likewise.
+
+2019-07-14 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (nonmemory_szext_operand): New mode attribute.
+ (test<mode>_ccno_1): Macroize insn pattern from testsi_ccno_1
+ and testdi_ccno_1 using SWI48 mode attribute.
+ (*testdi_1): Use x86_64_szext_nonmemory_operand instead of
+ x86_64_szext_general_operand.
+ (*testqi_1_maybe_si): Use nonmemory_operand instead of general_operand.
+ (*test<mode>_1): Use nonmemory_szext_operand mode attribute
+ instead of genera_operand mode attribute.
+
+2019-07-14 Vladislav Ivanishin <vlad@ispras.ru>
+
+ * gdbhooks.py (DumpFn.invoke): Add explicit casts of return values of
+ fopen and fclose to their respective types.
+ (DotFn.invoke): Ditto.
+
+2019-07-14 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-fnsummary.c (ipa_dump_hints): Do not dump array_index.
+ (ipa_fn_summary::~ipa_fn_summary): Do not destroy array_index.
+ (ipa_fn_summary_t::duplicate): Do not duplicate array_index.
+ (array_index_predicate): Remove.
+ (analyze_function_body): Account cost for variable ofsetted array
+ indexing.
+ (estimate_node_size_and_time): Do not compute array index hint.
+ (ipa_merge_fn_summary_after_inlining): Do not merge array index hint.
+ (inline_read_section): Do not read array index hint.
+ (ipa_fn_summary_write): Do not write array index hint.
+ * doc/invoke.texi (ipa-cp-array-index-hint-bonus): Remove.
+ * ipa-cp.c (hint_time_bonus): Remove.
+ * ipa-fnsummary.h (ipa_hints_vals): Remove array_index.
+ (ipa_fnsummary): Remove array_index.
+ * ipa-inline.c (want_inline_small_function_p): Do not use
+ array_index.
+ (edge_badness): Likewise.
+ * params.def (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS): Remove.
+
+2019-07-14 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/91148
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Remove
+ superfluous "builtin function" phrasing.
+
+2019-07-13 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-ssa-alias.c (component_ref_to_zero_sized_trailing_array_p):
+ Break out from ...
+ (aliasing_component_refs_walk): Break out from ...
+ (aliasing_component_refs_p): ... here.
+
+2019-07-13 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/91148
+ * config/rs6000/rs6000.c (rs6000_invalid_builtin): Remove superfluous
+ "builtin function" phrasing.
+
+2019-07-13 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR target/90723
+ * recog.h (temporary_volatile_ok): New class.
+ * config/aarch64/aarch64.c (aarch64_emit_sve_pred_move): Set
+ volatile_ok temporarily to true using temporary_volatile_ok.
+ * expr.c (emit_block_move_via_cpymem): Likewise.
+ * optabs.c (maybe_legitimize_operand): Likewise.
+
+2019-07-13 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (struct gimplify_omp_ctx): Add order_concurrent member.
+ (omp_notice_threadprivate_variable): Diagnose threadprivate variable
+ uses inside of order(concurrent) constructs.
+ (gimplify_scan_omp_clauses): Set ctx->order_concurrent if
+ OMP_CLAUSE_ORDER is seen.
+ * omp-low.c (struct omp_context): Add order_concurrent member.
+ (scan_sharing_clauses): Set ctx->order_concurrent if
+ OMP_CLAUSE_ORDER is seen.
+ (check_omp_nesting_restrictions): Diagnose ordered or atomic inside
+ of simd order(concurrent). Diagnose constructs not allowed inside of
+ for order(concurrent).
+ (setjmp_or_longjmp_p): Add a context and TREE_PUBLIC check to avoid
+ complaining about static double setjmp (double); or class static
+ methods or non-global namespace setjmps.
+ (omp_runtime_api_call): New function.
+ (scan_omp_1_stmt): Diagnose OpenMP runtime API calls inside of
+ order(concurrent) loops.
+
+2019-07-12 Martin Sebor <msebor@redhat.com>
+
+ * doc/invoke.texi (ssa-name-def-chain-limit): Document new --param.
+ * params.def (PARAM_SSA_NAME_DEF_CHAIN_LIMIT): Add new --param.
+ * tree-vrp.c (vrp_prop::check_mem_ref): Use
+ PARAM_SSA_NAME_DEF_CHAIN_LIMIT.
+
+2019-07-12 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-alias.c (same_tmr_indexing_p): Break out from ...
+ (indirect_refs_may_alias_p): ... here.
+ (nonoverlapping_component_refs_since_match_p): Support also non-trivial
+ mem refs in the access paths.
+
+2019-07-12 Jiangning Liu <jiangning.liu@amperecomputing.com>
+
+ PR tree-optimization/89430
+ * tree-ssa-phiopt.c (cond_store_replacement): Support conditional
+ store elimination for local variable without address escape.
+
+2019-07-12 Jeff Law <law@redhat.com>
+
+ * config/c6x/c6x.c (c6x_section_type): Clear SECTION_NOTYPE
+ for the ".far" section.
+
+2019-07-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91145
+ * tree-vect-slp.c (vect_build_slp_tree_2): Fix reduction
+ chain check.
+
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
+
+ * tree-eh.c (honor_protect_cleanup_actions): Use outer_
+ rather than this_state as the lowering context for the ELSE
+ seq in a GIMPLE_EH_ELSE.
+
+2019-07-12 Richard Sandiford <richard.sandiford@arm.com>
+
+ * vector-builder.h (vector_builder::elt): Allow already-supplied
+ elements to be read back before building is complete.
+
+2019-07-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR rtl-optimization/91136
+ * df-core.c (ACCESSING REFS): Fix typos in comment.
+ * resource.c (mark_target_live_reg): Add artificial defs that occur at
+ the beginning of the block to the initial set of live registers.
+
+2019-07-12 Richard Biener <rguenther@suse.de>
+
+ * fold-const.h (get_array_ctor_element_at_index): Adjust.
+ * fold-const.c (get_array_ctor_element_at_index): Add
+ ctor_idx output parameter informing the caller where in
+ the constructor the element was (not) found. Add early exit
+ for when the ctor is sorted.
+ * gimple-fold.c (fold_array_ctor_reference): Support constant
+ folding across multiple array elements.
+
+2019-07-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cfgexpand.c (expand_gimple_stmt_1) <GIMPLE_RETURN>: If the statement
+ doesn't have location, set the current location to the function's end.
+
+2019-07-12 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.md (*compare_condjump<mode>)
+ (loadwb_pair<GPI:mode>_<P:mode>, loadwb_pair<GPF:mode>_<P:mode>)
+ (storewb_pair<GPI:mode>_<P:mode>, storewb_pair<GPF:mode>_<P:mode>)
+ (*ands<mode>_compare0): Fix ambiguous uses of .md attributes.
+ * config/aarch64/aarch64-simd.md
+ (*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>): Likewise.
+ (*aarch64_get_lane_zero_extend<GPI:mode><VDQQH:mode>): Likewise.
+ * config/aarch64/aarch64-sve.md
+ (while_ult<GPI:mode><PRED_ALL:mode>): Likewise.
+ (*cond_<optab><mode>_any): Fix SVE_I/SVE_SDI typo.
+
+2019-07-12 Richard Sandiford <richard.sandiford@arm.com>
+
+ * doc/md.texi: Document that @ patterns can have different
+ numbers of operands.
+ * genemit.c (handle_overloaded_gen): Handle this case.
+ * genopinit.c (handle_overloaded_gen): Likewise.
+ * gensupport.c (replace_operands_with_dups): Iterate over
+ the new rtx's format rather than the old one's.
+
+2019-07-12 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_ORDER.
+ * tree.c (omp_clause_num_ops, omp_clause_code_name): Add
+ order clause entries.
+ (walk_tree_1): Handle OMP_CLAUSE_ORDER.
+ * tree-pretty-print.c (dump_omp_clause): Likewise.
+ * gimplify.c (gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses):
+ Likewise.
+ * omp-low.c (scan_sharing_clauses): Likewise.
+ * tree-nested.c (convert_nonlocal_omp_clauses,
+ convert_local_omp_clauses): Likewise.
+
+2019-07-12 Kewen Lin <linkw@gcc.gnu.org>
+
+ * gcc/cfgrtl.c (print_rtl_with_bb): Emit a hint if the
+ fallthrough target of current basic block isn't the placed
+ right next.
+
+2019-07-11 Sunil K Pandey <sunil.k.pandey@intel.com>
+
+ PR target/90980
+ * config/i386/avx512fintrin.h (_mm512_loadu_epi64): New.
+ (_mm512_storeu_epi64): Likewise.
+ (_mm512_loadu_epi32): Likewise.
+ (_mm512_storeu_epi32): Likewise.
+ * config/i386/avx512vlintrin.h (_mm256_storeu_epi64): New.
+ (_mm_storeu_epi64): Likewise.
+ (_mm256_storeu_epi32): Likewise.
+ (_mm_storeu_epi32): Likewise.
+
+2019-07-11 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000-logue.c: Add Modula-2 to comment.
+
+2019-07-11 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000-logue.c (rs6000_output_function_epilogue):
+ Handle Modula-2.
+
+2019-07-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/91124
+ * config/i386/sse.md (sse2_cvtpd2dq<mask_name>): Change into ...
+ (sse2_cvtpd2dq): ... this. Remove mask substitution macros.
+ (sse2_cvtpd2dq_mask, sse2_cvtpd2dq_mask_1): New define_insns.
+ (ufix_notruncv2dfv2si2<mask_name>): Change into ...
+ (ufix_notruncv2dfv2si2): ... this. Remove mask substitution macros.
+ (ufix_notruncv2dfv2si2_mask, ufix_notruncv2dfv2si2_mask_1): New
+ define_insns.
+ (ufix_truncv2dfv2si2<mask_name>): Change into ...
+ (ufix_truncv2dfv2si2): ... this. Remove mask substitution macros.
+ (ufix_truncv2dfv2si2_mask, ufix_truncv2dfv2si2_mask_1): New
+ define_insns.
+ (sse2_cvttpd2dq<mask_name>): Change into ...
+ (sse2_cvttpd2dq): ... this. Remove mask substitution macros.
+ (sse2_cvttpd2dq_mask, sse2_cvttpd2dq_mask_1): New define_insns.
+ (*sse2_cvtpd2dq<mask_name>): Change into ...
+ (*sse2_cvtpd2dq): ... this. Remove mask substitution macros.
+ Add "C" constraint to const0_operand.
+ (*sse2_cvtpd2dq_mask, *sse2_cvtpd2dq_mask_1): New define_insns.
+ (sse2_cvtpd2ps_mask): Adjust expand to match *sse2_cvtpd2ps_mask
+ changes.
+
+ PR target/91124
+ * config/i386/i386-builtin-types.def
+ (V32HI_FTYPE_V32HI_V32HI_V32HI_INT,
+ V16HI_FTYPE_V16HI_V16HI_V16HI_INT, V8HI_FTYPE_V8HI_V8HI_V8HI_INT,
+ V8SI_FTYPE_V8SI_V8SI_V8SI_INT, V4DI_FTYPE_V4DI_V4DI_V4DI_INT,
+ V8DI_FTYPE_V8DI_V8DI_V8DI_INT, V16SI_FTYPE_V16SI_V16SI_V16SI_INT,
+ V2DI_FTYPE_V2DI_V2DI_V2DI_INT, V4SI_FTYPE_V4SI_V4SI_V4SI_INT): Remove.
+ * config/i386/i386-builtin.def (__builtin_ia32_vpshrdv_v32hi_mask,
+ __builtin_ia32_vpshrdv_v32hi_maskz, __builtin_ia32_vpshrdv_v16hi_mask,
+ __builtin_ia32_vpshrdv_v16hi_maskz, __builtin_ia32_vpshrdv_v8hi_mask,
+ __builtin_ia32_vpshrdv_v8hi_maskz, __builtin_ia32_vpshrdv_v16si_mask,
+ __builtin_ia32_vpshrdv_v16si_maskz, __builtin_ia32_vpshrdv_v8si_mask,
+ __builtin_ia32_vpshrdv_v8si_maskz, __builtin_ia32_vpshrdv_v4si_mask,
+ __builtin_ia32_vpshrdv_v4si_maskz, __builtin_ia32_vpshrdv_v8di_mask,
+ __builtin_ia32_vpshrdv_v8di_maskz, __builtin_ia32_vpshrdv_v4di_mask,
+ __builtin_ia32_vpshrdv_v4di_maskz, __builtin_ia32_vpshrdv_v2di_mask,
+ __builtin_ia32_vpshrdv_v2di_maskz, __builtin_ia32_vpshldv_v32hi_mask,
+ __builtin_ia32_vpshldv_v32hi_maskz, __builtin_ia32_vpshldv_v16hi_mask,
+ __builtin_ia32_vpshldv_v16hi_maskz, __builtin_ia32_vpshldv_v8hi_mask,
+ __builtin_ia32_vpshldv_v8hi_maskz, __builtin_ia32_vpshldv_v16si_mask,
+ __builtin_ia32_vpshldv_v16si_maskz, __builtin_ia32_vpshldv_v8si_mask,
+ __builtin_ia32_vpshldv_v8si_maskz, __builtin_ia32_vpshldv_v4si_mask,
+ __builtin_ia32_vpshldv_v4si_maskz, __builtin_ia32_vpshldv_v8di_mask,
+ __builtin_ia32_vpshldv_v8di_maskz, __builtin_ia32_vpshldv_v4di_mask,
+ __builtin_ia32_vpshldv_v4di_maskz, __builtin_ia32_vpshldv_v2di_mask,
+ __builtin_ia32_vpshldv_v2di_maskz, __builtin_ia32_vpdpbusd_v16si_mask,
+ __builtin_ia32_vpdpbusd_v16si_maskz, __builtin_ia32_vpdpbusd_v8si_mask,
+ __builtin_ia32_vpdpbusd_v8si_maskz, __builtin_ia32_vpdpbusd_v4si_mask,
+ __builtin_ia32_vpdpbusd_v4si_maskz,
+ __builtin_ia32_vpdpbusds_v16si_mask,
+ __builtin_ia32_vpdpbusds_v16si_maskz,
+ __builtin_ia32_vpdpbusds_v8si_mask,
+ __builtin_ia32_vpdpbusds_v8si_maskz,
+ __builtin_ia32_vpdpbusds_v4si_mask,
+ __builtin_ia32_vpdpbusds_v4si_maskz,
+ __builtin_ia32_vpdpwssd_v16si_mask,
+ __builtin_ia32_vpdpwssd_v16si_maskz, __builtin_ia32_vpdpwssd_v8si_mask,
+ __builtin_ia32_vpdpwssd_v8si_maskz, __builtin_ia32_vpdpwssd_v4si_mask,
+ __builtin_ia32_vpdpwssd_v4si_maskz,
+ __builtin_ia32_vpdpwssds_v16si_mask,
+ __builtin_ia32_vpdpwssds_v16si_maskz,
+ __builtin_ia32_vpdpwssds_v8si_mask,
+ __builtin_ia32_vpdpwssds_v8si_maskz,
+ __builtin_ia32_vpdpwssds_v4si_mask,
+ __builtin_ia32_vpdpwssds_v4si_maskz): Use *_USI, *_UHI or *_UQI
+ suffixed types rather than *_INT.
+ * config/i386/i386-expand.c (ix86_expand_args_builtin): Don't handle
+ V32HI_FTYPE_V32HI_V32HI_V32HI_INT, V16HI_FTYPE_V16HI_V16HI_V16HI_INT,
+ V8HI_FTYPE_V8HI_V8HI_V8HI_INT, V8SI_FTYPE_V8SI_V8SI_V8SI_INT,
+ V4DI_FTYPE_V4DI_V4DI_V4DI_INT, V8DI_FTYPE_V8DI_V8DI_V8DI_INT,
+ V16SI_FTYPE_V16SI_V16SI_V16SI_INT, V2DI_FTYPE_V2DI_V2DI_V2DI_INT
+ and V4SI_FTYPE_V4SI_V4SI_V4SI_INT.
+
+2019-07-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.c (intersect_ranges): If we know the intersection is
+ empty, there is no need to conservatively add anything else to
+ the set.
+
+2019-07-11 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91131
+ * gimplify.c (gimplify_compound_literal_expr): Force a temporary
+ when the object is volatile and we have not cleared it even though
+ there are no nonzero elements.
+
+2019-07-10 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/predicates.md (cint34_operand): Update
+ SIGNED_34BIT_OFFSET_P call.
+ (pcrel_address): Update SIGNED_34BIT_OFFSET_P call.
+ (pcrel_external_address): Update SIGNED_34BIT_OFFSET_P call.
+ * config/rs6000/rs6000.c (rs6000_prefixed_address): Update
+ SIGNED_16BIT_OFFSET_P and SIGNED_34BIT_OFFSET_P calls.
+ * config/rs6000/rs6000.h (SIGNED_16BIT_OFFSET_P): Remove EXTRA
+ argument.
+ (SIGNED_34BIT_OFFSET_P): Remove EXTRA argument.
+ (SIGNED_16BIT_OFFSET_EXTRA_P): New macro, like
+ SIGNED_16BIT_OFFSET_P with an EXTRA argument.
+ (SIGNED_34BIT_OFFSET_EXTRA_P): New macro, like
+ SIGNED_34BIT_OFFSET_P with an EXTRA argument.
+
+2019-07-10 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/rs6000/darwin.h (LIB_SPEC): Collate this spec here.
+ * config/rs6000/darwin7.h (LIB_SPEC): Remove.
+ * config/rs6000/darwin8.h (LIB_SPEC): Remove.
+ (DEF_MIN_OSX_VERSION): New.
+
+2019-07-10 Richard Sandiford <richard.sandiford@arm.com>
+
+ * fold-const.c (fold_relational_const): Fix folding of
+ vector-to-scalar NE_EXPRs.
+ (test_vector_folding): Add more tests.
+
+2019-07-10 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/91060
+ * config/arm/iterators.md (V2DI_ONLY): New mode iterator.
+ * config/arm/neon.md (vec_set<mode>_internal): Add a '@' prefix.
+ (vec_setv2di_internal): Reexpress as...
+ (@vec_set<V2DI_ONLY:mode>_internal): ...this.
+ * config/arm/arm.c (neon_expand_vector_init): Use gen_vec_set_internal
+ rather than gen_neon_vset_lane<mode>.
+
+2019-07-10 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/91102
+ * lra-constraints.c (process_alt_operands): Don't match user
+ defined regs only if they are early clobbers.
+
+2019-07-10 Marc Glisse <marc.glisse@inria.fr>
+
+ * wide-int.h (wi::lshift): Reject negative values for the fast path.
+
+2019-07-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91126
+ * tree-ssa-sccvn.c (n_walk_cb_data::push_partial_def): Adjust
+ native encoding offset for BYTES_BIG_ENDIAN.
+ (vn_reference_lookup_3): Likewise.
+
+2019-07-10 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Look at valueized
+ LHS whenever possible.
+
+2019-07-09 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-ssa-alias.c (nonoverlapping_component_refs_p_1): Break out
+ from ...; work also on duplicated types.
+ (nonoverlapping_component_refs_since_match): ... here
+ (ncr_type_uid): Break out from ...
+ (ncr_compar): ... here; look for TYPE_UID of canonical type if
+ available.
+ (nonoverlapping_component_refs_p): Use same_type_for_tbaa to match
+ the types and nonoverlapping_component_refs_p_1 to disambiguate.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/90989
+ * tree-ssa-strlen.c (handle_char_store): Constrain a single character
+ optimization to just single character stores.
+
+2019-07-09 Joern Rennecke <joern.rennecke@riscy-ip.com>
+
+ * tree-vect-stmts.c (vectorizable_comparison) <!slp_node>:
+ Swap operands only once.
+
+2019-07-09 Dragan Mladjenovic <dmladjenovic@wavecomp.com>
+
+ * cfgcleanup.c (old_insns_match_p): Check if used hard regs set is equal
+ for both call instructions.
+
+2019-07-09 John Darrington <john@darrington.wattle.id.au>
+
+ * simplify-rtx.c (simplify_unary_operation_1): Use GET_MODE_PRECISION
+ rather than GET_MODE_BITSIZE to better handle partial integer modes.
+
+2019-07-09 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/rs6000-internal.h (create_TOC_reference): Delete.
+ * config/rs6000/rs6000-logue.c (create_TOC_reference): Move
+ function from rs6000-logue.c back to rs6000.c.
+ * config/rs6000/rs6000.c (create_TOC_reference): Likewise.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * auto-profile.c: Change class-key of PODs to struct and others
+ to class.
+ * basic-block.h: Same.
+ * bitmap.c (bitmap_alloc): Same.
+ * bitmap.h: Same.
+ * builtins.c (expand_builtin_prefetch): Same.
+ (expand_builtin_interclass_mathfn): Same.
+ (expand_builtin_strlen): Same.
+ (expand_builtin_mempcpy_args): Same.
+ (expand_cmpstr): Same.
+ (expand_builtin___clear_cache): Same.
+ (expand_ifn_atomic_bit_test_and): Same.
+ (expand_builtin_thread_pointer): Same.
+ (expand_builtin_set_thread_pointer): Same.
+ * caller-save.c (setup_save_areas): Same.
+ (replace_reg_with_saved_mem): Same.
+ (insert_restore): Same.
+ (insert_save): Same.
+ (add_used_regs): Same.
+ * cfg.c (get_bb_copy): Same.
+ (set_loop_copy): Same.
+ * cfg.h: Same.
+ * cfganal.h: Same.
+ * cfgexpand.c (alloc_stack_frame_space): Same.
+ (add_stack_var): Same.
+ (add_stack_var_conflict): Same.
+ (add_scope_conflicts_1): Same.
+ (update_alias_info_with_stack_vars): Same.
+ (expand_used_vars): Same.
+ * cfghooks.c (redirect_edge_and_branch_force): Same.
+ (delete_basic_block): Same.
+ (split_edge): Same.
+ (make_forwarder_block): Same.
+ (force_nonfallthru): Same.
+ (duplicate_block): Same.
+ (lv_flush_pending_stmts): Same.
+ * cfghooks.h: Same.
+ * cfgloop.c (flow_loops_cfg_dump): Same.
+ (flow_loop_nested_p): Same.
+ (superloop_at_depth): Same.
+ (get_loop_latch_edges): Same.
+ (flow_loop_dump): Same.
+ (flow_loops_dump): Same.
+ (flow_loops_free): Same.
+ (flow_loop_nodes_find): Same.
+ (establish_preds): Same.
+ (flow_loop_tree_node_add): Same.
+ (flow_loop_tree_node_remove): Same.
+ (flow_loops_find): Same.
+ (find_subloop_latch_edge_by_profile): Same.
+ (find_subloop_latch_edge_by_ivs): Same.
+ (mfb_redirect_edges_in_set): Same.
+ (form_subloop): Same.
+ (merge_latch_edges): Same.
+ (disambiguate_multiple_latches): Same.
+ (disambiguate_loops_with_multiple_latches): Same.
+ (flow_bb_inside_loop_p): Same.
+ (glb_enum_p): Same.
+ (get_loop_body_with_size): Same.
+ (get_loop_body): Same.
+ (fill_sons_in_loop): Same.
+ (get_loop_body_in_dom_order): Same.
+ (get_loop_body_in_custom_order): Same.
+ (release_recorded_exits): Same.
+ (get_loop_exit_edges): Same.
+ (num_loop_branches): Same.
+ (remove_bb_from_loops): Same.
+ (find_common_loop): Same.
+ (delete_loop): Same.
+ (cancel_loop): Same.
+ (verify_loop_structure): Same.
+ (loop_preheader_edge): Same.
+ (loop_exit_edge_p): Same.
+ (single_exit): Same.
+ (loop_exits_to_bb_p): Same.
+ (loop_exits_from_bb_p): Same.
+ (get_loop_location): Same.
+ (record_niter_bound): Same.
+ (get_estimated_loop_iterations_int): Same.
+ (max_stmt_executions_int): Same.
+ (likely_max_stmt_executions_int): Same.
+ (get_estimated_loop_iterations): Same.
+ (get_max_loop_iterations): Same.
+ (get_max_loop_iterations_int): Same.
+ (get_likely_max_loop_iterations): Same.
+ * cfgloop.h (simple_loop_desc): Same.
+ (get_loop): Same.
+ (loop_depth): Same.
+ (loop_outer): Same.
+ (loop_iterator::next): Same.
+ (loop_outermost): Same.
+ * cfgloopanal.c (mark_irreducible_loops): Same.
+ (num_loop_insns): Same.
+ (average_num_loop_insns): Same.
+ (expected_loop_iterations_unbounded): Same.
+ (expected_loop_iterations): Same.
+ (mark_loop_exit_edges): Same.
+ (single_likely_exit): Same.
+ * cfgloopmanip.c (fix_bb_placement): Same.
+ (fix_bb_placements): Same.
+ (remove_path): Same.
+ (place_new_loop): Same.
+ (add_loop): Same.
+ (scale_loop_frequencies): Same.
+ (scale_loop_profile): Same.
+ (create_empty_if_region_on_edge): Same.
+ (create_empty_loop_on_edge): Same.
+ (loopify): Same.
+ (unloop): Same.
+ (fix_loop_placements): Same.
+ (copy_loop_info): Same.
+ (duplicate_loop): Same.
+ (duplicate_subloops): Same.
+ (loop_redirect_edge): Same.
+ (can_duplicate_loop_p): Same.
+ (duplicate_loop_to_header_edge): Same.
+ (mfb_keep_just): Same.
+ (has_preds_from_loop): Same.
+ (create_preheader): Same.
+ (create_preheaders): Same.
+ (lv_adjust_loop_entry_edge): Same.
+ (loop_version): Same.
+ * cfgloopmanip.h: Same.
+ * cgraph.h: Same.
+ * cgraphbuild.c: Same.
+ * combine.c (make_extraction): Same.
+ * config/i386/i386-features.c: Same.
+ * config/i386/i386-features.h: Same.
+ * config/i386/i386.c (ix86_emit_outlined_ms2sysv_save): Same.
+ (ix86_emit_outlined_ms2sysv_restore): Same.
+ (ix86_noce_conversion_profitable_p): Same.
+ (ix86_init_cost): Same.
+ (ix86_simd_clone_usable): Same.
+ * configure.ac (ACX_PROG_CXX_WARNING_OPTS): Add -Wclass-is-pod and
+ Wstruct-not-pod.
+ * coretypes.h: Same.
+ * data-streamer-in.c (string_for_index): Change class-key of PODs
+ to struct and others to class.
+ (streamer_read_indexed_string): Same.
+ (streamer_read_string): Same.
+ (bp_unpack_indexed_string): Same.
+ (bp_unpack_string): Same.
+ (streamer_read_uhwi): Same.
+ (streamer_read_hwi): Same.
+ (streamer_read_gcov_count): Same.
+ (streamer_read_wide_int): Same.
+ * data-streamer.h (streamer_write_bitpack): Same.
+ (bp_unpack_value): Same.
+ (streamer_write_char_stream): Same.
+ (streamer_write_hwi_in_range): Same.
+ (streamer_write_record_start): Same.
+ * ddg.c (create_ddg_dep_from_intra_loop_link): Same.
+ (add_cross_iteration_register_deps): Same.
+ (build_intra_loop_deps): Same.
+ * df-core.c (df_analyze): Same.
+ (loop_post_order_compute): Same.
+ (loop_inverted_post_order_compute): Same.
+ * df-problems.c (df_rd_alloc): Same.
+ (df_rd_simulate_one_insn): Same.
+ (df_rd_local_compute): Same.
+ (df_rd_init_solution): Same.
+ (df_rd_confluence_n): Same.
+ (df_rd_transfer_function): Same.
+ (df_rd_free): Same.
+ (df_rd_dump_defs_set): Same.
+ (df_rd_top_dump): Same.
+ (df_lr_alloc): Same.
+ (df_lr_reset): Same.
+ (df_lr_local_compute): Same.
+ (df_lr_init): Same.
+ (df_lr_confluence_n): Same.
+ (df_lr_free): Same.
+ (df_lr_top_dump): Same.
+ (df_lr_verify_transfer_functions): Same.
+ (df_live_alloc): Same.
+ (df_live_reset): Same.
+ (df_live_init): Same.
+ (df_live_confluence_n): Same.
+ (df_live_finalize): Same.
+ (df_live_free): Same.
+ (df_live_top_dump): Same.
+ (df_live_verify_transfer_functions): Same.
+ (df_mir_alloc): Same.
+ (df_mir_reset): Same.
+ (df_mir_init): Same.
+ (df_mir_confluence_n): Same.
+ (df_mir_free): Same.
+ (df_mir_top_dump): Same.
+ (df_word_lr_alloc): Same.
+ (df_word_lr_reset): Same.
+ (df_word_lr_init): Same.
+ (df_word_lr_confluence_n): Same.
+ (df_word_lr_free): Same.
+ (df_word_lr_top_dump): Same.
+ (df_md_alloc): Same.
+ (df_md_simulate_one_insn): Same.
+ (df_md_reset): Same.
+ (df_md_init): Same.
+ (df_md_free): Same.
+ (df_md_top_dump): Same.
+ * df-scan.c (df_insn_delete): Same.
+ (df_insn_rescan): Same.
+ (df_notes_rescan): Same.
+ (df_sort_and_compress_mws): Same.
+ (df_install_mws): Same.
+ (df_refs_add_to_chains): Same.
+ (df_ref_create_structure): Same.
+ (df_ref_record): Same.
+ (df_def_record_1): Same.
+ (df_find_hard_reg_defs): Same.
+ (df_uses_record): Same.
+ (df_get_conditional_uses): Same.
+ (df_get_call_refs): Same.
+ (df_recompute_luids): Same.
+ (df_get_entry_block_def_set): Same.
+ (df_entry_block_defs_collect): Same.
+ (df_get_exit_block_use_set): Same.
+ (df_exit_block_uses_collect): Same.
+ (df_mws_verify): Same.
+ (df_bb_verify): Same.
+ * df.h (df_scan_get_bb_info): Same.
+ * doc/tm.texi: Same.
+ * dse.c (record_store): Same.
+ * dumpfile.h: Same.
+ * emit-rtl.c (const_fixed_hasher::equal): Same.
+ (set_mem_attributes_minus_bitpos): Same.
+ (change_address): Same.
+ (adjust_address_1): Same.
+ (offset_address): Same.
+ * emit-rtl.h: Same.
+ * except.c (dw2_build_landing_pads): Same.
+ (sjlj_emit_dispatch_table): Same.
+ * explow.c (allocate_dynamic_stack_space): Same.
+ (emit_stack_probe): Same.
+ (probe_stack_range): Same.
+ * expmed.c (store_bit_field_using_insv): Same.
+ (store_bit_field_1): Same.
+ (store_integral_bit_field): Same.
+ (extract_bit_field_using_extv): Same.
+ (extract_bit_field_1): Same.
+ (emit_cstore): Same.
+ * expr.c (emit_block_move_via_cpymem): Same.
+ (expand_cmpstrn_or_cmpmem): Same.
+ (set_storage_via_setmem): Same.
+ (emit_single_push_insn_1): Same.
+ (expand_assignment): Same.
+ (store_constructor): Same.
+ (expand_expr_real_2): Same.
+ (expand_expr_real_1): Same.
+ (try_casesi): Same.
+ * flags.h: Same.
+ * function.c (try_fit_stack_local): Same.
+ (assign_stack_local_1): Same.
+ (assign_stack_local): Same.
+ (cut_slot_from_list): Same.
+ (insert_slot_to_list): Same.
+ (max_slot_level): Same.
+ (move_slot_to_level): Same.
+ (temp_address_hasher::equal): Same.
+ (remove_unused_temp_slot_addresses): Same.
+ (assign_temp): Same.
+ (combine_temp_slots): Same.
+ (update_temp_slot_address): Same.
+ (preserve_temp_slots): Same.
+ * function.h: Same.
+ * fwprop.c: Same.
+ * gcc-rich-location.h: Same.
+ * gcov.c: Same.
+ * genattrtab.c (check_attr_test): Same.
+ (check_attr_value): Same.
+ (convert_set_attr_alternative): Same.
+ (convert_set_attr): Same.
+ (check_defs): Same.
+ (copy_boolean): Same.
+ (get_attr_value): Same.
+ (expand_delays): Same.
+ (make_length_attrs): Same.
+ (min_fn): Same.
+ (make_alternative_compare): Same.
+ (simplify_test_exp): Same.
+ (tests_attr_p): Same.
+ (get_attr_order): Same.
+ (clear_struct_flag): Same.
+ (gen_attr): Same.
+ (compares_alternatives_p): Same.
+ (gen_insn): Same.
+ (gen_delay): Same.
+ (find_attrs_to_cache): Same.
+ (write_test_expr): Same.
+ (walk_attr_value): Same.
+ (write_attr_get): Same.
+ (eliminate_known_true): Same.
+ (write_insn_cases): Same.
+ (write_attr_case): Same.
+ (write_attr_valueq): Same.
+ (write_attr_value): Same.
+ (write_dummy_eligible_delay): Same.
+ (next_comma_elt): Same.
+ (find_attr): Same.
+ (make_internal_attr): Same.
+ (copy_rtx_unchanging): Same.
+ (gen_insn_reserv): Same.
+ (check_tune_attr): Same.
+ (make_automaton_attrs): Same.
+ (handle_arg): Same.
+ * genextract.c (gen_insn): Same.
+ (VEC_char_to_string): Same.
+ * genmatch.c (print_operand): Same.
+ (lower): Same.
+ (parser::parse_operation): Same.
+ (parser::parse_capture): Same.
+ (parser::parse_c_expr): Same.
+ (parser::parse_simplify): Same.
+ (main): Same.
+ * genoutput.c (output_operand_data): Same.
+ (output_get_insn_name): Same.
+ (compare_operands): Same.
+ (place_operands): Same.
+ (process_template): Same.
+ (validate_insn_alternatives): Same.
+ (validate_insn_operands): Same.
+ (gen_expand): Same.
+ (note_constraint): Same.
+ * genpreds.c (write_one_predicate_function): Same.
+ (add_constraint): Same.
+ (process_define_register_constraint): Same.
+ (write_lookup_constraint_1): Same.
+ (write_lookup_constraint_array): Same.
+ (write_insn_constraint_len): Same.
+ (write_reg_class_for_constraint_1): Same.
+ (write_constraint_satisfied_p_array): Same.
+ * genrecog.c (optimize_subroutine_group): Same.
+ * gensupport.c (process_define_predicate): Same.
+ (queue_pattern): Same.
+ (remove_from_queue): Same.
+ (process_rtx): Same.
+ (is_predicable): Same.
+ (change_subst_attribute): Same.
+ (subst_pattern_match): Same.
+ (alter_constraints): Same.
+ (alter_attrs_for_insn): Same.
+ (shift_output_template): Same.
+ (alter_output_for_subst_insn): Same.
+ (process_one_cond_exec): Same.
+ (subst_dup): Same.
+ (process_define_cond_exec): Same.
+ (mnemonic_htab_callback): Same.
+ (gen_mnemonic_attr): Same.
+ (read_md_rtx): Same.
+ * ggc-page.c: Same.
+ * gimple-loop-interchange.cc (dump_reduction): Same.
+ (dump_induction): Same.
+ (loop_cand::~loop_cand): Same.
+ (free_data_refs_with_aux): Same.
+ (tree_loop_interchange::interchange_loops): Same.
+ (tree_loop_interchange::map_inductions_to_loop): Same.
+ (tree_loop_interchange::move_code_to_inner_loop): Same.
+ (compute_access_stride): Same.
+ (compute_access_strides): Same.
+ (proper_loop_form_for_interchange): Same.
+ (tree_loop_interchange_compute_ddrs): Same.
+ (prune_datarefs_not_in_loop): Same.
+ (prepare_data_references): Same.
+ (pass_linterchange::execute): Same.
+ * gimple-loop-jam.c (bb_prevents_fusion_p): Same.
+ (unroll_jam_possible_p): Same.
+ (fuse_loops): Same.
+ (adjust_unroll_factor): Same.
+ (tree_loop_unroll_and_jam): Same.
+ * gimple-loop-versioning.cc (loop_versioning::~loop_versioning): Same.
+ (loop_versioning::expensive_stmt_p): Same.
+ (loop_versioning::version_for_unity): Same.
+ (loop_versioning::dump_inner_likelihood): Same.
+ (loop_versioning::find_per_loop_multiplication): Same.
+ (loop_versioning::analyze_term_using_scevs): Same.
+ (loop_versioning::record_address_fragment): Same.
+ (loop_versioning::analyze_expr): Same.
+ (loop_versioning::analyze_blocks): Same.
+ (loop_versioning::prune_conditions): Same.
+ (loop_versioning::merge_loop_info): Same.
+ (loop_versioning::add_loop_to_queue): Same.
+ (loop_versioning::decide_whether_loop_is_versionable): Same.
+ (loop_versioning::make_versioning_decisions): Same.
+ (loop_versioning::implement_versioning_decisions): Same.
+ * gimple-ssa-evrp-analyze.c
+ (evrp_range_analyzer::record_ranges_from_phis): Same.
+ * gimple-ssa-store-merging.c (split_store::split_store): Same.
+ (count_multiple_uses): Same.
+ (split_group): Same.
+ (imm_store_chain_info::output_merged_store): Same.
+ (pass_store_merging::process_store): Same.
+ * gimple-ssa-strength-reduction.c (slsr_process_phi): Same.
+ * gimple-ssa-warn-alloca.c (adjusted_warn_limit): Same.
+ (is_max): Same.
+ (alloca_call_type): Same.
+ (pass_walloca::execute): Same.
+ * gimple-streamer-in.c (input_phi): Same.
+ (input_gimple_stmt): Same.
+ * gimple-streamer.h: Same.
+ * godump.c (go_force_record_alignment): Same.
+ (go_format_type): Same.
+ (go_output_type): Same.
+ (go_output_fndecl): Same.
+ (go_output_typedef): Same.
+ (keyword_hash_init): Same.
+ (find_dummy_types): Same.
+ * graph.c (draw_cfg_nodes_no_loops): Same.
+ (draw_cfg_nodes_for_loop): Same.
+ * hard-reg-set.h (hard_reg_set_iter_next): Same.
+ * hsa-brig.c: Same.
+ * hsa-common.h (hsa_internal_fn_hasher::equal): Same.
+ * hsa-dump.c (dump_hsa_cfun): Same.
+ * hsa-gen.c (gen_function_def_parameters): Same.
+ * hsa-regalloc.c (dump_hsa_cfun_regalloc): Same.
+ * input.c (dump_line_table_statistics): Same.
+ (test_lexer): Same.
+ * input.h: Same.
+ * internal-fn.c (get_multi_vector_move): Same.
+ (expand_load_lanes_optab_fn): Same.
+ (expand_GOMP_SIMT_ENTER_ALLOC): Same.
+ (expand_GOMP_SIMT_EXIT): Same.
+ (expand_GOMP_SIMT_LAST_LANE): Same.
+ (expand_GOMP_SIMT_ORDERED_PRED): Same.
+ (expand_GOMP_SIMT_VOTE_ANY): Same.
+ (expand_GOMP_SIMT_XCHG_BFLY): Same.
+ (expand_GOMP_SIMT_XCHG_IDX): Same.
+ (expand_addsub_overflow): Same.
+ (expand_neg_overflow): Same.
+ (expand_mul_overflow): Same.
+ (expand_call_mem_ref): Same.
+ (expand_mask_load_optab_fn): Same.
+ (expand_scatter_store_optab_fn): Same.
+ (expand_gather_load_optab_fn): Same.
+ * ipa-cp.c (ipa_get_parm_lattices): Same.
+ (print_all_lattices): Same.
+ (ignore_edge_p): Same.
+ (build_toporder_info): Same.
+ (free_toporder_info): Same.
+ (push_node_to_stack): Same.
+ (ipcp_lattice<valtype>::set_contains_variable): Same.
+ (set_agg_lats_to_bottom): Same.
+ (ipcp_bits_lattice::meet_with): Same.
+ (set_single_call_flag): Same.
+ (initialize_node_lattices): Same.
+ (ipa_get_jf_ancestor_result): Same.
+ (ipcp_verify_propagated_values): Same.
+ (propagate_scalar_across_jump_function): Same.
+ (propagate_context_across_jump_function): Same.
+ (propagate_bits_across_jump_function): Same.
+ (ipa_vr_operation_and_type_effects): Same.
+ (propagate_vr_across_jump_function): Same.
+ (set_check_aggs_by_ref): Same.
+ (set_chain_of_aglats_contains_variable): Same.
+ (merge_aggregate_lattices): Same.
+ (agg_pass_through_permissible_p): Same.
+ (propagate_aggs_across_jump_function): Same.
+ (call_passes_through_thunk_p): Same.
+ (propagate_constants_across_call): Same.
+ (devirtualization_time_bonus): Same.
+ (good_cloning_opportunity_p): Same.
+ (context_independent_aggregate_values): Same.
+ (gather_context_independent_values): Same.
+ (perform_estimation_of_a_value): Same.
+ (estimate_local_effects): Same.
+ (value_topo_info<valtype>::add_val): Same.
+ (add_all_node_vals_to_toposort): Same.
+ (value_topo_info<valtype>::propagate_effects): Same.
+ (ipcp_propagate_stage): Same.
+ (ipcp_discover_new_direct_edges): Same.
+ (same_node_or_its_all_contexts_clone_p): Same.
+ (cgraph_edge_brings_value_p): Same.
+ (gather_edges_for_value): Same.
+ (create_specialized_node): Same.
+ (find_more_scalar_values_for_callers_subset): Same.
+ (find_more_contexts_for_caller_subset): Same.
+ (copy_plats_to_inter): Same.
+ (intersect_aggregates_with_edge): Same.
+ (find_aggregate_values_for_callers_subset): Same.
+ (cgraph_edge_brings_all_agg_vals_for_node): Same.
+ (decide_about_value): Same.
+ (decide_whether_version_node): Same.
+ (spread_undeadness): Same.
+ (identify_dead_nodes): Same.
+ (ipcp_store_vr_results): Same.
+ * ipa-devirt.c (final_warning_record::grow_type_warnings): Same.
+ * ipa-fnsummary.c (ipa_fn_summary::account_size_time): Same.
+ (redirect_to_unreachable): Same.
+ (edge_set_predicate): Same.
+ (evaluate_conditions_for_known_args): Same.
+ (evaluate_properties_for_edge): Same.
+ (ipa_fn_summary_t::duplicate): Same.
+ (ipa_call_summary_t::duplicate): Same.
+ (dump_ipa_call_summary): Same.
+ (ipa_dump_fn_summary): Same.
+ (eliminated_by_inlining_prob): Same.
+ (set_cond_stmt_execution_predicate): Same.
+ (set_switch_stmt_execution_predicate): Same.
+ (compute_bb_predicates): Same.
+ (will_be_nonconstant_expr_predicate): Same.
+ (phi_result_unknown_predicate): Same.
+ (analyze_function_body): Same.
+ (compute_fn_summary): Same.
+ (estimate_edge_devirt_benefit): Same.
+ (estimate_edge_size_and_time): Same.
+ (estimate_calls_size_and_time): Same.
+ (estimate_node_size_and_time): Same.
+ (remap_edge_change_prob): Same.
+ (remap_edge_summaries): Same.
+ (ipa_merge_fn_summary_after_inlining): Same.
+ (ipa_fn_summary_generate): Same.
+ (inline_read_section): Same.
+ (ipa_fn_summary_read): Same.
+ (ipa_fn_summary_write): Same.
+ * ipa-fnsummary.h: Same.
+ * ipa-hsa.c (ipa_hsa_read_section): Same.
+ * ipa-icf-gimple.c (func_checker::compare_loops): Same.
+ * ipa-icf.c (sem_function::param_used_p): Same.
+ * ipa-inline-analysis.c (do_estimate_edge_time): Same.
+ * ipa-inline.c (edge_badness): Same.
+ (inline_small_functions): Same.
+ * ipa-polymorphic-call.c
+ (ipa_polymorphic_call_context::stream_out): Same.
+ * ipa-predicate.c (predicate::remap_after_duplication): Same.
+ (predicate::remap_after_inlining): Same.
+ (predicate::stream_out): Same.
+ * ipa-predicate.h: Same.
+ * ipa-profile.c (ipa_profile_read_summary): Same.
+ * ipa-prop.c (ipa_get_param_decl_index_1): Same.
+ (count_formal_params): Same.
+ (ipa_dump_param): Same.
+ (ipa_alloc_node_params): Same.
+ (ipa_print_node_jump_functions_for_edge): Same.
+ (ipa_print_node_jump_functions): Same.
+ (ipa_load_from_parm_agg): Same.
+ (get_ancestor_addr_info): Same.
+ (ipa_compute_jump_functions_for_edge): Same.
+ (ipa_analyze_virtual_call_uses): Same.
+ (ipa_analyze_stmt_uses): Same.
+ (ipa_analyze_params_uses_in_bb): Same.
+ (update_jump_functions_after_inlining): Same.
+ (try_decrement_rdesc_refcount): Same.
+ (ipa_impossible_devirt_target): Same.
+ (update_indirect_edges_after_inlining): Same.
+ (combine_controlled_uses_counters): Same.
+ (ipa_edge_args_sum_t::duplicate): Same.
+ (ipa_write_jump_function): Same.
+ (ipa_write_indirect_edge_info): Same.
+ (ipa_write_node_info): Same.
+ (ipa_read_edge_info): Same.
+ (ipa_prop_read_section): Same.
+ (read_replacements_section): Same.
+ * ipa-prop.h (ipa_get_param_count): Same.
+ (ipa_get_param): Same.
+ (ipa_get_type): Same.
+ (ipa_get_param_move_cost): Same.
+ (ipa_set_param_used): Same.
+ (ipa_get_controlled_uses): Same.
+ (ipa_set_controlled_uses): Same.
+ (ipa_get_cs_argument_count): Same.
+ * ipa-pure-const.c (analyze_function): Same.
+ (pure_const_read_summary): Same.
+ * ipa-ref.h: Same.
+ * ipa-reference.c (ipa_reference_read_optimization_summary): Same.
+ * ipa-split.c (test_nonssa_use): Same.
+ (dump_split_point): Same.
+ (dominated_by_forbidden): Same.
+ (split_part_set_ssa_name_p): Same.
+ (find_split_points): Same.
+ * ira-build.c (finish_loop_tree_nodes): Same.
+ (low_pressure_loop_node_p): Same.
+ * ira-color.c (ira_reuse_stack_slot): Same.
+ * ira-int.h: Same.
+ * ira.c (setup_reg_equiv): Same.
+ (print_insn_chain): Same.
+ (ira): Same.
+ * loop-doloop.c (doloop_condition_get): Same.
+ (add_test): Same.
+ (record_reg_sets): Same.
+ (doloop_optimize): Same.
+ * loop-init.c (loop_optimizer_init): Same.
+ (fix_loop_structure): Same.
+ * loop-invariant.c (merge_identical_invariants): Same.
+ (compute_always_reached): Same.
+ (find_exits): Same.
+ (may_assign_reg_p): Same.
+ (find_invariants_bb): Same.
+ (find_invariants_body): Same.
+ (replace_uses): Same.
+ (can_move_invariant_reg): Same.
+ (free_inv_motion_data): Same.
+ (move_single_loop_invariants): Same.
+ (change_pressure): Same.
+ (mark_ref_regs): Same.
+ (calculate_loop_reg_pressure): Same.
+ * loop-iv.c (biv_entry_hasher::equal): Same.
+ (iv_extend_to_rtx_code): Same.
+ (check_iv_ref_table_size): Same.
+ (clear_iv_info): Same.
+ (latch_dominating_def): Same.
+ (iv_get_reaching_def): Same.
+ (iv_constant): Same.
+ (iv_subreg): Same.
+ (iv_extend): Same.
+ (iv_neg): Same.
+ (iv_add): Same.
+ (iv_mult): Same.
+ (get_biv_step): Same.
+ (record_iv): Same.
+ (analyzed_for_bivness_p): Same.
+ (record_biv): Same.
+ (iv_analyze_biv): Same.
+ (iv_analyze_expr): Same.
+ (iv_analyze_def): Same.
+ (iv_analyze_op): Same.
+ (iv_analyze): Same.
+ (iv_analyze_result): Same.
+ (biv_p): Same.
+ (eliminate_implied_conditions): Same.
+ (simplify_using_initial_values): Same.
+ (shorten_into_mode): Same.
+ (canonicalize_iv_subregs): Same.
+ (determine_max_iter): Same.
+ (check_simple_exit): Same.
+ (find_simple_exit): Same.
+ (get_simple_loop_desc): Same.
+ * loop-unroll.c (report_unroll): Same.
+ (decide_unrolling): Same.
+ (unroll_loops): Same.
+ (loop_exit_at_end_p): Same.
+ (decide_unroll_constant_iterations): Same.
+ (unroll_loop_constant_iterations): Same.
+ (compare_and_jump_seq): Same.
+ (unroll_loop_runtime_iterations): Same.
+ (decide_unroll_stupid): Same.
+ (unroll_loop_stupid): Same.
+ (referenced_in_one_insn_in_loop_p): Same.
+ (reset_debug_uses_in_loop): Same.
+ (analyze_iv_to_split_insn): Same.
+ * lra-eliminations.c (lra_debug_elim_table): Same.
+ (setup_can_eliminate): Same.
+ (form_sum): Same.
+ (lra_get_elimination_hard_regno): Same.
+ (lra_eliminate_regs_1): Same.
+ (eliminate_regs_in_insn): Same.
+ (update_reg_eliminate): Same.
+ (init_elimination): Same.
+ (lra_eliminate): Same.
+ * lra-int.h: Same.
+ * lra-lives.c (initiate_live_solver): Same.
+ * lra-remat.c (create_remat_bb_data): Same.
+ * lra-spills.c (lra_spill): Same.
+ * lra.c (lra_set_insn_recog_data): Same.
+ (lra_set_used_insn_alternative_by_uid): Same.
+ (init_reg_info): Same.
+ (expand_reg_info): Same.
+ * lto-cgraph.c (output_symtab): Same.
+ (read_identifier): Same.
+ (get_alias_symbol): Same.
+ (input_node): Same.
+ (input_varpool_node): Same.
+ (input_ref): Same.
+ (input_edge): Same.
+ (input_cgraph_1): Same.
+ (input_refs): Same.
+ (input_symtab): Same.
+ (input_offload_tables): Same.
+ (output_cgraph_opt_summary): Same.
+ (input_edge_opt_summary): Same.
+ (input_cgraph_opt_section): Same.
+ * lto-section-in.c (lto_free_raw_section_data): Same.
+ (lto_create_simple_input_block): Same.
+ (lto_free_function_in_decl_state_for_node): Same.
+ * lto-streamer-in.c (lto_tag_check_set): Same.
+ (lto_location_cache::revert_location_cache): Same.
+ (lto_location_cache::input_location): Same.
+ (lto_input_location): Same.
+ (stream_input_location_now): Same.
+ (lto_input_tree_ref): Same.
+ (lto_input_eh_catch_list): Same.
+ (input_eh_region): Same.
+ (lto_init_eh): Same.
+ (make_new_block): Same.
+ (input_cfg): Same.
+ (fixup_call_stmt_edges): Same.
+ (input_struct_function_base): Same.
+ (input_function): Same.
+ (lto_read_body_or_constructor): Same.
+ (lto_read_tree_1): Same.
+ (lto_read_tree): Same.
+ (lto_input_scc): Same.
+ (lto_input_tree_1): Same.
+ (lto_input_toplevel_asms): Same.
+ (lto_input_mode_table): Same.
+ (lto_reader_init): Same.
+ (lto_data_in_create): Same.
+ * lto-streamer-out.c (output_cfg): Same.
+ * lto-streamer.h: Same.
+ * modulo-sched.c (duplicate_insns_of_cycles): Same.
+ (generate_prolog_epilog): Same.
+ (mark_loop_unsched): Same.
+ (dump_insn_location): Same.
+ (loop_canon_p): Same.
+ (sms_schedule): Same.
+ * omp-expand.c (expand_omp_for_ordered_loops): Same.
+ (expand_omp_for_generic): Same.
+ (expand_omp_for_static_nochunk): Same.
+ (expand_omp_for_static_chunk): Same.
+ (expand_omp_simd): Same.
+ (expand_omp_taskloop_for_inner): Same.
+ (expand_oacc_for): Same.
+ (expand_omp_atomic_pipeline): Same.
+ (mark_loops_in_oacc_kernels_region): Same.
+ * omp-offload.c (oacc_xform_loop): Same.
+ * omp-simd-clone.c (simd_clone_adjust): Same.
+ * optabs-query.c (get_traditional_extraction_insn): Same.
+ * optabs.c (expand_vector_broadcast): Same.
+ (expand_binop_directly): Same.
+ (expand_twoval_unop): Same.
+ (expand_twoval_binop): Same.
+ (expand_unop_direct): Same.
+ (emit_indirect_jump): Same.
+ (emit_conditional_move): Same.
+ (emit_conditional_neg_or_complement): Same.
+ (emit_conditional_add): Same.
+ (vector_compare_rtx): Same.
+ (expand_vec_perm_1): Same.
+ (expand_vec_perm_const): Same.
+ (expand_vec_cond_expr): Same.
+ (expand_vec_series_expr): Same.
+ (maybe_emit_atomic_exchange): Same.
+ (maybe_emit_sync_lock_test_and_set): Same.
+ (expand_atomic_compare_and_swap): Same.
+ (expand_atomic_load): Same.
+ (expand_atomic_store): Same.
+ (maybe_emit_op): Same.
+ (valid_multiword_target_p): Same.
+ (create_integer_operand): Same.
+ (maybe_legitimize_operand_same_code): Same.
+ (maybe_legitimize_operand): Same.
+ (create_convert_operand_from_type): Same.
+ (can_reuse_operands_p): Same.
+ (maybe_legitimize_operands): Same.
+ (maybe_gen_insn): Same.
+ (maybe_expand_insn): Same.
+ (maybe_expand_jump_insn): Same.
+ (expand_insn): Same.
+ * optabs.h (create_expand_operand): Same.
+ (create_fixed_operand): Same.
+ (create_output_operand): Same.
+ (create_input_operand): Same.
+ (create_convert_operand_to): Same.
+ (create_convert_operand_from): Same.
+ * optinfo.h: Same.
+ * poly-int.h: Same.
+ * predict.c (optimize_insn_for_speed_p): Same.
+ (optimize_loop_for_size_p): Same.
+ (optimize_loop_for_speed_p): Same.
+ (optimize_loop_nest_for_speed_p): Same.
+ (get_base_value): Same.
+ (predicted_by_loop_heuristics_p): Same.
+ (predict_extra_loop_exits): Same.
+ (predict_loops): Same.
+ (predict_paths_for_bb): Same.
+ (predict_paths_leading_to): Same.
+ (propagate_freq): Same.
+ (pass_profile::execute): Same.
+ * predict.h: Same.
+ * profile-count.c (profile_count::differs_from_p): Same.
+ (profile_probability::differs_lot_from_p): Same.
+ * profile-count.h: Same.
+ * profile.c (branch_prob): Same.
+ * regrename.c (free_chain_data): Same.
+ (mark_conflict): Same.
+ (create_new_chain): Same.
+ (merge_overlapping_regs): Same.
+ (init_rename_info): Same.
+ (merge_chains): Same.
+ (regrename_analyze): Same.
+ (regrename_do_replace): Same.
+ (scan_rtx_reg): Same.
+ (record_out_operands): Same.
+ (build_def_use): Same.
+ * regrename.h: Same.
+ * reload.h: Same.
+ * reload1.c (init_reload): Same.
+ (maybe_fix_stack_asms): Same.
+ (copy_reloads): Same.
+ (count_pseudo): Same.
+ (count_spilled_pseudo): Same.
+ (find_reg): Same.
+ (find_reload_regs): Same.
+ (select_reload_regs): Same.
+ (spill_hard_reg): Same.
+ (fixup_eh_region_note): Same.
+ (set_reload_reg): Same.
+ (allocate_reload_reg): Same.
+ (compute_reload_subreg_offset): Same.
+ (reload_adjust_reg_for_icode): Same.
+ (emit_input_reload_insns): Same.
+ (emit_output_reload_insns): Same.
+ (do_input_reload): Same.
+ (inherit_piecemeal_p): Same.
+ * rtl.h: Same.
+ * sanopt.c (maybe_get_dominating_check): Same.
+ (maybe_optimize_ubsan_ptr_ifn): Same.
+ (can_remove_asan_check): Same.
+ (maybe_optimize_asan_check_ifn): Same.
+ (sanopt_optimize_walker): Same.
+ * sched-deps.c (add_dependence_list): Same.
+ (chain_to_prev_insn): Same.
+ (add_insn_mem_dependence): Same.
+ (create_insn_reg_set): Same.
+ (maybe_extend_reg_info_p): Same.
+ (sched_analyze_reg): Same.
+ (sched_analyze_1): Same.
+ (get_implicit_reg_pending_clobbers): Same.
+ (chain_to_prev_insn_p): Same.
+ (deps_analyze_insn): Same.
+ (deps_start_bb): Same.
+ (sched_free_deps): Same.
+ (init_deps): Same.
+ (init_deps_reg_last): Same.
+ (free_deps): Same.
+ * sched-ebb.c: Same.
+ * sched-int.h: Same.
+ * sched-rgn.c (add_branch_dependences): Same.
+ (concat_insn_mem_list): Same.
+ (deps_join): Same.
+ (sched_rgn_compute_dependencies): Same.
+ * sel-sched-ir.c (reset_target_context): Same.
+ (copy_deps_context): Same.
+ (init_id_from_df): Same.
+ (has_dependence_p): Same.
+ (change_loops_latches): Same.
+ (bb_top_order_comparator): Same.
+ (make_region_from_loop_preheader): Same.
+ (sel_init_pipelining): Same.
+ (get_loop_nest_for_rgn): Same.
+ (make_regions_from_the_rest): Same.
+ (sel_is_loop_preheader_p): Same.
+ * sel-sched-ir.h (inner_loop_header_p): Same.
+ (get_all_loop_exits): Same.
+ * selftest.h: Same.
+ * sese.c (sese_build_liveouts): Same.
+ (sese_insert_phis_for_liveouts): Same.
+ * sese.h (defined_in_sese_p): Same.
+ * sreal.c (sreal::stream_out): Same.
+ * sreal.h: Same.
+ * streamer-hooks.h: Same.
+ * target-globals.c (save_target_globals): Same.
+ * target-globals.h: Same.
+ * target.def: Same.
+ * target.h: Same.
+ * targhooks.c (default_has_ifunc_p): Same.
+ (default_empty_mask_is_expensive): Same.
+ (default_init_cost): Same.
+ * targhooks.h: Same.
+ * toplev.c: Same.
+ * tree-affine.c (aff_combination_mult): Same.
+ (aff_combination_expand): Same.
+ (aff_combination_constant_multiple_p): Same.
+ * tree-affine.h: Same.
+ * tree-cfg.c (build_gimple_cfg): Same.
+ (replace_loop_annotate_in_block): Same.
+ (replace_uses_by): Same.
+ (remove_bb): Same.
+ (dump_cfg_stats): Same.
+ (gimple_duplicate_sese_region): Same.
+ (gimple_duplicate_sese_tail): Same.
+ (move_block_to_fn): Same.
+ (replace_block_vars_by_duplicates): Same.
+ (move_sese_region_to_fn): Same.
+ (print_loops_bb): Same.
+ (print_loop): Same.
+ (print_loops): Same.
+ (debug): Same.
+ (debug_loops): Same.
+ * tree-cfg.h: Same.
+ * tree-chrec.c (chrec_fold_plus_poly_poly): Same.
+ (chrec_fold_multiply_poly_poly): Same.
+ (chrec_evaluate): Same.
+ (chrec_component_in_loop_num): Same.
+ (reset_evolution_in_loop): Same.
+ (is_multivariate_chrec): Same.
+ (chrec_contains_symbols): Same.
+ (nb_vars_in_chrec): Same.
+ (chrec_convert_1): Same.
+ (chrec_convert_aggressive): Same.
+ * tree-chrec.h: Same.
+ * tree-core.h: Same.
+ * tree-data-ref.c (dump_data_dependence_relation): Same.
+ (canonicalize_base_object_address): Same.
+ (data_ref_compare_tree): Same.
+ (prune_runtime_alias_test_list): Same.
+ (get_segment_min_max): Same.
+ (create_intersect_range_checks): Same.
+ (conflict_fn_no_dependence): Same.
+ (object_address_invariant_in_loop_p): Same.
+ (analyze_ziv_subscript): Same.
+ (analyze_siv_subscript_cst_affine): Same.
+ (analyze_miv_subscript): Same.
+ (analyze_overlapping_iterations): Same.
+ (build_classic_dist_vector_1): Same.
+ (add_other_self_distances): Same.
+ (same_access_functions): Same.
+ (build_classic_dir_vector): Same.
+ (subscript_dependence_tester_1): Same.
+ (subscript_dependence_tester): Same.
+ (access_functions_are_affine_or_constant_p): Same.
+ (get_references_in_stmt): Same.
+ (loop_nest_has_data_refs): Same.
+ (graphite_find_data_references_in_stmt): Same.
+ (find_data_references_in_bb): Same.
+ (get_base_for_alignment): Same.
+ (find_loop_nest_1): Same.
+ (find_loop_nest): Same.
+ * tree-data-ref.h (dr_alignment): Same.
+ (ddr_dependence_level): Same.
+ * tree-if-conv.c (fold_build_cond_expr): Same.
+ (add_to_predicate_list): Same.
+ (add_to_dst_predicate_list): Same.
+ (phi_convertible_by_degenerating_args): Same.
+ (idx_within_array_bound): Same.
+ (all_preds_critical_p): Same.
+ (pred_blocks_visited_p): Same.
+ (predicate_bbs): Same.
+ (build_region): Same.
+ (if_convertible_loop_p_1): Same.
+ (is_cond_scalar_reduction): Same.
+ (predicate_scalar_phi): Same.
+ (remove_conditions_and_labels): Same.
+ (combine_blocks): Same.
+ (version_loop_for_if_conversion): Same.
+ (versionable_outer_loop_p): Same.
+ (ifcvt_local_dce): Same.
+ (tree_if_conversion): Same.
+ (pass_if_conversion::gate): Same.
+ * tree-if-conv.h: Same.
+ * tree-inline.c (maybe_move_debug_stmts_to_successors): Same.
+ * tree-loop-distribution.c (bb_top_order_cmp): Same.
+ (free_rdg): Same.
+ (stmt_has_scalar_dependences_outside_loop): Same.
+ (copy_loop_before): Same.
+ (create_bb_after_loop): Same.
+ (const_with_all_bytes_same): Same.
+ (generate_memset_builtin): Same.
+ (generate_memcpy_builtin): Same.
+ (destroy_loop): Same.
+ (build_rdg_partition_for_vertex): Same.
+ (compute_access_range): Same.
+ (data_ref_segment_size): Same.
+ (latch_dominated_by_data_ref): Same.
+ (compute_alias_check_pairs): Same.
+ (fuse_memset_builtins): Same.
+ (finalize_partitions): Same.
+ (find_seed_stmts_for_distribution): Same.
+ (prepare_perfect_loop_nest): Same.
+ * tree-parloops.c (lambda_transform_legal_p): Same.
+ (loop_parallel_p): Same.
+ (reduc_stmt_res): Same.
+ (add_field_for_name): Same.
+ (create_call_for_reduction_1): Same.
+ (replace_uses_in_bb_by): Same.
+ (transform_to_exit_first_loop_alt): Same.
+ (try_transform_to_exit_first_loop_alt): Same.
+ (transform_to_exit_first_loop): Same.
+ (num_phis): Same.
+ (gen_parallel_loop): Same.
+ (gather_scalar_reductions): Same.
+ (get_omp_data_i_param): Same.
+ (try_create_reduction_list): Same.
+ (oacc_entry_exit_single_gang): Same.
+ (parallelize_loops): Same.
+ * tree-pass.h: Same.
+ * tree-predcom.c (determine_offset): Same.
+ (last_always_executed_block): Same.
+ (split_data_refs_to_components): Same.
+ (suitable_component_p): Same.
+ (valid_initializer_p): Same.
+ (find_looparound_phi): Same.
+ (insert_looparound_copy): Same.
+ (add_looparound_copies): Same.
+ (determine_roots_comp): Same.
+ (predcom_tmp_var): Same.
+ (initialize_root_vars): Same.
+ (initialize_root_vars_store_elim_1): Same.
+ (initialize_root_vars_store_elim_2): Same.
+ (finalize_eliminated_stores): Same.
+ (initialize_root_vars_lm): Same.
+ (remove_stmt): Same.
+ (determine_unroll_factor): Same.
+ (execute_pred_commoning_cbck): Same.
+ (base_names_in_chain_on): Same.
+ (combine_chains): Same.
+ (pcom_stmt_dominates_stmt_p): Same.
+ (try_combine_chains): Same.
+ (prepare_initializers_chain_store_elim): Same.
+ (prepare_initializers_chain): Same.
+ (prepare_initializers): Same.
+ (prepare_finalizers_chain): Same.
+ (prepare_finalizers): Same.
+ (insert_init_seqs): Same.
+ * tree-scalar-evolution.c (loop_phi_node_p): Same.
+ (compute_overall_effect_of_inner_loop): Same.
+ (add_to_evolution_1): Same.
+ (add_to_evolution): Same.
+ (follow_ssa_edge_binary): Same.
+ (follow_ssa_edge_expr): Same.
+ (backedge_phi_arg_p): Same.
+ (follow_ssa_edge_in_condition_phi_branch): Same.
+ (follow_ssa_edge_in_condition_phi): Same.
+ (follow_ssa_edge_inner_loop_phi): Same.
+ (follow_ssa_edge): Same.
+ (analyze_evolution_in_loop): Same.
+ (analyze_initial_condition): Same.
+ (interpret_loop_phi): Same.
+ (interpret_condition_phi): Same.
+ (interpret_rhs_expr): Same.
+ (interpret_expr): Same.
+ (interpret_gimple_assign): Same.
+ (analyze_scalar_evolution_1): Same.
+ (analyze_scalar_evolution): Same.
+ (analyze_scalar_evolution_for_address_of): Same.
+ (get_instantiated_value_entry): Same.
+ (loop_closed_phi_def): Same.
+ (instantiate_scev_name): Same.
+ (instantiate_scev_poly): Same.
+ (instantiate_scev_binary): Same.
+ (instantiate_scev_convert): Same.
+ (instantiate_scev_not): Same.
+ (instantiate_scev_r): Same.
+ (instantiate_scev): Same.
+ (resolve_mixers): Same.
+ (initialize_scalar_evolutions_analyzer): Same.
+ (scev_reset_htab): Same.
+ (scev_reset): Same.
+ (derive_simple_iv_with_niters): Same.
+ (simple_iv_with_niters): Same.
+ (expression_expensive_p): Same.
+ (final_value_replacement_loop): Same.
+ * tree-scalar-evolution.h (block_before_loop): Same.
+ * tree-ssa-address.h: Same.
+ * tree-ssa-dce.c (find_obviously_necessary_stmts): Same.
+ * tree-ssa-dom.c (edge_info::record_simple_equiv): Same.
+ (record_edge_info): Same.
+ * tree-ssa-live.c (var_map_base_fini): Same.
+ (remove_unused_locals): Same.
+ * tree-ssa-live.h: Same.
+ * tree-ssa-loop-ch.c (should_duplicate_loop_header_p): Same.
+ (pass_ch_vect::execute): Same.
+ (pass_ch::process_loop_p): Same.
+ * tree-ssa-loop-im.c (mem_ref_hasher::hash): Same.
+ (movement_possibility): Same.
+ (outermost_invariant_loop): Same.
+ (stmt_cost): Same.
+ (determine_max_movement): Same.
+ (invariantness_dom_walker::before_dom_children): Same.
+ (move_computations): Same.
+ (may_move_till): Same.
+ (force_move_till_op): Same.
+ (force_move_till): Same.
+ (memref_free): Same.
+ (record_mem_ref_loc): Same.
+ (set_ref_stored_in_loop): Same.
+ (mark_ref_stored): Same.
+ (sort_bbs_in_loop_postorder_cmp): Same.
+ (sort_locs_in_loop_postorder_cmp): Same.
+ (analyze_memory_references): Same.
+ (mem_refs_may_alias_p): Same.
+ (find_ref_loc_in_loop_cmp): Same.
+ (rewrite_mem_ref_loc::operator): Same.
+ (first_mem_ref_loc_1::operator): Same.
+ (sm_set_flag_if_changed::operator): Same.
+ (execute_sm_if_changed_flag_set): Same.
+ (execute_sm): Same.
+ (hoist_memory_references): Same.
+ (ref_always_accessed::operator): Same.
+ (refs_independent_p): Same.
+ (record_dep_loop): Same.
+ (ref_indep_loop_p_1): Same.
+ (ref_indep_loop_p): Same.
+ (can_sm_ref_p): Same.
+ (find_refs_for_sm): Same.
+ (loop_suitable_for_sm): Same.
+ (store_motion_loop): Same.
+ (store_motion): Same.
+ (fill_always_executed_in): Same.
+ * tree-ssa-loop-ivcanon.c (constant_after_peeling): Same.
+ (estimated_unrolled_size): Same.
+ (loop_edge_to_cancel): Same.
+ (remove_exits_and_undefined_stmts): Same.
+ (remove_redundant_iv_tests): Same.
+ (unloop_loops): Same.
+ (estimated_peeled_sequence_size): Same.
+ (try_peel_loop): Same.
+ (canonicalize_loop_induction_variables): Same.
+ (canonicalize_induction_variables): Same.
+ * tree-ssa-loop-ivopts.c (iv_inv_expr_hasher::equal): Same.
+ (name_info): Same.
+ (stmt_after_inc_pos): Same.
+ (contains_abnormal_ssa_name_p): Same.
+ (niter_for_exit): Same.
+ (find_bivs): Same.
+ (mark_bivs): Same.
+ (find_givs_in_bb): Same.
+ (find_induction_variables): Same.
+ (find_interesting_uses_cond): Same.
+ (outermost_invariant_loop_for_expr): Same.
+ (idx_find_step): Same.
+ (add_candidate_1): Same.
+ (add_iv_candidate_derived_from_uses): Same.
+ (alloc_use_cost_map): Same.
+ (prepare_decl_rtl): Same.
+ (generic_predict_doloop_p): Same.
+ (computation_cost): Same.
+ (determine_common_wider_type): Same.
+ (get_computation_aff_1): Same.
+ (get_use_type): Same.
+ (determine_group_iv_cost_address): Same.
+ (iv_period): Same.
+ (difference_cannot_overflow_p): Same.
+ (may_eliminate_iv): Same.
+ (determine_set_costs): Same.
+ (cheaper_cost_pair): Same.
+ (compare_cost_pair): Same.
+ (iv_ca_cand_for_group): Same.
+ (iv_ca_recount_cost): Same.
+ (iv_ca_set_remove_invs): Same.
+ (iv_ca_set_no_cp): Same.
+ (iv_ca_set_add_invs): Same.
+ (iv_ca_set_cp): Same.
+ (iv_ca_add_group): Same.
+ (iv_ca_cost): Same.
+ (iv_ca_compare_deps): Same.
+ (iv_ca_delta_reverse): Same.
+ (iv_ca_delta_commit): Same.
+ (iv_ca_cand_used_p): Same.
+ (iv_ca_delta_free): Same.
+ (iv_ca_new): Same.
+ (iv_ca_free): Same.
+ (iv_ca_dump): Same.
+ (iv_ca_extend): Same.
+ (iv_ca_narrow): Same.
+ (iv_ca_prune): Same.
+ (cheaper_cost_with_cand): Same.
+ (iv_ca_replace): Same.
+ (try_add_cand_for): Same.
+ (get_initial_solution): Same.
+ (try_improve_iv_set): Same.
+ (find_optimal_iv_set_1): Same.
+ (create_new_iv): Same.
+ (rewrite_use_compare): Same.
+ (remove_unused_ivs): Same.
+ (determine_scaling_factor): Same.
+ * tree-ssa-loop-ivopts.h: Same.
+ * tree-ssa-loop-manip.c (create_iv): Same.
+ (compute_live_loop_exits): Same.
+ (add_exit_phi): Same.
+ (add_exit_phis): Same.
+ (find_uses_to_rename_use): Same.
+ (find_uses_to_rename_def): Same.
+ (find_uses_to_rename_in_loop): Same.
+ (rewrite_into_loop_closed_ssa): Same.
+ (check_loop_closed_ssa_bb): Same.
+ (split_loop_exit_edge): Same.
+ (ip_end_pos): Same.
+ (ip_normal_pos): Same.
+ (copy_phi_node_args): Same.
+ (gimple_duplicate_loop_to_header_edge): Same.
+ (can_unroll_loop_p): Same.
+ (determine_exit_conditions): Same.
+ (scale_dominated_blocks_in_loop): Same.
+ (niter_for_unrolled_loop): Same.
+ (tree_transform_and_unroll_loop): Same.
+ (rewrite_all_phi_nodes_with_iv): Same.
+ * tree-ssa-loop-manip.h: Same.
+ * tree-ssa-loop-niter.c (number_of_iterations_ne_max): Same.
+ (number_of_iterations_ne): Same.
+ (assert_no_overflow_lt): Same.
+ (assert_loop_rolls_lt): Same.
+ (number_of_iterations_lt): Same.
+ (adjust_cond_for_loop_until_wrap): Same.
+ (tree_simplify_using_condition): Same.
+ (simplify_using_initial_conditions): Same.
+ (simplify_using_outer_evolutions): Same.
+ (loop_only_exit_p): Same.
+ (ssa_defined_by_minus_one_stmt_p): Same.
+ (number_of_iterations_popcount): Same.
+ (number_of_iterations_exit): Same.
+ (find_loop_niter): Same.
+ (finite_loop_p): Same.
+ (chain_of_csts_start): Same.
+ (get_val_for): Same.
+ (loop_niter_by_eval): Same.
+ (derive_constant_upper_bound_ops): Same.
+ (do_warn_aggressive_loop_optimizations): Same.
+ (record_estimate): Same.
+ (get_cst_init_from_scev): Same.
+ (record_nonwrapping_iv): Same.
+ (idx_infer_loop_bounds): Same.
+ (infer_loop_bounds_from_ref): Same.
+ (infer_loop_bounds_from_array): Same.
+ (infer_loop_bounds_from_pointer_arith): Same.
+ (infer_loop_bounds_from_signedness): Same.
+ (bound_index): Same.
+ (discover_iteration_bound_by_body_walk): Same.
+ (maybe_lower_iteration_bound): Same.
+ (estimate_numbers_of_iterations): Same.
+ (estimated_loop_iterations): Same.
+ (estimated_loop_iterations_int): Same.
+ (max_loop_iterations): Same.
+ (max_loop_iterations_int): Same.
+ (likely_max_loop_iterations): Same.
+ (likely_max_loop_iterations_int): Same.
+ (estimated_stmt_executions_int): Same.
+ (max_stmt_executions): Same.
+ (likely_max_stmt_executions): Same.
+ (estimated_stmt_executions): Same.
+ (stmt_dominates_stmt_p): Same.
+ (nowrap_type_p): Same.
+ (loop_exits_before_overflow): Same.
+ (scev_var_range_cant_overflow): Same.
+ (scev_probably_wraps_p): Same.
+ (free_numbers_of_iterations_estimates): Same.
+ * tree-ssa-loop-niter.h: Same.
+ * tree-ssa-loop-prefetch.c (release_mem_refs): Same.
+ (idx_analyze_ref): Same.
+ (analyze_ref): Same.
+ (gather_memory_references_ref): Same.
+ (mark_nontemporal_store): Same.
+ (emit_mfence_after_loop): Same.
+ (may_use_storent_in_loop_p): Same.
+ (mark_nontemporal_stores): Same.
+ (should_unroll_loop_p): Same.
+ (volume_of_dist_vector): Same.
+ (add_subscript_strides): Same.
+ (self_reuse_distance): Same.
+ (insn_to_prefetch_ratio_too_small_p): Same.
+ * tree-ssa-loop-split.c (split_at_bb_p): Same.
+ (patch_loop_exit): Same.
+ (find_or_create_guard_phi): Same.
+ (easy_exit_values): Same.
+ (connect_loop_phis): Same.
+ (connect_loops): Same.
+ (compute_new_first_bound): Same.
+ (split_loop): Same.
+ (tree_ssa_split_loops): Same.
+ * tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Same.
+ (is_maybe_undefined): Same.
+ (tree_may_unswitch_on): Same.
+ (simplify_using_entry_checks): Same.
+ (tree_unswitch_single_loop): Same.
+ (tree_unswitch_loop): Same.
+ (tree_unswitch_outer_loop): Same.
+ (empty_bb_without_guard_p): Same.
+ (used_outside_loop_p): Same.
+ (get_vop_from_header): Same.
+ (hoist_guard): Same.
+ * tree-ssa-loop.c (gate_oacc_kernels): Same.
+ (get_lsm_tmp_name): Same.
+ * tree-ssa-loop.h: Same.
+ * tree-ssa-reassoc.c (add_repeat_to_ops_vec): Same.
+ (build_and_add_sum): Same.
+ (no_side_effect_bb): Same.
+ (get_ops): Same.
+ (linearize_expr): Same.
+ (should_break_up_subtract): Same.
+ (linearize_expr_tree): Same.
+ * tree-ssa-scopedtables.c: Same.
+ * tree-ssa-scopedtables.h: Same.
+ * tree-ssa-structalias.c (condense_visit): Same.
+ (label_visit): Same.
+ (dump_pred_graph): Same.
+ (perform_var_substitution): Same.
+ (move_complex_constraints): Same.
+ (remove_preds_and_fake_succs): Same.
+ * tree-ssa-threadupdate.c (dbds_continue_enumeration_p): Same.
+ (determine_bb_domination_status): Same.
+ (duplicate_thread_path): Same.
+ (thread_through_all_blocks): Same.
+ * tree-ssa-threadupdate.h: Same.
+ * tree-streamer-in.c (streamer_read_string_cst): Same.
+ (input_identifier): Same.
+ (unpack_ts_type_common_value_fields): Same.
+ (unpack_ts_block_value_fields): Same.
+ (unpack_ts_translation_unit_decl_value_fields): Same.
+ (unpack_ts_omp_clause_value_fields): Same.
+ (streamer_read_tree_bitfields): Same.
+ (streamer_alloc_tree): Same.
+ (lto_input_ts_common_tree_pointers): Same.
+ (lto_input_ts_vector_tree_pointers): Same.
+ (lto_input_ts_poly_tree_pointers): Same.
+ (lto_input_ts_complex_tree_pointers): Same.
+ (lto_input_ts_decl_minimal_tree_pointers): Same.
+ (lto_input_ts_decl_common_tree_pointers): Same.
+ (lto_input_ts_decl_non_common_tree_pointers): Same.
+ (lto_input_ts_decl_with_vis_tree_pointers): Same.
+ (lto_input_ts_field_decl_tree_pointers): Same.
+ (lto_input_ts_function_decl_tree_pointers): Same.
+ (lto_input_ts_type_common_tree_pointers): Same.
+ (lto_input_ts_type_non_common_tree_pointers): Same.
+ (lto_input_ts_list_tree_pointers): Same.
+ (lto_input_ts_vec_tree_pointers): Same.
+ (lto_input_ts_exp_tree_pointers): Same.
+ (lto_input_ts_block_tree_pointers): Same.
+ (lto_input_ts_binfo_tree_pointers): Same.
+ (lto_input_ts_constructor_tree_pointers): Same.
+ (lto_input_ts_omp_clause_tree_pointers): Same.
+ (streamer_read_tree_body): Same.
+ * tree-streamer.h: Same.
+ * tree-switch-conversion.c (bit_test_cluster::is_beneficial): Same.
+ * tree-vect-data-refs.c (vect_get_smallest_scalar_type): Same.
+ (vect_analyze_possibly_independent_ddr): Same.
+ (vect_analyze_data_ref_dependence): Same.
+ (vect_compute_data_ref_alignment): Same.
+ (vect_enhance_data_refs_alignment): Same.
+ (vect_analyze_data_ref_access): Same.
+ (vect_check_gather_scatter): Same.
+ (vect_find_stmt_data_reference): Same.
+ (vect_create_addr_base_for_vector_ref): Same.
+ (vect_setup_realignment): Same.
+ (vect_supportable_dr_alignment): Same.
+ * tree-vect-loop-manip.c (rename_variables_in_bb): Same.
+ (adjust_phi_and_debug_stmts): Same.
+ (vect_set_loop_mask): Same.
+ (add_preheader_seq): Same.
+ (vect_maybe_permute_loop_masks): Same.
+ (vect_set_loop_masks_directly): Same.
+ (vect_set_loop_condition_masked): Same.
+ (vect_set_loop_condition_unmasked): Same.
+ (slpeel_duplicate_current_defs_from_edges): Same.
+ (slpeel_add_loop_guard): Same.
+ (slpeel_can_duplicate_loop_p): Same.
+ (create_lcssa_for_virtual_phi): Same.
+ (iv_phi_p): Same.
+ (vect_update_ivs_after_vectorizer): Same.
+ (vect_gen_vector_loop_niters_mult_vf): Same.
+ (slpeel_update_phi_nodes_for_loops): Same.
+ (slpeel_update_phi_nodes_for_guard1): Same.
+ (find_guard_arg): Same.
+ (slpeel_update_phi_nodes_for_guard2): Same.
+ (slpeel_update_phi_nodes_for_lcssa): Same.
+ (vect_do_peeling): Same.
+ (vect_create_cond_for_alias_checks): Same.
+ (vect_loop_versioning): Same.
+ * tree-vect-loop.c (vect_determine_vf_for_stmt): Same.
+ (vect_inner_phi_in_double_reduction_p): Same.
+ (vect_analyze_scalar_cycles_1): Same.
+ (vect_fixup_scalar_cycles_with_patterns): Same.
+ (vect_get_loop_niters): Same.
+ (bb_in_loop_p): Same.
+ (vect_get_max_nscalars_per_iter): Same.
+ (vect_verify_full_masking): Same.
+ (vect_compute_single_scalar_iteration_cost): Same.
+ (vect_analyze_loop_form_1): Same.
+ (vect_analyze_loop_form): Same.
+ (vect_active_double_reduction_p): Same.
+ (vect_analyze_loop_operations): Same.
+ (neutral_op_for_slp_reduction): Same.
+ (vect_is_simple_reduction): Same.
+ (vect_model_reduction_cost): Same.
+ (get_initial_def_for_reduction): Same.
+ (get_initial_defs_for_reduction): Same.
+ (vect_create_epilog_for_reduction): Same.
+ (vectorize_fold_left_reduction): Same.
+ (vectorizable_reduction): Same.
+ (vectorizable_induction): Same.
+ (vectorizable_live_operation): Same.
+ (loop_niters_no_overflow): Same.
+ (vect_get_loop_mask): Same.
+ (vect_transform_loop_stmt): Same.
+ (vect_transform_loop): Same.
+ * tree-vect-patterns.c (vect_reassociating_reduction_p): Same.
+ (vect_determine_precisions): Same.
+ (vect_pattern_recog_1): Same.
+ * tree-vect-slp.c (vect_analyze_slp_instance): Same.
+ * tree-vect-stmts.c (stmt_vectype): Same.
+ (process_use): Same.
+ (vect_init_vector_1): Same.
+ (vect_truncate_gather_scatter_offset): Same.
+ (get_group_load_store_type): Same.
+ (vect_build_gather_load_calls): Same.
+ (vect_get_strided_load_store_ops): Same.
+ (vectorizable_simd_clone_call): Same.
+ (vectorizable_store): Same.
+ (permute_vec_elements): Same.
+ (vectorizable_load): Same.
+ (vect_transform_stmt): Same.
+ (supportable_widening_operation): Same.
+ * tree-vectorizer.c (vec_info::replace_stmt): Same.
+ (vec_info::free_stmt_vec_info): Same.
+ (vect_free_loop_info_assumptions): Same.
+ (vect_loop_vectorized_call): Same.
+ (set_uid_loop_bbs): Same.
+ (vectorize_loops): Same.
+ * tree-vectorizer.h (STMT_VINFO_BB_VINFO): Same.
+ * tree.c (add_tree_to_fld_list): Same.
+ (fld_type_variant_equal_p): Same.
+ (fld_decl_context): Same.
+ (fld_incomplete_type_of): Same.
+ (free_lang_data_in_binfo): Same.
+ (need_assembler_name_p): Same.
+ (find_decls_types_r): Same.
+ (get_eh_types_for_runtime): Same.
+ (find_decls_types_in_eh_region): Same.
+ (find_decls_types_in_node): Same.
+ (assign_assembler_name_if_needed): Same.
+ * value-prof.c (stream_out_histogram_value): Same.
+ * value-prof.h: Same.
+ * var-tracking.c (use_narrower_mode): Same.
+ (prepare_call_arguments): Same.
+ (vt_expand_loc_callback): Same.
+ (resolve_expansions_pending_recursion): Same.
+ (vt_expand_loc): Same.
+ * varasm.c (const_hash_1): Same.
+ (compare_constant): Same.
+ (tree_output_constant_def): Same.
+ (simplify_subtraction): Same.
+ (get_pool_constant): Same.
+ (output_constant_pool_2): Same.
+ (output_constant_pool_1): Same.
+ (mark_constants_in_pattern): Same.
+ (mark_constant_pool): Same.
+ (get_section_anchor): Same.
+ * vr-values.c (compare_range_with_value): Same.
+ (vr_values::extract_range_from_phi_node): Same.
+ * vr-values.h: Same.
+ * web.c (unionfind_union): Same.
+ * wide-int.h: Same.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * align.h: Change class-key from class to struct and vice versa
+ to match convention and avoid -Wclass-is-pod and -Wstruct-no-pod.
+ * alloc-pool.h: Same.
+ * asan.c (shadow_mem_size): Same.
+ * auto-profile.c: Same.
+ * basic-block.h: Same.
+ * bitmap.h: Same.
+ * cfgexpand.c (set_rtl): Same.
+ (expand_one_stack_var_at): Same.
+ * cfghooks.h: Same.
+ * cfgloop.h: Same.
+ * cgraph.h: Same.
+ * config/i386/i386.h: Same.
+ * df-problems.c (df_print_bb_index): Same.
+ * df-scan.c: Same.
+ * df.h (df_single_use): Same.
+ * diagnostic-show-locus.c (layout::print_annotation_line): Same.
+ (layout::annotation_line_showed_range_p): Same.
+ (get_printed_columns): Same.
+ (correction::ensure_terminated): Same.
+ (line_corrections::~line_corrections): Same.
+ * dojump.h: Same.
+ * dse.c: Same.
+ * dump-context.h: Same.
+ * dumpfile.h: Same.
+ * dwarf2out.c: Same.
+ * edit-context.c: Same.
+ * fibonacci_heap.c (test_union_of_equal_heaps): Same.
+ * flags.h: Same.
+ * function.c (assign_stack_local): Same.
+ * function.h: Same.
+ * gcc.c: Same.
+ * gcov.c (block_info::block_info): Same.
+ * genattrtab.c: Same.
+ * genextract.c: Same.
+ * genmatch.c (comparison_code_p): Same.
+ (id_base::id_base): Same.
+ (decision_tree::print): Same.
+ * genoutput.c: Same.
+ * genpreds.c (write_one_predicate_function): Same.
+ * genrecog.c (validate_pattern): Same.
+ (find_operand_positions): Same.
+ (optimize_subroutine_group): Same.
+ (merge_pattern_transition::merge_pattern_transition): Same.
+ (merge_pattern_info::merge_pattern_info): Same.
+ (merge_state_result::merge_state_result): Same.
+ (merge_into_state): Same.
+ * gensupport.c: Same.
+ * gensupport.h: Same.
+ * ggc-common.c (init_ggc_heuristics): Same.
+ * ggc-tests.c (test_union): Same.
+ * gimple-loop-interchange.cc (dump_induction): Same.
+ * gimple-loop-versioning.cc: Same.
+ * gimple-match.h (gimple_match_cond::any_else): Same.
+ * gimple-ssa-backprop.c: Same.
+ * gimple-ssa-sprintf.c: Same.
+ * gimple-ssa-store-merging.c (store_operand_info::store_operand_info):
+ Same.
+ (store_immediate_info::store_immediate_info): Same.
+ (merged_store_group::apply_stores): Same.
+ (get_location_for_stmts): Same.
+ * gimple-ssa-strength-reduction.c: Same.
+ * gimple-ssa-warn-alloca.c: Same.
+ * gimple-ssa-warn-restrict.c (pass_wrestrict::execute): Same.
+ * godump.c (go_type_decl): Same.
+ * hash-map-tests.c (test_map_of_strings_to_int): Same.
+ * hash-map.h: Same.
+ * hash-set-tests.c (test_set_of_strings): Same.
+ * hsa-brig.c: Same.
+ * hsa-common.h: Same.
+ * hsa-gen.c (transformable_switch_to_sbr_p): Same.
+ * input.c (assert_loceq): Same.
+ * input.h: Same.
+ * ipa-cp.c: Same.
+ * ipa-devirt.c (possible_polymorphic_call_targets_1): Same.
+ * ipa-fnsummary.h: Same.
+ * ipa-inline.h: Same.
+ * ipa-prop.h: Same.
+ * ipa-split.c (visit_bb): Same.
+ * ira-int.h (minmax_set_iter_next): Same.
+ * loop-invariant.c: Same.
+ * loop-iv.c: Same.
+ * lra-eliminations.c: Same.
+ * lra-int.h: Same.
+ * lra-lives.c (mark_regno_dead): Same.
+ * lra-remat.c: Same.
+ * lra-spills.c: Same.
+ * lto-streamer.h: Same.
+ * mem-stats.h: Same.
+ * omp-grid.c (omp_grid_lastprivate_predicate): Same.
+ * omp-low.c (omp_clause_aligned_alignment): Same.
+ * optabs-query.h (get_vcond_eq_icode): Same.
+ * optabs.h: Same.
+ * opts.c (wrap_help): Same.
+ * poly-int.h: Same.
+ * predict.c (predict_paths_leading_to_edge): Same.
+ * pretty-print.h: Same.
+ * profile-count.h: Same.
+ * read-md.h: Same.
+ * read-rtl-function.c: Same.
+ * ree.c: Same.
+ * reginfo.c: Same.
+ * regrename.c: Same.
+ * regrename.h: Same.
+ * reload.h: Same.
+ * rtl-iter.h: Same.
+ * rtl.h (costs_add_n_insns): Same.
+ * sanopt.c: Same.
+ * sched-int.h: Same.
+ * sel-sched-ir.h: Same.
+ * selftest.h: Same.
+ * sese.h (vec_find): Same.
+ * stmt.c: Same.
+ * target-globals.h: Same.
+ * tree-affine.c (aff_combination_find_elt): Same.
+ * tree-affine.h: Same.
+ * tree-data-ref.h: Same.
+ * tree-outof-ssa.c (ssa_is_replaceable_p): Same.
+ * tree-predcom.c: Same.
+ * tree-scalar-evolution.c (find_var_scev_info): Same.
+ * tree-ssa-alias.h: Same.
+ * tree-ssa-ccp.c: Same.
+ * tree-ssa-coalesce.c (ssa_conflicts_dump): Same.
+ * tree-ssa-loop-im.c (for_all_locs_in_loop): Same.
+ (rewrite_mem_refs): Same.
+ (execute_sm_if_changed): Same.
+ (hoist_memory_references): Same.
+ * tree-ssa-loop-ivopts.c (operator<=): Same.
+ * tree-ssa-loop.h: Same.
+ * tree-ssa-pre.c (get_or_alloc_expr_for_name): Same.
+ * tree-ssa-structalias.c: Same.
+ * tree-switch-conversion.h (cluster::cluster): Same.
+ (simple_cluster::simple_cluster): Same.
+ * tree-vect-patterns.c (type_conversion_p): Same.
+ * tree-vectorizer.c (dump_stmt_cost): Same.
+ * tree-vectorizer.h (loop_vec_info_for_loop): Same.
+ * tree.c (protected_set_expr_location): Same.
+ * tree.h (desired_pro_or_demotion_p): Same.
+ (fndecl_built_in_p): Same.
+ * unique-ptr-tests.cc: Same.
+ * var-tracking.c (delete_variable_part): Same.
+ * varasm.c (assemble_real): Same.
+ (tree_output_constant_def): Same.
+ * vec.c: Same.
+ * wide-int-bitmask.h: Same.
+ * wide-int.h (decompose): Same.
+
+2019-07-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91114
+ * tree-vect-data-refs.c (vect_analyze_data_refs): Failure to
+ find a vector type isn't fatal.
+
+2019-07-09 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ * config/aarch64/aarch64-simd.md
+ (aarch64_crypto_aes<aes_op>v16qi): Redefine pattern with xor.
+ (aarch64_crypto_aes<aesmc_op>v16qi): Remove attribute enabled.
+ (*aarch64_crypto_aes<aes_op>v16qi_xor_combine): Remove both.
+ (*aarch64_crypto_aese_fused,
+ *aarch64_crypto_aesd_fused): Update to new definition.
+ * config/aarch64/aarch64.c
+ (aarch_macro_fusion_pair_p): Remove aese/aesmc fusion check.
+
+2019-07-09 Richard Biener <rguenther@suse.de>
+
+ * gimple-match.h (gimple_match_op::resimplify): New.
+ (gimple_resimplify1, gimple_resimplify2, gimple_resimplify3,
+ gimple_resimplify4, gimple_resimplify5): Remove.
+ * gimple-match-head.c (gimple_resimplify1, gimple_resimplify2,
+ gimple_resimplify3, gimple_resimplify4, gimple_resimplify5):
+ Make static.
+ (gimple_match_op::resimplify): New.
+ * tree-ssa-sccvn.c (vn_nary_build_or_lookup_1): Valueize
+ according to availability. Use gimple_match_op::resimplify.
+
+2019-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * ira-emit.c (emit_moves): Skip DEBUG_INSNs when setting the location.
+
+2019-07-09 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ * config/arm/crypto.md:
+ (crypto_<crypto_pattern>): Redefine aese/aesd pattern with xor.
+ (crypto_<crypto_pattern>): Remove attribute enabled for aesmc.
+ (crypto_<crypto_pattern>): Split CRYPTO_BINARY into 2 patterns.
+ (*aarch32_crypto_aese_fused, *aarch32_crypto_aesd_fused): New.
+ * config/arm/arm.c
+ (aarch_macro_fusion_pair_p): Remove aes/aesmc fusion check.
+ * config/arm/aarch-common-protos.h
+ (aarch_crypto_can_dual_issue): Remove.
+ * config/arm/aarch-common.c
+ (aarch_crypto_can_dual_issue): Likewise.
+ * config/arm/exynos-m1.md: Remove aese/aesmc fusion.
+ * config/arm/cortex-a53.md: Likewise.
+ * config/arm/cortex-a57.md: Likewise.
+ * config/arm/iterators.md:
+ (CRYPTO_BINARY): Redefine.
+ (CRYPTO_UNARY): Removed.
+ (CRYPTO_AES, CRYPTO_AESMC): New.
+
+2019-07-09 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (struct vn_walk_cb_data): Add orig_ref member.
+ (vn_reference_lookup_3): If the main ref has no access path recorded
+ but orig_ref has use it to do access-path based disambiguation.
+ (vn_reference_lookup_pieces): Adjust.
+ (vn_reference_lookup): Pass down original ref if we valueized.
+
+2019-07-09 Martin Liska <mliska@suse.cz>
+
+ * doc/extend.texi: Document influence on loop
+ optimizers.
+
+2019-07-09 Martin Liska <mliska@suse.cz>
+
+ * lto-compress.c (lto_normalized_zstd_level): Do not use
+ ZSTD_CLEVEL_DEFAULT as it is not default in old releases
+ of libzstd. One can use 0 as a default compression level.
+
+2019-07-09 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Add link from -fprofile-dir option.
+ Use better wording for 'gcno filename'.
+
+2019-07-08 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/71924
+ PR middle-end/90549
+ * gimple-ssa-isolate-paths.c (isolate_path): Add attribute. Update
+ comment.
+ (args_loc_t): New type.
+ (args_loc_t, locmap_t): same.
+ (diag_returned_locals): New function.
+ (is_addr_local): Same.
+ (handle_return_addr_local_phi_arg, warn_return_addr_local): Same.
+ (find_implicit_erroneous_behavior): Call warn_return_addr_local_phi_arg.
+ (find_explicit_erroneous_behavior): Call warn_return_addr_local.
+
+2019-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-vect-stmts.c (scan_operand_equal_p): Look through MEM_REF
+ with SSA_NAME address of POINTER_PLUS_EXPR. Handle MULT_EXPR
+ and casts in offset when different, both through gimple stmts
+ and through trees. Rewritten using loops to minimize code duplication
+ for each operand.
+
+2019-07-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * emit-rtl.c (set_insn_locations): New function moved from...
+ * function.c (set_insn_locations): ...here.
+ * ira-emit.c (emit_moves): Propagate location of the first instruction
+ to the inserted move instructions.
+ * reg-stack.c (compensate_edge): Set the location if the sequence is
+ inserted on the edge.
+ * rtl.h (set_insn_locations): Declare.
+
+2019-07-08 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.c (rs6000_machine_from_flags): Ignore
+ OPTION_MASK_PPC_GFXOPT and OPTION_MASK_PPC_GPOPT for selecting the
+ .machine string.
+
+2019-07-08 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/88233
+ * common.opt (fsplit-wide-types-early): New option.
+ * common/config/rs6000/rs6000-common.c
+ (rs6000_option_optimization_table): Add OPT_fsplit_wide_types_early for
+ OPT_LEVELS_ALL.
+ * doc/invoke.texi (Optimization Options): Add -fsplit-wide-types-early.
+ * lower-subreg.c (pass_lower_subreg2::gate): Add test for
+ flag_split_wide_types_early.
+ (pass_data_lower_subreg3): New.
+ (pass_lower_subreg3): New.
+ (make_pass_lower_subreg3): New.
+ * passes.def (pass_lower_subreg2): Move after the loop passes.
+ (pass_lower_subreg3): New, inserted where pass_lower_subreg2 was.
+ * tree-pass.h (make_pass_lower_subreg2): Move up, to its new place in
+ the pass pipeline; its previous place is taken by ...
+ (make_pass_lower_subreg3): ... this.
+
+2019-07-08 Robin Dapp <rdapp@linux.ibm.com>
+
+ * config/s390/s390.c (s390_shift_truncation_mask): Define.
+ (TARGET_SHIFT_TRUNCATION_MASK): Define.
+
+2019-07-08 Robin Dapp <rdapp@linux.ibm.com>
+
+ * config/s390/constraints.md: Add new jsc constraint.
+ * config/s390/predicates.md: New predicates.
+ * config/s390/s390-protos.h (s390_valid_shift_count): New function.
+ * config/s390/s390.c (s390_valid_shift_count): New function.
+ (print_shift_count_operand): Use s390_valid_shift_count.
+ (print_operand): Likewise.
+ * config/s390/s390.md: Use new predicate.
+ * config/s390/subst.md: Remove addr_style_op and masked_op substs.
+ * config/s390/vector.md: Use new predicate.
+
+2019-07-08 Joern Rennecke <joern.rennecke@riscy-ip.com>
+
+ Avoid clash with system header declaration.
+ * testsuite/gcc.dg/vect/slp-reduc-sad.c (uint32_t):
+ Remove unused declaration.
+
+2019-07-08 Andrew Waterman <andrew@sifive.com>
+ Jim Wilson <jimw@sifive.com>
+
+ * config/riscv/riscv.md (lshrsi3_zero_extend_3+1): Use operands[1]
+ bitsize instead of BITS_PER_WORD.
+ gcc/testsuite/
+
+2019-07-08 Martin Liska <mliska@suse.cz>
+
+ * collect2.c (defined): Revert to before r254460.
+ (scan_prog_file): Revert to before r254460.
+
+2019-07-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/83518
+ * tree-ssa-sccvn.c: Include splay-tree.h.
+ (struct pd_range, struct pd_data): New.
+ (struct vn_walk_cb_data): Add data to track partial definitions.
+ (vn_walk_cb_data::~vn_walk_cb_data): New.
+ (vn_walk_cb_data::push_partial_def): New.
+ (pd_tree_alloc, pd_tree_dealloc, pd_range_compare): New.
+ (vn_reference_lookup_2): When partial defs are registered give up.
+ (vn_reference_lookup_3): Track partial defs for memset and
+ constructor zeroing and for defs from constants.
+
+2019-07-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * doc/install.texi (bootstrap-Og): Document.
+
+2019-07-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/riscv/pic.md (*local_pic_load_s<mode>)
+ (*local_pic_load_u<mode>): Explicitly specify the mode iterator
+ referenced by <mode>, giving...
+ (*local_pic_load_s<SUBX:mode>, *local_pic_load_u<SUBX:mode>): ...these.
+ * config/riscv/riscv.md (*sge<u>_<X:mode><GPR:mode>)
+ (*slt<u>_<X:mode><GPR:mode>, *sle<u>_<X:mode><GPR:mode>): Explicitly
+ use <X:MODE> for the mode attribute.
+
+2019-07-07 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/91090
+ * tree-ssa-dom.c (simplify_stmt_for_jump_threading): Fix logic error
+ in handling of ranges to simplify switch statements.
+
+2019-07-07 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.c (darwin_override_options): Make a final check on PIC
+ options.
+
+2019-07-07 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.c (darwin_override_options): Don't jam symbol stubs
+ on for kernel code.
+
+2019-07-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/91068
+ * config/mips/mips.md (*mul_acc_si, *mul_acc_si_r3900, *macc)
+ (*msac, *msac_using_macc, *mul_sub_si): Use "l" for input operands
+ instead of matching them to "l" output operands.
+
+2019-07-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/mips/mips.c (mips_split_move): Zero-initialize addr
+ and check whether addr.reg is nonnull before using it.
+
+2019-07-06 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (lower_rec_input_clauses): For lastprivate clauses in
+ ctx->for_simd_scan_phase simd copy the outer var to the privatized
+ variable(s). For conditional lastprivate look through outer
+ GIMPLE_OMP_SCAN context.
+ (lower_omp_1): For conditional lastprivate look through outer
+ GIMPLE_OMP_SCAN context.
+
+ * omp-low.c (struct omp_context): Rename combined_into_simd_safelen0
+ member to combined_into_simd_safelen1.
+ (lower_rec_input_clauses, lower_omp_1): Adjust uses.
+ (lower_lastprivate_clauses): Likewise. For conditional lastprivate
+ clauses if ctx->combined_into_simd_safelen1 put statements after the
+ predicate conditionalized block rather than into it.
+
+2019-07-06 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/s390/s390.md (*negabs<FP:mode>2_nocc): Use FP for
+ operand 1.
+ * config/s390/vx-builtins.md (*vec_cmp<insn_cmp><mode>_cconly):
+ Make the choice of <mode> explicit, giving...
+ (*vec_cmp<insn_cmp><VF_HW:mode>_cconly): ...this.
+
+2019-07-06 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/i386/i386.md (*fop_<X87MODEF:mode>_3_i387)
+ (l<rounding_insn><MODEF:mode><SWI48:mode>2): Fix ambiguous uses
+ of .md attributes.
+ * config/i386/sse.md (*avx512pf_gatherpf<mode>sf_mask)
+ (*avx512pf_gatherpf<mode>df_mask, *avx512pf_scatterpf<mode>sf_mask)
+ (*avx512pf_scatterpf<mode>df_mask, *avx2_gathersi<mode>)
+ (*avx2_gathersi<mode>_2, *avx2_gatherdi<mode>)
+ (*avx2_gatherdi<mode>_2, *avx2_gatherdi<mode>_3): Likewise.
+ (*avx2_gatherdi<mode>_4, *avx512f_gathersi<mode>): Likewise.
+ (*avx512f_gathersi<mode>_2, *avx512f_gatherdi<mode>): Likewise.
+ (*avx512f_gatherdi<mode>_2, *avx512f_scattersi<mode>): Likewise.
+ (*avx512f_scatterdi<mode>): Likewise.
+ (*andnot<mode>3_bcst): Fix VI/VI48_AVX512VL typo.
+
+2019-07-06 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/h8300/h8300.md (*push1_h8300hs_<mode>): Explicitly
+ specify the mode iterator referenced by <mode>, giving...
+ (*push1_h8300hs_<QHI:mode>): ...this.
+
+2019-07-06 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/gcn/gcn-valu.md
+ (vcond<VEC_1REG_MODE:mode><VEC_1REG_ALT:mode>): Use
+ gen_vec_cmp<VEC_1REG_ALT:mode>di rather than (implicitly)
+ gen_vec_cmp<VEC_1REG_MODE:mode>di. Explicitly use
+ gen_vcond_mask_<VEC_1REG_MODE:mode>di.
+ (vcond<VEC_1REG_MODE:mode><VEC_1REG_ALT:mode>_exec): Likewise,
+ but using the _exec comparison patterns.
+ (vcondu<VEC_1REG_INT_MODE:mode><VEC_1REG_INT_ALT:mode>): Use
+ gen_vec_cmp<VEC_1REG_INT_ALT:mode>di rather than (implicitly)
+ gen_vec_cmp<VEC_1REG_INT_MODE:mode>di. Explicitly use
+ gen_vcond_mask_<VEC_1REG_INT_MODE:mode>di.
+ (vcondu<VEC_1REG_INT_MODE:mode><VEC_1REG_INT_ALT:mode>_exec): Likewise,
+ but using the _exec comparison patterns.
+
+2019-07-06 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/arm/sync.md
+ (@atomic_compare_and_swap<CCSI:arch><NARROW:mode>_1): Use
+ <NARROW:sync_predtab> instead of (implicitly) <CCSI:sync_predtab>.
+ (@atomic_compare_and_swap<CCSI:arch><SIDI:mode>_1): Likewise
+ <SIDI:sync_predtab>. Use <SIDI:cas_cmp_operand> and
+ <SIDI:cas_cmp_str>.
+
+2019-07-06 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (struct omp_context): Add for_simd_scan_phase member.
+ (maybe_lookup_ctx): Add forward declaration.
+ (omp_find_scan): Likewise. Walk into body of simd if composited
+ with worksharing loop.
+ (scan_omp_simd_scan): New function.
+ (scan_omp_1_stmt): Call it.
+ (lower_rec_simd_input_clauses): Don't create rvar nor rvar2 if
+ ctx->for_simd_scan_phase.
+ (lower_rec_input_clauses): Do much less work for inscan reductions
+ in ctx->for_simd_scan_phase is_simd regions.
+ (lower_omp_scan): Set is_simd also on simd constructs composited
+ with worksharing loop, unless ctx->for_simd_scan_phase. Never emit
+ a sorry message. Don't change GIMPLE_OMP_SCAN stmts into nops and
+ emit their body after in simd constructs composited with worksharing
+ loop.
+ (lower_omp_for_scan): Handle worksharing loop composited with simd.
+
+ * omp-low.c (omp_find_scan): Make static.
+ (lower_omp_for_scan): Fix order of merge arguments in input phase of
+ the second loop, var2 represents the first partial sum and so needs
+ to go before rprivb[ivar].
+
+2019-07-05 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/rs6000/rs6000-logue.c: Remove unused code.
+
+2019-07-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-ssa-loop-manip.c (create_iv): Add missing guard for gsi_end_p.
+
+2019-07-05 Sam Tebbs <sam.tebbs@arm.com>
+
+ PR target/90712
+ * config/aarch64/aarch64.c (aarch64_post_cfi_startproc): Replace thunk
+ check with a frame laid out check.
+
+2019-07-05 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Valueize RHS
+ when comparing against a store with possibly the same value.
+
+2019-07-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91091
+ * tree-ssa-alias.h (get_continuation_for_phi): Add tbaa_p parameter.
+ (walk_non_aliased_vuses): Likewise.
+ * tree-ssa-alias.c (maybe_skip_until): Pass down tbaa_p.
+ (get_continuation_for_phi): New tbaa_p parameter and pass
+ it down.
+ (walk_non_aliased_vuses): Likewise.
+ * ipa-prop.c (determine_known_aggregate_parts): Adjust.
+ * tree-ssa-pre.c (translate_vuse_through_block): Likewise.
+ * tree-ssa-scopedtables.c (avail_exprs_stack::lookup_avail_expr):
+ Likewise.
+ * tree-ssa-sccvn.c (struct vn_walk_cb_data): Add tbaa_p flag.
+ (adjust_offsets_for_equal_base_address): New function.
+ (vn_reference_lookup_3): Use it to catch more base equivalences.
+ Handle and pass down tbaa_p flag.
+ (vn_reference_lookup_pieces): Adjust.
+ (vn_reference_lookup): Remove alias-set altering, instead pass
+ down false as tbaa_p.
+
+2019-07-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91091
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): Overlap of
+ accesses can happen with -fno-strict-aliasing.
+
+2019-07-05 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-ssa-alias.c (alias_stats): Add
+ nonoverlapping_component_refs_since_match_p_must_overlap.
+ (dump_alias_stats): Print it.
+ (nonoverlapping_component_refs_since_match_p): Add early exit.
+ (nonoverlapping_component_refs_p): Do not account early exit.
+
+2019-07-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * except.c (emit_to_new_bb_before): Make sure to put a location on SEQ.
+ * tree-eh.c (replace_goto_queue_1) <GIMPLE_GOTO>: Propagate location.
+ (emit_eh_dispatch): Delete.
+ (lower_catch): Emit the eh_dispatch manually and set the location of
+ the first catch statement onto it.
+ (lower_eh_filter): Emit the eh_dispatch manually and set location.
+ (lower_eh_dispatch): Propagate location.
+ * tree-outof-ssa.c (set_location_for_edge): Handle EH edges specially.
+ (eliminate_build): Likewise.
+
+2019-07-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-cfg.c (gimple_make_forwarder_block): Propagate location info on
+ phi nodes if possible.
+ * tree-scalar-evolution.c (final_value_replacement_loop): Propagate
+ location info on the newly created statement.
+ * tree-ssa-loop-manip.c (create_iv): Propagate location info on the
+ newly created increment if needed.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/78884
+ * gimplify.c (struct gimplify_omp_ctx): Add add_safelen1 member.
+ (gimplify_bind_expr): If seeing TREE_ADDRESSABLE VLA inside of simd
+ loop body, set ctx->add_safelen1 instead of making it GOVD_PRIVATE.
+ (gimplify_adjust_omp_clauses): Add safelen (1) clause if
+ ctx->add_safelen1 is set.
+
+ * omp-expand.c (expand_omp_for_static_nochunk): Don't emit
+ GOMP_loop_start at the start of second worksharing loop in a scan.
+ For nowait, don't emit GOMP_loop_end_nowait at the end of first
+ worksharing loop in a scan even if there are conditional lastprivates,
+ and do emit GOMP_loop_end_nowait at the end of second worksharing loop.
+
+2019-07-04 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-alias.c (nonoverlapping_component_refs_since_match_p):
+ Fix check for match in the ref walk.
+
+2019-07-04 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-loop-niter.c
+ (get_upper_bound_based_on_builtin_expr_with_prob): New function.
+ (estimate_numbers_of_iterations):
+ Support __builtin_expect_with_probability for analysis
+ of # of loop iterations.
+
+2019-07-04 Alexandre Oliva <oliva@adacore.com>
+
+ * doc/generic.texi (Cleanups): Document EH_ELSE_EXPR.
+ * except.c: Likewise.
+ * expr.c (expand_expr_real_1): Reject it.
+ * gimplify.c (gimplify_expr): Gimplify it, within
+ TRY_FINALLY_EXPR.
+ * tree-dump.c (dequeue_and_dump): Dump it.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ * tree.c (block_may_fallthru): Handle it.
+ * tree.def (EH_ELSE_EXPR): Introduce it.
+ * gimple-pretty-print.c (dump_gimple_try): Dump TRY_FINALLY
+ with GIMPLE_EH_ELSE as try/finally/else.
+
+2019-07-04 Richard Biener <rguenther@suse.de>
+
+ PR ipa/91062
+ * tree-pass.h (execute_all_ipa_transforms): Add a flag
+ parameter whether to disable GC collection.
+ * passes.c (execute_one_ipa_transform_pass): Likewise, and
+ honor it.
+ (execute_all_ipa_transforms): Likewise and pass it down.
+ * cgraph.c (cgraph_node::get_body): Do not invoke garbage
+ collection from applying IPA transforms.
+ * cgraphunit.c (cgraph_node::expand): Allow garbage collection
+ from applying IPA transforms.
+
+2019-07-04 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/90911
+ * tree-vectorizer.h (_loop_vec_info::scalar_loop_scaling): New field.
+ (LOOP_VINFO_SCALAR_LOOP_SCALING): new.
+ * tree-vect-loop.c (_loop_vec_info::_loop_vec_info): Initialize
+ scalar_loop_scaling.
+ (vect_transform_loop): Scale scalar loop profile if needed.
+ * tree-vect-loop-manip.c (vect_loop_versioning): When re-using
+ the loop copy from if-conversion adjust edge probabilities
+ and scale the vectorized loop body profile, queue the scalar
+ profile for updating after peeling.
+
+2019-07-04 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-alias.c (decl_refs_may_alias_p): Add size1 and size2
+ parameters; return early for must-alias.
+ (indirect_ref_may_alias_decl_p): Likewise; when establishing
+ outer types match, try nonoverlapping_component_refs
+ if must-alias is not obvious.
+ (indirect_refs_may_alias_p): Likewise.
+ (refs_may_alias_p_2): Likewise.
+
+2019-07-04 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-sccvn.h (vn_reference_lookup): Add last_vuse_ptr
+ argument.
+ * tree-ssa-sccvn.c (last_vuse_ptr, vn_walk_kind): Move
+ globals into...
+ (struct vn_walk_cb_data): New callback data struct.
+ (vn_reference_lookup_2): Adjust.
+ (vn_reference_lookup_3): Likewise.
+ (vn_reference_lookup_pieces): Likewise.
+ (vn_reference_lookup): Likewise, get last_vuse_ptr argument.
+ (visit_reference_op_load): Adjust.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91063
+ * tree-vect-stmts.c (vect_init_vector): Call gsi_remove to remove
+ stmt from stmts sequence before calling vect_init_vector_1.
+ Formatting fix.
+
+2019-07-04 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR target/88833
+ * fwprop.c (reg_single_def_p): New function.
+ (propagate_rtx_1): Add unconditional else inside RTX_EXTRA case.
+ (forward_propagate_into): New parameter reg_prop_only
+ with default value false.
+ Propagate def's src into loop only if SET_SRC and SET_DEST
+ of def_set have single definitions.
+ Likewise if reg_prop_only is set to true.
+ (fwprop): New param fwprop_addr_p.
+ Integrate fwprop_addr into fwprop.
+ (fwprop_addr): Remove.
+ (pass_rtl_fwprop_addr::execute): Call fwprop with arg set
+ to true.
+ (pass_rtl_fwprop::execute): Call fwprop with arg set to false.
+ * simplify-rtx.c (simplify_subreg): Add case for vector comparison.
+ * config/i386/sse.md (UNSPEC_BLENDV): Adjust pattern.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * omp-low.c (lower_omp_scan): Call lower_omp on stmt's body
+ in worksharing loop scans.
+
+ PR tree-optimization/91074
+ * omp-low.c (lower_omp_for_scan): Set DECL_GIMPLE_REG_P on cplx
+ temporary.
+
+ PR rtl-optimization/90756
+ * explow.c (promote_ssa_mode): Always use TYPE_MODE, don't bypass it
+ for VECTOR_TYPE_P.
+
2019-07-03 Dennis Zhang <dennis.zhang@arm.com>
* config/aarch64/aarch64.md: Remove redundant constraints from
@@ -545,7 +3887,7 @@
2019-07-01 Vladislav Ivanishin <vlad@ispras.ru>
- * gdbhooks.py (GdbPrettyPrinters.add_printer_for_types): Reorder
+ * gdbhooks.py (GdbPrettyPrinters.add_printer_for_types): Reorder
parameter names to match usage (no functional change).
(GdbPrettyPrinters.add_printer_for_regex): Ditto.
@@ -732,7 +4074,7 @@
* config/arc/arc.h: Change movmem to cpymem in comment.
* config/arc/arc.md (movmemsi): Change movmem to cpymem.
* config/arm/arm-protos.h: Change movmem to cpymem in names.
- * config/arm/arm.c (arm_movmemqi_unaligned, arm_gen_movmemqi,
+ * config/arm/arm.c (arm_movmemqi_unaligned, arm_gen_movmemqi,
gen_movmem_ldrd_strd, thumb_expand_movmemqi) Change movmem to cpymem.
* config/arm/arm.md (movmemqi): Change movmem to cpymem.
* config/arm/thumb1.md (movmem12b, movmem8b): Change movmem to cpymem.
@@ -757,7 +4099,7 @@
expand_setmem_epilogue_via_loop, expand_set_or_cpymem_prologue,
expand_small_cpymem_or_setmem,
expand_set_or_cpymem_prologue_epilogue_by_misaligned_moves,
- expand_set_or_cpymem_constant_prologue,
+ expand_set_or_cpymem_constant_prologue,
ix86_expand_set_or_cpymem): Change movmem to cpymem.
* config/i386/i386-protos.h: Change movmem to cpymem.
* config/i386/i386.h: Change movmem to cpymem in comment.
@@ -788,9 +4130,9 @@
* config/pa/pa.c (compute_movmem_length): Change movmem to cpymem.
(pa_adjust_insn_length): Change call to compute_movmem_length.
* config/pa/pa.md (movmemsi, movmemsi_prereload, movmemsi_postreload,
- movmemdi, movmemdi_prereload,
+ movmemdi, movmemdi_prereload,
movmemdi_postreload): Change movmem to cpymem.
- * config/pdp11/pdp11.md (movmemhi, movmemhi1,
+ * config/pdp11/pdp11.md (movmemhi, movmemhi1,
movmemhi_nocc, UNSPEC_MOVMEM): Change movmem to cpymem.
* config/riscv/riscv.c: Change movmem to cpymem in comment.
* config/riscv/riscv.h: Change movmem to cpymem.
@@ -815,7 +4157,7 @@
* doc/md.texi: Change movmem to cpymem and update description to match.
* doc/rtl.texi: Change movmem to cpymem.
* target.def (use_by_pieces_infrastructure_p): Change movmem to cpymem.
- * doc/tm.texi: Regenerate.
+ * doc/tm.texi: Regenerate.
2019-06-27 Bill Schmidt <wschmidt@linux.ibm.com>
@@ -894,7 +4236,8 @@
* dojump.c (do_jump_by_parts_greater_rtx): Likewise.
* early-remat.c (early_remat::record_equiv_candidates): Likewise.
* emit-rtl.c (try_split): Likewise.
- * graphite-scop-detection.c (assign_parameter_index_in_region): Likewise.
+ * graphite-scop-detection.c (assign_parameter_index_in_region):
+ Likewise.
* ipa-cp.c (cgraph_edge_brings_all_agg_vals_for_node): Likewise.
* ira-color.c (setup_profitable_hard_regs): Likewise.
* ira.c (rtx_moveable_p): Likewise.
@@ -1051,13 +4394,6 @@
* bb-reorder.c (connect_better_edge_p): Add missing else
statement in the middle of if-else statements.
-/home/marxin/Programming/gcc/gcc/bb-reorder.c:1031:2: warning: Value stored to 'is_better_edge' is never read
- is_better_edge = true;
- ^ ~~~~
-/home/marxin/Programming/gcc/gcc/bb-reorder.c:1034:2: warning: Value stored to 'is_better_edge' is never read
- is_better_edge = false;
- ^ ~~~~~
-
2019-06-25 Hongtao Liu <hongtao.liu@intel.com>
H.J. Lu <hongjiu.lu@intel.com>
Olga Makhotina <olga.makhotina@intel.com>
@@ -1207,7 +4543,7 @@
(df_update_exit_block_uses): Likewise.
2019-06-25 Kwok Cheung Yeung <kcy@codesourcery.com>
- Andrew Stubbs <ams@codesourcery.com>
+ Andrew Stubbs <ams@codesourcery.com>
* config.gcc (thread_file): Set to gcn for AMD GCN.
* config/gcn/gcn.c (gcn_emutls_var_init): New function.
@@ -1697,7 +5033,7 @@
2019-06-18 Iain Sandoe <iain@sandoe.co.uk>
- * config/darwin.c: Strip trailing whitespace.
+ * config/darwin.c: Strip trailing whitespace.
2019-06-18 Iain Sandoe <iain@sandoe.co.uk>
@@ -2229,10 +5565,10 @@
2019-06-12 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com>
- * config/arm/iterators.md (VABAL): New int iterator.
- * config/arm/neon.md (<sup>sadv16qi): New define_expand.
- * config/arm/unspecs.md ("unspec"): Define UNSPEC_VABAL_S, UNSPEC_VABAL_U
- values.
+ * config/arm/iterators.md (VABAL): New int iterator.
+ * config/arm/neon.md (<sup>sadv16qi): New define_expand.
+ * config/arm/unspecs.md ("unspec"): Define UNSPEC_VABAL_S,
+ UNSPEC_VABAL_U values.
2019-06-12 Martin Liska <mliska@suse.cz>
@@ -2481,8 +5817,7 @@
(gimple_stringops_transform): Likewise.
(gimple_find_values_to_profile): Set number
of counters for HIST_TYPE_SINGLE_VALUE.
- * value-prof.h (get_most_common_single_value):
- New.
+ * value-prof.h (get_most_common_single_value): New.
2019-06-10 Martin Liska <mliska@suse.cz>
@@ -2566,7 +5901,7 @@
(types_same_for_odr): Remove.
(types_odr_comparable): Remove.
(odr_vtable_hasher::equal): Remove.
- (odr_vtable_hash_type, odr_vtable_hash): Remove.
+ (odr_vtable_hash_type, odr_vtable_hash): Remove.
(add_type_duplicate): Do not synchronize vtable and name hashtables.
(get_odr_type): Do not use vtable hash.
(dump_odr_type): Remove commented out code.
@@ -3277,7 +6612,8 @@
2019-06-03 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/iterators.md (MAX_OPP): New code attr.
- * config/aarch64/aarch64-simd.md (*aarch64_<su>abd<mode>_3): Rename to...
+ * config/aarch64/aarch64-simd.md (*aarch64_<su>abd<mode>_3):
+ Rename to...
(aarch64_<su>abd<mode>_3): ... This.
(<sur>sadv16qi): Add TARGET_DOTPROD expansion.
@@ -3358,7 +6694,7 @@
NOTE_INSN_DELETED_LABEL check.
2019-05-31 Prachi Godbole <prachi.godbole@imgtec.com>
- Robert Suchanek <robert.suchanek@mips.com>
+ Robert Suchanek <robert.suchanek@mips.com>
* config/mips/mips.c (mips_expand_builtin_insn): Swap the 1st
and 3rd operands of the fmadd/fmsub/maddv builtin.
@@ -3524,7 +6860,7 @@
2019-05-30 Sam Tebbs <sam.tebbs@arm.com>
- * aarch64/aarch64.c (aarch64_post_cfi_startproc): Add
+ * aarch64/aarch64.c (aarch64_post_cfi_startproc): Add
cfun->is_thunk check.
2019-05-30 Jakub Jelinek <jakub@redhat.com>
@@ -3566,7 +6902,6 @@
(*call_indirect_pcrel): New insn.
(*call_value_indirect_pcrel): Likewise.
-
2019-05-29 Uroš Bizjak <ubizjak@gmail.com>
* config/i386/sse.md (*save_multiple<mode>): Rename from
@@ -3653,8 +6988,9 @@
* config/aarch64/iterators.md (pauth_hint_num_a): Replace
UNSPEC_PACI1716 and UNSPEC_AUTI1716 with UNSPEC_PACIA1716 and
UNSPEC_AUTIA1716 respectively.
- * config/aarch64/iterators.md (pauth_hint_num_a): Rename to pauth_hint_num
- and add UNSPEC_PACIBSP, UNSPEC_AUTIBSP, UNSPEC_PACIB1716, UNSPEC_AUTIB1716.
+ * config/aarch64/iterators.md (pauth_hint_num_a): Rename to
+ pauth_hint_num and add UNSPEC_PACIBSP, UNSPEC_AUTIBSP,
+ UNSPEC_PACIB1716, UNSPEC_AUTIB1716.
* doc/invoke.texi (-mbranch-protection): Add b-key type.
* config/aarch64/aarch64-bti-insert.c (aarch64_pac_insn_p): Rename
UNSPEC_PACISP to UNSPEC_PACIASP and UNSPEC_PACIBSP.
@@ -4001,8 +7337,8 @@
2019-05-23 Iain Sandoe <iain@sandoe.co.uk>
- * config/i386/darwin.h: Reject -mfentry*.
- * doc/sourcebuild.texi: Document mfentry target support.
+ * config/i386/darwin.h: Reject -mfentry*.
+ * doc/sourcebuild.texi: Document mfentry target support.
2019-05-23 Bill Schmidt <wschmidt@linux.ibm.com>
@@ -4139,7 +7475,7 @@
decl.
2019-05-22 Kwok Cheung Yeung <kcy@codesourcery.com>
- Andrew Stubbs <amd@codesourcery.com>
+ Andrew Stubbs <amd@codesourcery.com>
* config.gcc (gcc_cv_initfini_array): Set for AMD GCN.
* config/gcn/gcn-run.c (init_array_kernel, fini_array_kernel): New.
@@ -4417,8 +7753,6 @@
(altivec_expand_builtin): Likewise.
(rs6000_get_function_versions_dispatcher): Quote target_clones.
-Fix test-suite.
-
2019-05-20 Jakub Jelinek <jakub@redhat.com>
PR c++/59813
@@ -4689,120 +8023,120 @@ Fix test-suite.
2019-05-16 Martin Sebor <msebor@redhat.com>
- * builtins.c (expand_builtin_atomic_always_lock_free): Quote
- identifiers, keywords, operators, and types in diagnostics. Correct
- quoting, spelling, and sentence capitalization issues.
- (expand_builtin_atomic_is_lock_free): Same.
- (fold_builtin_next_arg): Same.
- * cfgexpand.c (expand_one_var): Same.
- (tree_conflicts_with_clobbers_p): Same.
- (expand_asm_stmt): Same.
- (verify_loop_structure): Same.
- * cgraphunit.c (process_function_and_variable_attributes): Same.
- * collect-utils.c (collect_execute): Same.
- * collect2.c (maybe_run_lto_and_relink): Same.
- (is_lto_object_file): Same.
- (scan_prog_file): Same.
- * convert.c (convert_to_real_1): Same.
- * dwarf2out.c (dwarf2out_begin_prologue): Same.
- * except.c (verify_eh_tree): Same.
- * gcc.c (execute): Same.
- (eval_spec_function): Same.
- (run_attempt): Same.
- (driver::set_up_specs): Same.
- (compare_debug_auxbase_opt_spec_function): Same.
- * gcov-tool.c (unlink_gcda_file): Same.
- (do_merge): Same.
- (do_rewrite): Same.
- * gcse.c (gcse_or_cprop_is_too_expensive): Same.
- * gimplify.c (gimplify_asm_expr): Same.
- (gimplify_adjust_omp_clauses): Same.
- * hsa-gen.c (gen_hsa_addr_insns): Same.
- (gen_hsa_insns_for_load): Same.
- (gen_hsa_cmp_insn_from_gimple): Same.
- (gen_hsa_insns_for_operation_assignment): Same.
- (gen_get_level): Same.
- (gen_hsa_alloca): Same.
- (omp_simple_builtin::generate): Same.
- (gen_hsa_atomic_for_builtin): Same.
- (gen_hsa_insns_for_call): Same.
- * input.c (dump_location_info): Same.
- * ipa-devirt.c (compare_virtual_tables): Same.
- * ira.c (ira_setup_eliminable_regset): Same.
- * lra-assigns.c (lra_assign): Same.
- * lra-constraints.c (lra_constraints): Same.
- * lto-streamer-in.c (lto_input_mode_table): Same.
- * lto-wrapper.c (get_options_from_collect_gcc_options): Same.
- (merge_and_complain): Same.
- (compile_offload_image): Same.
- (compile_images_for_offload_targets): Same.
- (debug_objcopy): Same.
- (run_gcc): Same.
- (main): Same.
- * opts.c (print_specific_help): Same.
- (parse_no_sanitize_attribute): Same.
- (print_help): Same.
- (handle_param): Same.
- * plugin.c (add_new_plugin): Same.
- (parse_plugin_arg_opt): Same.
- (try_init_one_plugin): Same.
- * print-rtl.c (debug_bb_n_slim): Quote identifiers, keywords,
- operators, and types in diagnostics. Correct quoting and spelling
- issues.
- * read-rtl-function.c (parse_edge_flag_token): Same.
- (function_reader::parse_enum_value): Same.
- * reg-stack.c (check_asm_stack_operands): Same.
- * regcprop.c (validate_value_data): Same.
- * sched-rgn.c (make_pass_sched_fusion): Same.
- * stmt.c (check_unique_operand_names): Same.
- * targhooks.c (default_target_option_pragma_parse): Same.
- * tlink.c (recompile_files): Same.
- * toplev.c (process_options): Same.
- (do_compile): Same.
- * trans-mem.c (diagnose_tm_1): Same.
- (ipa_tm_scan_irr_block): Same.
- (ipa_tm_diagnose_transaction): Same.
- * tree-cfg.c (verify_address): Same. Use get_tree_code_name to
- format a tree code name in a diagnostic.
- (verify_types_in_gimple_min_lval): Same.
- (verify_types_in_gimple_reference): Same.
- (verify_gimple_call): Same.
- (verify_gimple_assign_unary): Same.
- (verify_gimple_assign_binary): Same.
- (verify_gimple_assign_ternary): Same.
- (verify_gimple_assign_single): Same.
- (verify_gimple_switch): Same.
- (verify_gimple_label): Same.
- (verify_gimple_phi): Same.
- (verify_gimple_in_seq): Same.
- (verify_eh_throw_stmt_node): Same.
- (collect_subblocks): Same.
- (gimple_verify_flow_info): Same.
- (do_warn_unused_result): Same.
- * tree-inline.c (expand_call_inline): Same.
- * tree-into-ssa.c (update_ssa): Same.
- * tree.c (tree_int_cst_elt_check_failed): Same.
- (tree_vec_elt_check_failed): Same.
- (omp_clause_operand_check_failed): Same.
- (verify_type_variant): Same.
- (verify_type): Same.
- * value-prof.c (verify_histograms): Same.
- * varasm.c (assemble_start_function): Same.
+ * builtins.c (expand_builtin_atomic_always_lock_free): Quote
+ identifiers, keywords, operators, and types in diagnostics. Correct
+ quoting, spelling, and sentence capitalization issues.
+ (expand_builtin_atomic_is_lock_free): Same.
+ (fold_builtin_next_arg): Same.
+ * cfgexpand.c (expand_one_var): Same.
+ (tree_conflicts_with_clobbers_p): Same.
+ (expand_asm_stmt): Same.
+ (verify_loop_structure): Same.
+ * cgraphunit.c (process_function_and_variable_attributes): Same.
+ * collect-utils.c (collect_execute): Same.
+ * collect2.c (maybe_run_lto_and_relink): Same.
+ (is_lto_object_file): Same.
+ (scan_prog_file): Same.
+ * convert.c (convert_to_real_1): Same.
+ * dwarf2out.c (dwarf2out_begin_prologue): Same.
+ * except.c (verify_eh_tree): Same.
+ * gcc.c (execute): Same.
+ (eval_spec_function): Same.
+ (run_attempt): Same.
+ (driver::set_up_specs): Same.
+ (compare_debug_auxbase_opt_spec_function): Same.
+ * gcov-tool.c (unlink_gcda_file): Same.
+ (do_merge): Same.
+ (do_rewrite): Same.
+ * gcse.c (gcse_or_cprop_is_too_expensive): Same.
+ * gimplify.c (gimplify_asm_expr): Same.
+ (gimplify_adjust_omp_clauses): Same.
+ * hsa-gen.c (gen_hsa_addr_insns): Same.
+ (gen_hsa_insns_for_load): Same.
+ (gen_hsa_cmp_insn_from_gimple): Same.
+ (gen_hsa_insns_for_operation_assignment): Same.
+ (gen_get_level): Same.
+ (gen_hsa_alloca): Same.
+ (omp_simple_builtin::generate): Same.
+ (gen_hsa_atomic_for_builtin): Same.
+ (gen_hsa_insns_for_call): Same.
+ * input.c (dump_location_info): Same.
+ * ipa-devirt.c (compare_virtual_tables): Same.
+ * ira.c (ira_setup_eliminable_regset): Same.
+ * lra-assigns.c (lra_assign): Same.
+ * lra-constraints.c (lra_constraints): Same.
+ * lto-streamer-in.c (lto_input_mode_table): Same.
+ * lto-wrapper.c (get_options_from_collect_gcc_options): Same.
+ (merge_and_complain): Same.
+ (compile_offload_image): Same.
+ (compile_images_for_offload_targets): Same.
+ (debug_objcopy): Same.
+ (run_gcc): Same.
+ (main): Same.
+ * opts.c (print_specific_help): Same.
+ (parse_no_sanitize_attribute): Same.
+ (print_help): Same.
+ (handle_param): Same.
+ * plugin.c (add_new_plugin): Same.
+ (parse_plugin_arg_opt): Same.
+ (try_init_one_plugin): Same.
+ * print-rtl.c (debug_bb_n_slim): Quote identifiers, keywords,
+ operators, and types in diagnostics. Correct quoting and spelling
+ issues.
+ * read-rtl-function.c (parse_edge_flag_token): Same.
+ (function_reader::parse_enum_value): Same.
+ * reg-stack.c (check_asm_stack_operands): Same.
+ * regcprop.c (validate_value_data): Same.
+ * sched-rgn.c (make_pass_sched_fusion): Same.
+ * stmt.c (check_unique_operand_names): Same.
+ * targhooks.c (default_target_option_pragma_parse): Same.
+ * tlink.c (recompile_files): Same.
+ * toplev.c (process_options): Same.
+ (do_compile): Same.
+ * trans-mem.c (diagnose_tm_1): Same.
+ (ipa_tm_scan_irr_block): Same.
+ (ipa_tm_diagnose_transaction): Same.
+ * tree-cfg.c (verify_address): Same. Use get_tree_code_name to
+ format a tree code name in a diagnostic.
+ (verify_types_in_gimple_min_lval): Same.
+ (verify_types_in_gimple_reference): Same.
+ (verify_gimple_call): Same.
+ (verify_gimple_assign_unary): Same.
+ (verify_gimple_assign_binary): Same.
+ (verify_gimple_assign_ternary): Same.
+ (verify_gimple_assign_single): Same.
+ (verify_gimple_switch): Same.
+ (verify_gimple_label): Same.
+ (verify_gimple_phi): Same.
+ (verify_gimple_in_seq): Same.
+ (verify_eh_throw_stmt_node): Same.
+ (collect_subblocks): Same.
+ (gimple_verify_flow_info): Same.
+ (do_warn_unused_result): Same.
+ * tree-inline.c (expand_call_inline): Same.
+ * tree-into-ssa.c (update_ssa): Same.
+ * tree.c (tree_int_cst_elt_check_failed): Same.
+ (tree_vec_elt_check_failed): Same.
+ (omp_clause_operand_check_failed): Same.
+ (verify_type_variant): Same.
+ (verify_type): Same.
+ * value-prof.c (verify_histograms): Same.
+ * varasm.c (assemble_start_function): Same.
2019-05-16 Martin Sebor <msebor@redhat.com>
- * config/i386/i386-expand.c (get_element_number): Quote keywords
- and other internal names in diagnostics. Adjust other diagnostic
- formatting issues noted by -Wformat-diag.
- * config/i386/i386-features.c
- (ix86_mangle_function_version_assembler_name): Same.
- * config/i386/i386-options.c (ix86_handle_abi_attribute): Same.
- * config/i386/i386.c (ix86_function_type_abi): Same.
- (ix86_function_ms_hook_prologue): Same.
- (classify_argument): Same.
- (ix86_expand_prologue): Same.
- (ix86_md_asm_adjust): Same.
- (ix86_memmodel_check): Same.
+ * config/i386/i386-expand.c (get_element_number): Quote keywords
+ and other internal names in diagnostics. Adjust other diagnostic
+ formatting issues noted by -Wformat-diag.
+ * config/i386/i386-features.c
+ (ix86_mangle_function_version_assembler_name): Same.
+ * config/i386/i386-options.c (ix86_handle_abi_attribute): Same.
+ * config/i386/i386.c (ix86_function_type_abi): Same.
+ (ix86_function_ms_hook_prologue): Same.
+ (classify_argument): Same.
+ (ix86_expand_prologue): Same.
+ (ix86_md_asm_adjust): Same.
+ (ix86_memmodel_check): Same.
2019-05-17 Dragan Mladjenovic <dmladjenovic@wavecomp.com>
@@ -6543,8 +9877,8 @@ Fix test-suite.
PR target/89952
* config/s390/s390.c (s390_restore_gprs_from_fprs): Restore GPRs
- from FPRs in reverse order. Generate REG_CFA_DEF_CFA note also
- for restored hard frame pointer.
+ from FPRs in reverse order. Generate REG_CFA_DEF_CFA note also
+ for restored hard frame pointer.
(s390_sched_dependencies_evaluation): Implement new target hook.
(TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK): New macro definition.
@@ -6913,7 +10247,7 @@ Fix test-suite.
* config/microblaze/microblaze.c (microblaze_expand_block_move): Treat
size and alignment as unsigned.
-
+
2019-04-15 Richard Biener <rguenther@suse.de>
PR debug/90074
@@ -11901,7 +15235,8 @@ Fix test-suite.
(_mm256_mask_fixupimm_ps): Ditto.
(_mm_mask_fixupimm_pd): Ditto.
(_mm_mask_fixupimm_ps): Ditto.
- * config/i386/i386-builtin-types.def: Add new types and remove useless ones.
+ * config/i386/i386-builtin-types.def: Add new types and remove
+ useless ones.
* config/i386/i386-builtin.def: Update builtin definitions.
* config/i386/i386.c: Handle new builtin types and remove useless ones.
* config/i386/sse.md: Update VFIXUPIMM* patterns.
@@ -12020,10 +15355,12 @@ Fix test-suite.
2019-01-16 Tamar Christina <tamar.christina@arm.com>
- * config/arm/arm-protos.h (neon_vcmla_lane_prepare_operands): Remove patternmode.
+ * config/arm/arm-protos.h (neon_vcmla_lane_prepare_operands):
+ Remove patternmode.
* config/arm/arm.c (neon_vcmla_lane_prepare_operands): Likewise.
- * config/arm/neon.md (neon_vcmla_lane<rot><mode>, neon_vcmla_laneq<rot><mode>,
- neon_vcmlaq_lane<rot><mode>): Remove endianness conversion.
+ * config/arm/neon.md (neon_vcmla_lane<rot><mode>,
+ neon_vcmla_laneq<rot><mode>, neon_vcmlaq_lane<rot><mode>):
+ Remove endianness conversion.
2019-01-16 Martin Liska <mliska@suse.cz>
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 905e21d..0d94c83 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20190703
+20190723
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c28a942..64ac98b 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,2174 @@
+2019-07-23 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch13.adb (Check_Aspect_At_End_Of_Declarations,
+ Freeze_Entity_Checks): Include Aspect_CPU with other aspects
+ whose expresssion may depend on a discriminant, and thus require
+ that components of the type be made visible.
+
+2019-07-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.adb (Convert_And_Check_Range): Add Suppress parameter
+ and pass it in the call to Insert_Actions. Rename local
+ variable.
+ (Generate_Range_Check): Minor comment fixes. Pass Range_Check
+ in the first call to Convert_And_Check_Range and All_Checks in
+ the second call.
+ * exp_ch4.adb (Expand_N_Type_Conversion): Reset the
+ Do_Overflow_Check flag in the float-to-float case too if there
+ is also a range check.
+
+2019-07-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.adb (Activate_Overflow_Check): Remove redundant
+ argument.
+ * exp_ch4.adb (Discrete_Range_Check): Reset the overflow flag.
+ (Expand_N_Type_Conversion): Do not reset it here.
+
+2019-07-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo.adb (List_Component_Layout): Pass Decimal to UI_Write.
+ (Write_Val): Likewise.
+
+2019-07-23 Ed Schonberg <schonberg@adacore.com>
+
+ * aspects.ads: New table Operational_Aspect, used to distinguish
+ between aspects that are view-specific, such as those related to
+ iterators, and representation aspects that apply to all views of
+ a type.
+ * aspects.adb (Find_Aspect): If the aspect being sought is
+ operational, do not ecamine the full view of a private type to
+ retrieve it.
+ * sem_ch5.adb (Analyze_Iterator_Specification): Improve error
+ message when the intended domain of iteration does not implement
+ the required iterator aspects.
+
+2019-07-23 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.ads (Is_Local_Context): New function.
+ * sem_spark.adb (Check_Declaration): Issue errors on violations
+ of SPARK RM 3.10(4)
+ (Process_Path): Do not issue error on borrow/observe during
+ elaboration, as these are caught by the new rule.
+
+2019-07-23 Yannick Moy <moy@adacore.com>
+
+ * exp_ch7.adb (Create_Finalizer): Force finalizer not to be
+ Ghost enabled.
+ * exp_dbug.adb (Get_External_Name): Explain special case of
+ Ghost finalizer.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo.adb (List_Entities): Also list compiled-generated
+ types present as Etype of objects.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sinfo.ads: Update the documentation about the
+ Do_Division_Check, Do_Overflow_Check and Do_Range_Check flags.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Type_Conversion): Beef up comment.
+ (Fixup_Universal_Fixed_Operation): Set the base type instead of
+ the type of the enclosing type conversion on the operation.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.adb (Expand_N_In): Do not suggest the use of attribute
+ 'Valid as a replacement for a range check on a discrete type
+ when the bounds of the range are given by type conversions,
+ because in such a case there are distinct types involved and the
+ subbested attribute replacement would be misplaced.
+
+2019-07-22 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Get_Root_Object, Is_Path_Expression,
+ Is_Subpath_Expression): Add parameter Is_Traversal to adapt
+ these functions to the case of paths returned from a traversal
+ function.
+ (Read_Indexes): Handle the case of an if-expression or
+ case-expression.
+ (Check_Statement): Check Emit_Messages only when issuing an
+ error message. This is important as Emit_Messages may store the
+ information that an error was detected.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.adb (Apply_Type_Conversion_Checks): Do not set
+ Do_Range_Check flag on conversions from fixed-point types
+ either.
+ * exp_attr.adb: Add use and with clause for Expander.
+ (Expand_N_Attribute_Reference) <Fixed_Value, Integer_Value>: Set
+ the Conversion_OK flag and do not generate overflow/range checks
+ manually.
+ * exp_ch4.adb (Expand_N_Qualified_Expression): Remove
+ superfluous clearing of Do_Range_Check flag.
+ (Discrete_Range_Check): New procedure to generate a range check
+ for discrete types.
+ (Real_Range_Check): Remove redundant local variable and adjust.
+ Remove useless shortcut. Clear Do_Range_Check flag on all
+ paths.
+ (Expand_N_Type_Conversion): Remove redundant test on
+ Conversion_OK. Call Discrete_Range_Check to generate range
+ checks on discrete types. Remove obsolete code for
+ float-to-integer conversions. Add code to generate range checks
+ for conversions involving fixed-point types.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sprint.ads: Fix pasto in comment.
+
+2019-07-22 Javier Miranda <miranda@adacore.com>
+
+ * sem_res.adb (Resolve_Actuals): Replace code that displaces the
+ pointer to an allocated object to reference its secondary
+ dispatch table by a type conversion (which takes care of
+ handling all cases).
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sprint.adb (Sprint_Node_Actual)
+ <N_Decimal_Fixed_Point_Definition>: Swap a couple of spaces.
+ (Write_Itype): Minor consistency fixes throughout. Add support
+ for printing ordinary and decimal fixed-point types and
+ subtypes.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_attr.adb (Expand_Loop_Entry_Attribute): Beef up comment.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * libgnat/s-valboo.ads, libgnat/s-valcha.ads,
+ libgnat/s-valdec.ads, libgnat/s-valenu.ads,
+ libgnat/s-valint.ads, libgnat/s-vallld.ads,
+ libgnat/s-vallli.ads, libgnat/s-valllu.ads,
+ libgnat/s-valrea.ads, libgnat/s-valuns.ads,
+ libgnat/s-valwch.ads: Change categorization of packages that
+ implement attribute 'Value from Pure to Preelaborate, to prevent
+ undesirable optimizations when the evaluation of the attribute
+ raises Constraint_Error, but subsequent use of the result of
+ this evsaluation is removed by a subsequent optimization.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_warn.adb (Check_References): Do not emit s warning on a
+ referenced entity with no explicit assignment if the type of the
+ entity has Preelaborable_Initialixation, such as
+ Exception_Occurrence.
+
+2019-07-22 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch4.adb (Size_In_Storage_Elements): Improve the expansion
+ to handle array indexes that are modular type.
+ (Expand_N_Allocator): For 32-bit targets improve the generation
+ of the runtime check associated with large arrays supporting
+ arrays initialized with a qualified expression.
+ * libgnat/s-imenne.adb (Image_Enumeration_8,
+ Image_Enumeration_16, Image_Enumeration_32): Define the index of
+ Index_Table with range Natural'First .. Names'Length since in
+ the worst case all the literals of the enumeration type would be
+ single letter literals and the Table built by the frontend would
+ have as many components as the length of the names string. As a
+ result of this enhancement, the internal tables declared using
+ Index_Table have a length closer to the real needs, thus
+ avoiding the declaration of large arrays on 32-bit CCG targets.
+
+2019-07-22 Yannick Moy <moy@adacore.com>
+
+ * sem_ch3.adb (Constrain_Access): Issue a message about ignored
+ constraint.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch8.adb (End_Use_Type): Reset the In_Use flag on the
+ class-wide type if the type is tagged.
+ (Use_One_Type): Add commentary on the handling of the class-wide
+ type.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * einfo.ads (Is_For_Access_Subtype): Delete.
+ (Set_Is_For_Access_Subtype): Likewise.
+ * einfo.adb (Is_For_Access_Subtype): Likewise.
+ (Set_Is_For_Access_Subtype): Likewise.
+ (Write_Entity_Flags): Do not write Is_For_Access_Subtype.
+ * exp_ch4.adb (Expand_N_Selected_Component): Do not deal with
+ it.
+ * exp_spark.adb (Expand_SPARK_N_Selected_Component): Likewise.
+ * sem_ch4.adb (Analyze_Explicit_Dereference): Likewise.
+ * sem_ch3.adb (Build_Discriminated_Subtype): Do not build a
+ special private subtype for access-to-record subtypes.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch3.adb (Complete_Private_Subtype): Rework the setting of
+ the Etype of the full view for full base types that cannot
+ contain any discriminant. Remove code and comment about it in
+ the main path.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Convert_Bound): Subsidiary of
+ Floating_Point_Type_Declaration, to handle properly range
+ specifications with bounds that may include static constants of
+ a given type rather than real literals.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_aggr.adb (Rewrite_Bound): Be prepared for discriminals
+ too.
+ (Rewrite_Range;): Minor tweak.
+ (Resolve_Record_Aggregate): For a component with default
+ initialization whose expression is an array aggregate, also
+ rewrite the bounds of the component associations, if any.
+
+2019-07-22 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_ch5.adb (Expand_N_Case_Statement): In the case where a
+ case statement is rewritten as an equivalent if statement,
+ inherit the From_Condition_Expression flag from the case
+ statement.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch8.adb (Check_Constrained_Object): Further extend the
+ special optimization to all limited types.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_attr.adb (Expand_N_Attribute_Reference)
+ <Attribute_Enum_Val>: Set No_Truncation on the
+ N_Unchecked_Type_Conversion built around the argument passed to
+ the attribute.
+
+2019-07-22 Nicolas Roche <roche@adacore.com>
+
+ * libgnat/s-valrea.adb (Scan_Real): Ignore non significative
+ digits to avoid converging to infinity in some cases.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnat/g-encstr.adb (Encode_Wide_String): Fix oversight.
+ (Encode_Wide_Wide_String): Likewise.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_warn.adb (Find_Var): Bail out for a function call with an
+ Out or In/Out parameter.
+
+2019-07-22 Nicolas Roche <roche@adacore.com>
+
+ * terminals.c (__gnat_tty_waitpid): Support both blocking and
+ not blocking mode.
+ * libgnat/g-exptty.ads (Is_Process_Running): New function.
+ * libgnat/g-exptty.adb (Close): Don't try to interrupt/terminate
+ a process if it is already dead.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * freeze.adb (Freeze_Fixed_Point_Type): When freezing a
+ fixed-point subtype, check whether the parent type declarastion
+ includes an aspect specification for the 'Small type attribute,
+ and inherit the specified value.
+
+2019-07-22 Javier Miranda <miranda@adacore.com>
+
+ * freeze.adb (Freeze_Subprogram): Check that C++ constructors
+ must have external or link name.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_res.adb (Resolve_Selected_Component): If the prefix has a
+ deferred reference, generate the correct reference now, to
+ indicate that the previous assignment is used. This prevents
+ spurious warnings on useless assignments when compiling with all
+ warnings enabled. when there is a subsequent call in the same
+ stqtement list, in which the prefix of the selected component is
+ the actual for an out parameter.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_attr.adb (Expand_Loop_Entry_Attribute): Copy the condition
+ of a while loop instead of simply relocating it.
+
+2019-07-18 Arnaud Charlet <charlet@adacore.com>
+
+ * Makefile.rtl, expect.c, env.c, aux-io.c, mkdir.c, initialize.c,
+ cstreams.c, raise.c, tracebak.c, adadecode.c, init.c, raise-gcc.c,
+ argv.c, adaint.c, adaint.h, ctrl_c.c, sysdep.c, rtinit.c, cio.c,
+ seh_init.c, exit.c, targext.c: Introduce a "STANDALONE" mode where C
+ runtime files do not have any dependency on GCC include files.
+ Remove unnecessary includes.
+ Remove remaining references to VMS in runtime C file.
+ * runtime.h: new File.
+
+2019-07-13 Andreas Schwab <schwab@linux-m68k.org>
+
+ * Makefile.rtl: Use g-sercom__linux.adb for all linuxes.
+
+2019-07-11 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-writ.adb (Ensure_System_Dependency,
+ Up_To_Date_ALI_File_Exists, Write_ALI): Replace low-level access
+ to table with a high-level query.
+
+2019-07-11 Piotr Trojanek <trojanek@adacore.com>
+
+ * checks.adb: Fix typo in comment.
+ * sem.adb (Semantics): Avoid repeated calls to
+ In_Extended_Main_Source_Unit by reusing an already-cached
+ result.
+ * sem_util.adb (First_Global): Fix style.
+
+2019-07-11 Yannick Moy <moy@adacore.com>
+
+ * sem_res.adb (Resolve_Call): Do not perform dimensionality
+ checking on inlined bodies.
+
+2019-07-11 Yannick Moy <moy@adacore.com>
+
+ * debug.adb: Flip meaning of debug switch -gnatdF.
+
+2019-07-11 Yannick Moy <moy@adacore.com>
+
+ * sem_eval.adb (Is_Same_Value): Add special case for rewritten
+ Loop_Entry attribute.
+
+2019-07-11 Claire Dross <dross@adacore.com>
+
+ * gnat1drv.adb: SPARK checking rules for pointer aliasing are
+ moved to GNATprove backend.
+ * sem_spark.ads, sem_spark.adb (Sem_SPARK): Is now a generic
+ unit. Takes as parameters:
+ - Retysp which is used to query the most underlying type
+ visible in SPARK. We do not introduce aliasing checks for
+ types which are not visibly deep.
+ - Component_Is_Visible_In_SPARK is used to avoid doing pointer
+ aliasing checks on components which are not visible in SPARK.
+ - Emit_Messages returns True in the second phase of SPARK
+ analysis. Error messages for failed aliasing checks are only
+ output in this case.
+ Additionally, errors on constructs not supported in SPARK are
+ removed as duplicates of marking errors. Components are stored
+ in the permission map using their original component to avoid
+ inconsistencies between components of different views of the
+ same type.
+ (Check_Expression): Handle delta constraints.
+ (Is_Deep): Exported so that we can check for SPARK restrictions
+ on deep types inside SPARK semantic checkings.
+ (Is_Traversal_Function): Exported so that we can check for SPARK
+ restrictions on traversal functions inside SPARK semantic
+ checkings.
+ (Check_Call_Statement, Read_Indexes): Check wether we are
+ dealing with a subprogram pointer type before querying called
+ entity.
+ (Is_Subpath_Expression): Image attribute can appear inside a
+ path.
+ (Check_Loop_Statement): Correct order of statements in the loop.
+ (Check_Node): Ignore raise nodes.
+ (Check_Statement): Use Last_Non_Pragma to get the object
+ declaration in an extended return statement.
+
+2019-07-11 Patrick Bernardi <bernardi@adacore.com>
+
+ * bindgen.adb (Gen_Main): Do not generate a reference to
+ Ada_Main_Program_Name when the Minimal_Binder flag is set.
+ (Gen_Output_File_Ada): Do not output GNAT_Version and
+ Ada_Main_Program_Name info if Minimal_Binder flag is set.
+ * bindusg.adb: Add documentation for new -minimal switch.
+ * gnatbind.adb (Scan_Bind_Arg): Scan -minimal switch.
+ * opt.ads: Add new global flag Minimal_Binder to indicate if the
+ binder should not produce global variables.
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Update documentation with new binder -minimal switch.
+ * gnat_ugn.texi: Regenerate.
+
+2019-07-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * Makefile.rtl: Add warning note about compilation flags and
+ capitalize.
+
+2019-07-11 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch9.adb (Expand_N_Protected_Type_Declaaration): New
+ subsidiary routine Replace_Access_Definition, to handle properly
+ a protected type PT one of whose private components is of type
+ access PT.
+
+2019-07-11 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-socket.ads (Level_Type): Add enumerators for
+ IP_Protocol_For_ICMP, IP_Protocol_For_IGMP,
+ IP_Protocol_For_RAW_Level.
+ * libgnat/g-socket.adb (Levels): Handle them.
+ * s-oscons-tmplt.c: Import socket protocols defined in
+ netinet/in.h.
+
+2019-07-11 Claire Dross <dross@adacore.com>
+
+ * libgnat/a-cfhama.adb, libgnat/a-cfhase.adb (Free): Do not
+ reset the Has_Element flag if no element is freed.
+
+2019-07-11 Arnaud Charlet <charlet@adacore.com>
+
+ * errno.c: Remove obsolete support for MaRTE OS.
+
+2019-07-11 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Type_Conversion): If a predicate check
+ is generated, analyze it with range check suppressed, because
+ that check has been previously applied.
+ * exp_ch5.adb (Expand_N_Assignment_Statement): If the RHS is a
+ type conversion to the type of the LHS, do not apply a predicate
+ check to the RHS because it will have been generated already
+ during its expansion.
+ * exp_ch6.adb (Can_Fold_Predicate_Call): Extend processing to
+ handle a predicate check on a constant entity whose value is
+ static.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo.adb: Remove the documentation of switch -d_N because it
+ is no longer in use.
+ * bindo-graphs.ads, bindo-graphs.adb (Is_Spec_Before_Body_Edge):
+ New routine.
+ * bindo-writers.adb (Write_Dependency_Edge): Add the missing
+ case of a spec-before-body edge.
+
+2019-07-11 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-socket.ads (Mode_Type): Add a Socket_Raw enumerator.
+ * libgnat/g-socket.adb (Modes): Handle Socket_Raw.
+
+2019-07-11 Justin Squirek <squirek@adacore.com>
+
+ * exp_ch9.adb (Build_Private_Protected_Declaration): Add
+ exception for the moving of pragmas to internally generated
+ specs for pragma Unreferenced.
+
+2019-07-11 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Fix inconsistent
+ documentation for gnatmetric.
+ * gnat_ugn.texi: Regenerate.
+
+2019-07-11 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Document gnatpp's
+ --spaces-only switch.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_util.adb (Null_Status): Assume that an erroneous construct
+ has an undefined null status.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * checks.adb, exp_ch6.adb, gnat1drv.adb, sem_aux.adb,
+ sem_ch2.adb, sem_ch8.adb, sem_res.adb: Minor reformatting.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_ch8.adb (Analyze_Object_Renaming): Obtain the object being
+ renamed using routine Get_Object_Name which takes care of
+ various name forms.
+ (Get_Object_Name): New routine.
+
+2019-07-11 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch6.adb (Can_Fold_Predicate_Call): New function,
+ subsidiary of Expand_Call_Helper, to compute statically a
+ predicate check when the argument is a static integer.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_res.adb (Resolve_Op_Not): Do not rewrite an equality
+ operator into a function call when the operator is intrinsic.
+
+2019-07-11 Thomas Quinot <quinot@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma, case pragma Check): Do not call
+ Set_SCO_Pragma_Enabled for the dynamic predicate case.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_util.ads, exp_util.adb (Needs_Finalization): Move to
+ Sem_Util.
+ * sem_ch9.adb (Analyze_Protected_Definition): Code cleanup. Mark
+ the protected type as having controlled components when it
+ contains at least one such component.
+ * sem_util.ads, sem_util.adb (Needs_Finalization): New
+ function.
+
+2019-07-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * alloc.ads (Rep_JSON_Table_Initial): New constant.
+ (Rep_JSON_Table_Increment): Likewise.
+ * debug.adb: Document -gnatd_j switch.
+ * gcc-interface/Make-lang.in (GNAT_ADA_OBJS): Add
+ repinfo-input.o.
+ * gnat1drv.adb: Add with clause for Repinfo.Input.
+ Add with and use clauses for Sinput.
+ (Read_JSON_Files_For_Repinfo): New procedure.
+ (Gnat1drv1): Deal with -gnatd_j switch.
+ * repinfo-input.ad[sb]: New unit.
+ * snames.ads-tmpl (Name_Discriminant): New constant.
+ (Name_Operands): Likewise.
+
+2019-07-11 Justin Squirek <squirek@adacore.com>
+
+ * checks.adb (Apply_Accessibility_Check): Add check for constant
+ folded conditions on accessibility checks.
+
+2019-07-11 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnarl/g-thread.ads, libgnarl/g-thread.adb (Get_Thread):
+ Update comments. Add new version taking a Task_Id.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo.adb: Update the section of switches and debugging
+ elaboration issues.
+ * bindo.ads: Add type Elaboration_Phase.
+ * bindo-augmentors.adb: Add use clause for
+ Bindo.Writers.Phase_Writers.
+ (Augment_Library_Graph): Signal the start and end of the
+ aubmentation phase.
+ * bindo-builders.adb: Add with and use clause for Bindo.Writers.
+ Add use clause for Bindo.Writers.Phase_Writers.
+ (Build_Invocation_Graph): Signal the start and end of the
+ invocation graph construction phase.
+ (Build_Library_Graph): Signal the start and end of the library
+ graph construction phase.
+ * bindo-diagnostics.adb: Add use clause for
+ Bindo.Writers.Phase_Writers.
+ (Diagnose_Cycle): Signal the start and end of the cycle
+ diagnostic phase.
+ * bindo-elaborators.adb: Add use clause for
+ Bindo.Writers.Phase_Writers.
+ (Elaborate_Units): Signal the start and end of the unit
+ elaboration phase.
+ * bindo-graphs.adb: Add use clause for
+ Bindo.Writers.Phase_Writers.
+ (Find_Components): Signal the start and end of the component
+ discovery phase.
+ (Find_Cycles): Signal the start and end of the cycle discovery
+ phase.
+ * bindo-units.adb: Add with and use clause for Bindo.Writers.
+ Add use clause for Bindo.Writers.Phase_Writers.
+ (Collect_Elaborable_Units): Signal the start and end of the unit
+ collection phase.
+ * bindo-validators.adb: Add with and use clause for
+ Bindo.Writers. Add use clause for Bindo.Writers.Phase_Writers.
+ (Validate_Cycles, Validate_Elaboration_Order,
+ Validate_Invocation_Graph, Validate_Library_Graph): Signal the
+ start and end of the libray graph validation phase.
+ * bindo-writers.ads, bindo-writers.adb: Add new nested package
+ Phase_Writers.
+ * debug.adb: Update the documentation of switch d_S.
+
+2019-07-11 Yannick Moy <moy@adacore.com>
+
+ * sem_res.adb (Check_Argument_Order): Special case calls to
+ operators.
+
+2019-07-10 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/s-ststop.adb: Remove System.Strings.Stream_Ops
+ dependence on System.Streams.Stream_IO.
+
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch2.adb (Analyze_Integer_Literal): Preserve the type of
+ the literal if prior analysis determined that its type is a
+ modular integer type.
+
+2019-07-10 Doug Rupp <rupp@adacore.com>
+
+ * init.c: Do not attempt to re-arm guard page on x86_64-vx7(r2).
+
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch8.adb (Check_Constrained_Object): A record that is
+ limited because of the presence of a limited component is
+ constrained, and no subtype indiciation needs to be created for
+ it, just as is the case for declared limited records.
+
+2019-07-10 Yannick Moy <moy@adacore.com>
+
+ * sem_aux.adb, sem_aux.ads (Is_Protected_Operation): New
+ function to determine if a subprogram is protected.
+ * sem_spark.adb (Setup_Protected_Components): New procedure to
+ add protected components to the environment.
+ (Check_Callable_Body): Call the new Setup_Protected_Components.
+ (Check_Package_Spec): Merge local environment with enclosing one
+ when done.
+
+2019-07-10 Claire Dross <dross@adacore.com>
+
+ * sem_spark.adb (Check_Expression): Allow digits constraints as
+ input.
+ (Illegal_Global_Usage): Pass in the entity.
+ (Is_Subpath_Expression): New function to allow different nodes
+ as inner parts of a path expression.
+ (Read_Indexes): Allow concatenation and aggregates with box
+ expressions. Allow attributes Update and Loop_Entry.
+ (Check_Expression): Allow richer membership test.
+ (Check_Node): Ignore bodies of generics.
+ (Get_Root_Object): Allow concatenation and attributes.
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_ch6.adb (Check_Discriminant_Conformance): Use Find_Type to
+ discover the type of a full view discriminant.
+
+2019-07-10 Arnaud Charlet <charlet@adacore.com>
+
+ * doc/gnat_ugn/gnat_and_program_execution.rst: Improve gnatmem's
+ doc for the depth switch.
+
+2019-07-10 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Document gnatpp's
+ --source-line-breaks switch.
+
+2019-07-10 Justin Squirek <squirek@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_attributes.rst: Add mention
+ of 'Image attribute with 'Img's entry to mention additional
+ added 2012 usage of Obj'Image.
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Correct
+ mispelling of Async_Writers.
+ * gnat_rm.texi: Regenerate.
+ * sem_prag.adb (Analyze_Pragma): Correct mispelling of
+ Async_Writers.
+ * sem_util.adb (State_Has_Enabled_Property): Correct mispelling
+ of Async_Writers.
+
+2019-07-10 Simon Buist <buist@adacore.com>
+
+ * sem_util.ads (Child_Prefix): New constant.
+ * sem_util.adb (Unique_Name): Add a special prefix to child
+ units that have a nested subprogram or package.
+
+2019-07-10 Arnaud Charlet <charlet@adacore.com>
+
+ * sfn_scan.adb (Scan_SFN_Pragmas): Add pragma Assert.
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_ch3.adb (Check_Nonoverridable_Aspects): Correct the
+ spelling in certain error messages.
+ (Check_Pragma_Implemented): Correct the spelling in certain
+ error messages.
+
+2019-07-10 Eric Botcazou <ebotcazou@adacore.com>
+
+ * Makefile.rtl (GNATRTL_NONTASKING_OBJS): Add g-brapre.
+ * libgnat/g-brapre.ads: New package specification.
+ * doc/gnat_rm/the_gnat_library.rst: Document it.
+ * gnat_rm.texi: Regenerate.
+
+2019-07-10 Yannick Moy <moy@adacore.com>
+
+ * osint-c.adb (Set_File_Name): Always add extension for multiple
+ units per file mode.
+
+2019-07-10 Corentin Gay <gay@adacore.com>
+
+ * sysdep.c: Put include directive for 'vxWorks.h' before any
+ other VxWorks headers.
+
+2019-07-10 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_attributes.rst
+ (Scalar_Storage_Order): Minor tweaks. Add note about debuggers.
+ * gnat_rm.texi: Regenerate.
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Case_Expression): Mark the generated
+ assignments to the temporary result as being OK because the
+ expansion of case expressions is correct by construction.
+ (Is_Copy_Type): Update the predicate to match the comment
+ within.
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo-graphs.adb, bindo.adb, debug.adb, exp_ch6.adb,
+ sem_ch10.adb, sem_ch13.adb, sem_ch3.adb, sem_ch4.adb,
+ sem_ch6.adb, sem_ch7.adb, sem_res.adb, sem_spark.adb,
+ sem_util.adb, warnsw.ads: Minor reformatting.
+
+2019-07-10 Joffrey Huguet <huguet@adacore.com>
+
+ * libgnat/a-strbou.ads, libgnat/a-strfix.ads,
+ libgnat/a-strunb.ads, libgnat/a-strunb__shared.ads: Add global
+ contracts, contract cases, preconditions and postconditions to
+ procedures and functions.
+
+2019-07-10 Doug Rupp <rupp@adacore.com>
+
+ * sysdep.c (__gnat_is_file_not_found_error): Reformulate to also
+ work for vxworks7r2 SR0610.
+
+2019-07-10 Doug Rupp <rupp@adacore.com>
+
+ * env.c (__gnat_environ): Reformulate to also work for
+ vxworks7r2 SR0610.
+
+2019-07-10 Patrick Bernardi <bernardi@adacore.com>
+
+ * Makefile.rtl: Handle vxworks7r2 ppc target
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo.adb: Update the section on switches.
+ * bindo-graphs.adb
+ (Add_Cycle, Add_Vertex_And_Complement): Remove.
+ (Create): The graph no longer needs a set of recorded cycles
+ because the cycles are not rediscovered in permuted forms.
+ (Cycle_End_Vertices): New routine.
+ (Destroy): The graph no longer needs a set of recorded cycles
+ because the cycles are not rediscovered in permuted forms.
+ (Destroy_Library_Graph_Vertex): Move to the library level.
+ (Find_All_Cycles_Through_Vertex, Find_All_Cycles_With_Edge):
+ Remove.
+ (Find_Cycles_From_Successor, Find_Cycles_From_Vertex,
+ Find_Cycles_In_Component, Has_Elaborate_All_Edge): New routines.
+ (Insert_And_Sort): Remove.
+ (Is_Elaborate_Body_Edge): Use predicate
+ Is_Vertex_With_Elaborate_Body.
+ (Is_Recorded_Cycle): Remove.
+ (Is_Vertex_With_Elaborate_Body): New routine.
+ (Normalize_And_Add_Cycle): Remove.
+ (Precedence): Rename to xxx_Precedence, where xxx relates to the
+ input. These versions better reflect the desired input
+ precedence.
+ (Record_Cycle): New routine.
+ (Remove_Vertex_And_Complement, Set_Is_Recorded_Cycle): Remove.
+ (Trace_xxx): Update all versions to use debug switch -d_t.
+ (Trace_Component): New routine.
+ (Trace_Eol): Removed.
+ (Trace_Vertex): Do not output the component as this information
+ is already available when the component is traced.
+ (Unvisit, Visit): New routine.
+ * bindo-graphs.ads: Add new instance LGV_Lists. Remove instance
+ RC_Sets. Update the structure of type Library_Graph_Attributes
+ to remove the set of recorded cycles.
+ (Destroy_Library_Graph_Vertex): Move to the library level.
+ * bindo-writers.adb (Write_Component_Vertices): Output
+ information about the number of vertices.
+ * debug.adb: Document the use of binder switch -d_t. Update the
+ use of binder switch -d_T.
+
+2019-07-10 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Get_Root_Object): Replace precondition by error
+ message.
+ (Read_Indexes): Replace precondition by error message.
+ (Check_Callable_Body): Check only traversal function returns an
+ anonymous access type.
+ (Check_Expression): Issue error on unexpected expression as
+ path.
+ * sem_util.adb (First_Global): Fix access to global on
+ entry/task.
+
+2019-07-10 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch6.adb (Is_Class_Wide_Interface_Type): New subprogram.
+ (Expand_Call_Helper): Handle non-limited views when we check if
+ any formal is a class-wide interface type.
+ * exp_disp.adb (Expand_Interface_Actuals): Handle non-limited
+ views when we look for interface type formals to force "this"
+ displacement.
+
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_res.adb (Resolve_Equality_Op): Do not replace the resolved
+ operator by its alias if expander is not active, because the
+ operand type may not be frozen yet and its inherited operations
+ have not yet been created.
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo-elaborators.adb (Elaborate_Units): Set attribute
+ Elab_Position of all elaborated units.
+ (Set_Unit_Elaboration_Positions): New routine.
+
+2019-07-10 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_util.adb: Reformatting and a typo fix.
+
+2019-07-10 Yannick Moy <moy@adacore.com>
+
+ * exp_util.adb (Remove_Side_Effects): Prefer renamings for
+ objects of possible owning type in GNATprove mode.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Analyze_Object_Declaration): If the object type
+ is a composite type that has a dynamic predicate and, the
+ expression in the declaration is an aggregate, the generated
+ predicate check must appear after the expanded code for the
+ aggregate, which will appear after the rewritten object
+ declarastion.
+
+2019-07-09 Justin Squirek <squirek@adacore.com>
+
+ * sem_eval.adb (Expr_Value_E): Add conditional to correctly
+ handle constant enumerated character types.
+
+2019-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * libgnarl/s-osinte__mingw.ads (CRITICAL_SECTION): Use proper
+ type for SpinCount component.
+
+2019-07-09 Justin Squirek <squirek@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Allocator): Add conditional to detect
+ the presence of anoymous access type allocators and issue a
+ warning if the appropriate warning flag is enabled.
+ * warnsw.ads: Add new warning flag for anonymous allocators
+ * warnsw.adb (All_Warnings, Restore_Warnings, Save_Warnings,
+ Set_Underscore_Warning_Switch): Register new flags.
+ (WA_Warnings): Register new flag as an "all warnings" switch
+ * usage.adb,
+ doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Document new warning switches -gnatw_a and -gnatw_A.
+ * gnat_ugn.texi: Regenerate.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch4.adb (Diagnose_Call): Improve error recovery when a
+ local subprogram name hides a possible candidate name declared
+ in a child package in the context of the current unit.
+ * sem_ch6.adb (Process_Formals): Protect against malformed
+ formal types when the parameter type does not denote an entity.
+
+2019-07-09 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo-augmentors.adb (Visit_Elaboration_Root): Do not start a
+ DFS from an elaboration root whose corresponding unit lacks
+ elaboration code. This behavior mimics that of the old
+ elaboration order mechanism.
+ * bindo-graphs.adb (Find_All_Cycles_Through_Vertex): Move the
+ vertex tracing within the functional branches of the routine.
+ This prevents spurious trace output.
+ (Has_No_Elaboration_Code): New routine.
+ (Trace_Cycle, Trace_Edge): Update the various Ids to use the
+ "standard" trace format.
+ * bindo-graphs.ads (Has_No_Elaboration_Code): New routine.
+ * bindo-units.ads, bindo-units.adb (Has_No_Elaboration_Code):
+ New routine.
+
+2019-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * ali.ads, bindo-graphs.adb, bindo-validators.adb, clean.adb,
+ doc/gnat_ugn/elaboration_order_handling_in_gnat.rst, einfo.ads,
+ exp_aggr.adb, exp_ch13.adb, exp_ch4.adb, exp_ch5.adb,
+ exp_ch6.adb, exp_ch7.adb, exp_ch9.adb, exp_pakd.adb,
+ fname-uf.ads, gnatlink.adb, inline.adb, lib.ads, make.adb,
+ namet.ads, opt.ads, par-ch4.adb, par-ch6.adb, par-labl.adb,
+ prep.adb, sem_aggr.adb, sem_ch13.adb, sem_ch4.adb, sem_ch5.adb,
+ sem_ch6.adb, sem_ch6.ads, sem_ch7.adb, sem_ch8.adb, sem_dim.adb,
+ sem_disp.adb, sem_prag.adb, sem_res.adb, sem_warn.adb,
+ sinfo.ads: Replace ". " with ". ". Minor reformatting and typo
+ corrections.
+ * gnat_ugn.texi: Generate.
+
+2019-07-09 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo.ads: Move type Precedence_Kind from the private to the
+ visible part of the unit.
+ * bindo-augmentors.adb: Remove the use of global data as it is
+ bad practice.
+ (Augment_Library_Graph): Update the parameter profile.
+ (Is_Visited, Set_Is_Visited): Remove.
+ (Visit_Elaboration_Root, Visit_Elaboration_Roots): Update the
+ parameter profile and comment on usage.
+ (Visit_Vertex): Likewise. Also keep track of which invocation
+ edge activates a task.
+ * bindo-augmentors.ads (Augment_Library_Graph): Update the
+ parameter profile and comment on usage.
+ * bindo-builders.adb (Create_Forced_Edge,
+ Create_Spec_And_Body_Edge, Create_With_Edge): Update the call to
+ Add_Edge.
+ * bindo-diagnostics.adb: Add with end use clauses for Restrict
+ and Rident.
+ (Output_Dynamic_Model_Suggestions): Remove.
+ (Output_Invocation_Related_Suggestions): New routine.
+ (Output_Suggestions): Output all invocation-related suggestions
+ together.
+ * bindo-elaborators.adb: Remove types Comparator_Ptr and
+ Predicate_Ptr.
+ (Find_Best_Vertex): Update the parameter profile.
+ * bindo-graphs.adb (Activates_Task): New routine.
+ (Add_Body_Before_Spec_Edge): Update the call to
+ Add_Edge_With_Return.
+ (Add_Edge): Update the parameter profile and the call to
+ Add_Edge_With_Return.
+ (Add_Edge_With_Return): Update the parameter profile and comment
+ on usage.
+ (At_Least_One_Edge_Satisfies): New routine.
+ (Contains_Elaborate_All_Edge): Reimplement.
+ (Contains_Static_Successor_Edge, Contains_Task_Activation): New
+ routine.
+ (Contains_Weak_Static_Successor): Remove.
+ (Is_Static_Successor_Edge): New routine.
+ * bindo-graphs.ads: Add types LGE_Predicate_Ptr,
+ LGV_Comparator_Ptr, and LGV_Predicate_Ptr. Update type
+ Library_Graph_Edge_Attributes to capture whether an invocation
+ edge activates a task. Update the value of
+ No_Library_Graph_Edge_Attributes.
+ (Activates_Task): Update the parameter profile and comment on
+ usage.
+ (Contains_Static_Successor_Edge, Contains_Task_Activation): New
+ routines.
+ (Contains_Weak_Static_Successor): Remove.
+ * doc/gnat_ugn/elaboration_order_handling_in_gnat.rst:
+ Update the documentation to reflect the new task-related advice.
+ * gnat_ugn.texi: Regenerate.
+
+2019-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * exp_util.adb (Containing_Package_With_Ext_Axioms): Replace
+ low-level Ekind test with a high-level wrapper.
+
+2019-07-09 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnat/s-memory.adb: Disable calls to Abort defer/undefer
+ when ZCX_By_Default.
+
+2019-07-09 Javier Miranda <miranda@adacore.com>
+
+ * sem_ch13.adb (Rep_Item_Too_Early): Representation clauses are
+ not allowed for a derivation of a generic type. Extend the
+ current test to check that none of the parents is a generic
+ type.
+
+2019-07-09 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch9.adb, exp_util.adb, repinfo.adb, sem_ch12.adb,
+ sem_prag.adb, sem_res.adb, sem_spark.adb, sem_util.adb: Minor
+ reformatting.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_res.adb (Resolve_Equality_Op): If the node was overloaded,
+ set properly the entity to which the node has been resolved. The
+ original entity is the first one found during analysis, and is
+ not necessarily the resolved one.
+ (Resolve_Op_Not): If the argument of negation is an overloaded
+ equality operation, call its resolution directly given that the
+ context type does not participate in overload resolution.
+
+2019-07-09 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo.adb: Remove with and use clauses for Debug. Add with
+ and use clauses for Opt.
+ (Find_Elaboration_Order): Enable the v4.0 elaboration order. The
+ v3.0 mechanism is now available under binder switch -H.
+ * bindusg.adb (Display): Enable switch -H.
+ * debug.adb: Free compiler switch -gnatd_G. Free binder switch
+ -d_N.
+ * sem_elab.adb: Update the section on switches to remove
+ -gnatd_G.
+ (Invocation_Graph_Recording_OK): The invocation graph is now
+ unconditionally recorded in ALI files.
+ * switch-b.adb (Scan_Binder_Switches): Scan switch -H.
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Update the documentation on compiler switches related to
+ elaboration. Update the documentation on binder switches to
+ include switch -H.
+ * doc/gnat_ugn/elaboration_order_handling_in_gnat.rst: Update
+ the documentation on elaboration order handling in GNAT.
+ * gnat_ugn.texi: Regenerate.
+
+2019-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo.adb (List_Entities): Disregard formals altogether.
+ (List_Name): Properly escape the double quote in the JSON
+ output.
+
+2019-07-09 Javier Miranda <miranda@adacore.com>
+
+ * exp_util.adb (Remove_Side_Effects): Preserve the
+ Do_Range_Check flag.
+
+2019-07-09 Yannick Moy <moy@adacore.com>
+
+ * sinfo.ads: Refine comment for Do_Range_Check.
+
+2019-07-09 Yannick Moy <moy@adacore.com>
+
+ * exp_spark.adb (Expand_SPARK_N_Attribute_Reference): Expand
+ attribute reference on Enum_Rep.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch12.adb (Instantiate_Formal_Package): Handle properly the
+ case where the actual for a formal package in an instance is the
+ current instance of an enclosing generic package.
+ (Check_Formal_Packages): If the formal package declaration is
+ box-initialized or lacks associations altogether, no internal
+ instance was created to verify conformance, and there is no
+ validating package to remove from tree.
+
+2019-07-09 Yannick Moy <moy@adacore.com>
+
+ * freeze.adb (Build_Renamed_Body): Do not set body to inline in
+ GNATprove mode.
+
+2019-07-09 Yannick Moy <moy@adacore.com>
+
+ * exp_util.adb (Expand_Subtype_From_Expr): Still expand the type
+ of static expressions in GNATprove_Mode.
+ * sem_ch3.adb (Analyze_Object_Declaration): Remove obsolete
+ special case for GNATprove_Mode.
+
+2019-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * doc/gnat_rm/the_gnat_library.rst,
+ doc/gnat_ugn/building_executable_programs_with_gnat.rst,
+ erroutc.adb, libgnat/g-comlin.adb, libgnat/g-comlin.ads,
+ libgnat/g-regexp.ads, libgnat/g-regpat.ads,
+ libgnat/g-spipat.ads, libgnat/s-os_lib.ads,
+ libgnat/s-regexp.ads: Reword "wild card" to "wildcard".
+ * gnat_rm.texi, gnat_ugn.texi: Regenerate.
+
+2019-07-09 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Check_Expression): Handle correctly implicit
+ assignments as part of allocators and (extension) aggregates.
+ (Get_Root_Object): Adapt for new path expressions.
+ (Is_Path_Expression): Return True for (extension) aggregate.
+
+2019-07-09 Piotr Trojanek <trojanek@adacore.com>
+
+ * einfo.ads: Fix a typo.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.adb (Scope_Within_Or_Same): Handle properly task
+ bodies and protected bodies, so that local variables within have
+ their proper scopes after these constructs have been rewritten
+ during expansion. This patch resembles but is not identical to
+ the code in Scope_Within.
+
+2019-07-09 Arnaud Charlet <charlet@adacore.com>
+
+ * gnat1drv.adb (Adjust_Global_Switches): Set
+ Dynamic_Elaboration_Checks to True in CodePeer mode.
+
+2019-07-09 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Get_Perm_Or_Tree): Issue an error when
+ encountering unknown global variable.
+
+2019-07-09 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Check_Expression): Change signature to take an
+ Extended_Checking_Mode, for handling read permission checking of
+ sub-expressions in an assignment.
+ (Check_Parameter_Or_Global): Adapt to new behavior of
+ Check_Expression for mode Assign.
+ (Check_Safe_Pointers): Do not analyze generic bodies.
+ (Check_Assignment): Separate checking of the target of an
+ assignment.
+
+2019-07-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo.ads (JSON format): Adjust.
+ * repinfo.adb (Need_Blank_Line): Rename to...
+ (Need_Separator): ...this.
+ (Blank_Line): Rename to...
+ (Write_Separator): ...this and add JSON specific handling.
+ (List_Array_Info): Adjust to above renaming.
+ (List_Object_Info): Likewise.
+ (List_Record_Info): Likewise.
+ (List_Subprogram_Info): Likewise.
+ (List_Type_Info): Likewise.
+ (List_Entities): Do not set Need_Blank_Line.
+ (List_Rep_Info): Set Need_Separator and add JSON specific
+ handling. Output a single JSON stream in the normal case.
+
+2019-07-09 Arnaud Charlet <charlet@adacore.com>
+
+ * doc/gnat_ugn/the_gnat_compilation_model.rst: Update doc on
+ -fdump-ada-spec now that we generate Ada 2012.
+ * gnat_ugn.texi: Regenerate.
+
+2019-07-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo.adb (List_Common_Type_Info): New procedure extracted
+ from...
+ (List_Type_Info): ...here. Call it for the common information,
+ start with a blank line and output the linker section at the
+ end, if any.
+ (List_Mechanisms): Rename to...
+ (List_Subprogram_Info): ...this.
+ (List_Array_Info): Call List_Common_Type_Info.
+ (List_Entities): Adjust to above change and renaming.
+ (List_Record_Info): Call List_Common_Type_Info.
+
+2019-07-08 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-sercom.ads
+ (Serial_Port_Descriptor): New type.
+ (Serial_Port): Add a comment, make it hold a
+ Serial_Port_Descriptor.
+ (To_Ada, To_C): New procedures.
+ (Port_Data, Port_Data_Access): Remove types.
+ * libgnat/g-sercom.adb (To_Ada): New stub.
+ * libgnat/g-sercom__linux.adb, libgnat/g-sercom__mingw.adb:
+ Update implementations accordingly.
+ * s-oscons-tmplt.c: Bind Serial_Port_Descriptor to
+ System.Win32.HANDLE on Windows, and to Interfaces.C.int on
+ Linux. Add "Interfaces.C." prefix for other basic integer type
+ bindings.
+ * xoscons.adb (Output_Info): Remove the "Interfaces.C." prefix
+ for subtypes generation.
+
+2019-07-08 Arnaud Charlet <charlet@adacore.com>
+
+ * doc/gnat_rm/standard_and_implementation_defined_restrictions.rst:
+ Update documentation on No_Exceptions restriction.
+ * gnat_rm.texi: Regenerate.
+
+2019-07-08 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/s-os_lib.adb: Do not call __gnat_kill for Invalid_Pid.
+
+2019-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Enclosing_Package_Or_Subprogram): Do not expect
+ package and subprogram bodies.
+
+2019-07-08 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Remove documentation
+ of ignored GNATpp switch.
+
+2019-07-08 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst:
+ Update the documentation of pragma Initialize_Scalars.
+ * gnat_rm.texi: Regenerate.
+
+2019-07-08 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch4.adb (Tagged_Membership): Fix regression silently
+ introduced in r260738 that erroneouslusy causes the evaluation
+ to True of the membership test when the left operand of the
+ membership test is a class-wide interface object and the right
+ operand is a type that implements such interface type.
+
+2019-07-08 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_ch13.adb (Analyze_Attribute_Definition_Clause): Do not
+ register an address clause when its prefix denotes a generic
+ formal object.
+
+2019-07-08 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo-diagnostics.adb (Diagnose_Cycle): Capture the presence
+ of an Elaborate_All edge before iterating over the edges of the
+ cycle.
+ (Output_Elaborate_Body_Transition): Update the parameter profile
+ and the comment on usage. Add a missing case where the edge is
+ within the context of an Elaborate_All.
+ (Output_Transition): Update the call to
+ Output_Elaborate_Body_Transition.
+ * bindo-graphs.ads, bindo-graphs.adb
+ (Contains_Elaborate_All_Edge): New routine.
+
+2019-07-08 Piotr Trojanek <trojanek@adacore.com>
+
+ * lib-xref-spark_specific.adb (Create_Heap): Set dummy Etype for
+ the fake __HEAP entity.
+
+2019-07-08 Daniel Mercier <mercier@adacore.com>
+
+ * gnat1drv.adb: Suppress warnings on memory representation in
+ CodePeer compiler mode.
+
+2019-07-08 Nicolas Roche <roche@adacore.com>
+
+ * rtinit.c (__gnat_runtime_initialize): Remove dependency on
+ CommandLineToArgvW.
+
+2019-07-08 Doug Rupp <rupp@adacore.com>
+
+ * Makefile.rtl: Handle vxworks7r2 in x86_64 and x86 vxworks7.
+
+2019-07-08 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * Makefile.rtl: Use g-sercom__linux.adb for all linuxes.
+
+2019-07-08 Yannick Moy <moy@adacore.com>
+
+ * expander.adb (Expand): Do not reset Analyzed flag always.
+ * sem_eval.adb (Fold_Ureal): Mark node as analyzed.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch9.adb (Expand_N_Timed_Entry_Call): Do not insert twice
+ the assignment statement that computes the delay value, to
+ prevent improper tree sharing when the value is a type
+ conversion and Float_Overflow checks are enabled.
+
+2019-07-08 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo.adb: Update the section on terminology to include new
+ concepts. Update the section on switches to include new
+ entries.
+ * bindo.ads: Add type Precedence_Kind.
+ * bindo-builders.adb: Add with and use clauses for Debug and
+ Bindo.Validators. Add use clauses for
+ Bindo.Validators.Invocation_Graph_Validators and
+ Bindo.Validators.Library_Graph_Validators.
+ (Build_Invocation_Graph): Validate the graph immediately after
+ it was built.
+ (Build_Library_Graph): Update the parameter profile. The
+ creation of the graph is now elaboration model-agnostic.
+ Validate the graph immediately after it was built.
+ (Create_With_Edge): Create regular with edges for Elaborate and
+ Elaborate_All edges when the appropriate debug switches are in
+ effect.
+ * bindo-builders.ads (Build_Library_Graph): Update the parameter
+ profile.
+ * bindo-diagnostics.adb (Diagnose_Cycle): Track the presence of
+ an Elaborate_All edge throughout the inspection of the cycle's
+ edges.
+ (Output_Dynamic_Model_Suggestions): Output the suggestion only
+ when the cycle contains at least one weak edge where the
+ successor was statically elaborated.
+ (Output_Elaborate_Body_Transition, Output_Forced_Transition,
+ Output_With_Transition): Update the assertions.
+ * bindo-elaborators.adb: Remove use clauses for
+ Bindo.Validators.Invocation_Graph_Validators and
+ Bindo.Validators.Library_Graph_Validators. Remove strings
+ Add_To_All_Candidates_Msg and Add_To_Comp_Candidates_Msg.
+ Remove type String_Ptr.
+ (Add_Vertex, Add_Vertex_If_Elaborable, Create_All_Candidates_Set
+ Create_Component_Candidates_Set): Remove.
+ (Create_Component_Vertex_Sets, Create_Vertex_Sets): New routine.
+ (Elaborate_Component): Update the parameter profile and the
+ comment on usage. Reimplement the elaboration of a component.
+ The algorithm will now attempt to elaborate as many vertices
+ possible. If this is not possible, and a weakly elaborable
+ vertex is available use unit was compiled using the dynamic
+ model, the algorithm will elaborate it.
+ (Elaborate_Library_Graph): Reimplement the elaboration of the
+ graph. The algorithm will now attempt to elaborate as many
+ vertices along with their components as possible. If this is not
+ possible, and a weakly elaborable vertex is available use unit
+ was compiled using the dynamic model, the algorithm will
+ elaborate it along with its component.
+ (Elaborate_Units): Merge with the functionality of
+ Elaborate_Units_Common.
+ (Elaborate_Units_Common, Elaborate_Units_Dynamic,
+ Elaborate_Units_Static): Remove.
+ (Elaborate_Vertex): Update the parameter profile and the comment
+ on usage. Reimplemented.
+ (Find_Best_Candidate): Remove.
+ (Find_Best_Elaborable_Vertex, Find_Best_Vertex,
+ Find_Best_Weakly_Elaborable_Vertex, Has_Elaborable_Body,
+ Insert_Elaborable_Successor, Insert_Vertex): New routines.
+ (Is_Better_Candidate): Remove.
+ (Is_Better_Elaborable_Vertex,
+ Is_Better_Weakly_Elaborable_Vertex,
+ Is_Suitable_Elaborable_Vertex,
+ Is_Suitable_Weakly_Elaborable_Vertex): New routines.
+ (Trace_Candidate_Vertices): Remove.
+ (Trace_Component): Output the number of strong and weak
+ predecessors.
+ (Trace_Unelaborated_Vertices): Remove.
+ (Trace_Vertex): Output the number of strong and weak
+ predecessors.
+ (Trace_Vertices): New routine.
+ (Update_Successor, Update_Successors): Update the parameter
+ profile and the comment on usage.
+ * bindo-graphs.adb: Remove type Precedence_Kind.
+ (Add_Edge_With_Return): Update the increment of pending
+ predecessors.
+ (Add_Vertex): Provide default values for strong and weak
+ predecessors.
+ (Complementary_Vertex): Move the initial declaration to the
+ spec. Update the parameter profile and the comment on usage.
+ (Contains_Weak_Static_Successor): New routine.
+ (Create): Update the parameter profile. The creation of the
+ graph is now elaboration model-agnostic.
+ (Decrement_Pending_Predecessors): Update the parameter profile
+ and the comment on usage. Reimplemented.
+ (Delete_Edge): Update the decrement of pending predecesors.
+ (Has_Elaborate_Body): Do not treat a vertex as being subject to
+ Elaborate_Body when a debug switch is in effect.
+ (Increment_Pending_Predecessors): Update the parameter profile
+ and the comment on usage. Reimplemented.
+ (Is_Elaborable_Component): Reimplemented.
+ (Is_Elaborable_Vertex): Move the initial declaration to the
+ spec. Reimplemented.
+ (Is_Elaborate_Body_Pair): New routine.
+ (Is_Dynamically_Elaborated): Update the parameter profile.
+ Reimplemented.
+ (Is_Weakly_Elaborable_Vertex): New routine.
+ (Pending_Predecessors): Removed.
+ (Pending_Predecessors_For_Elaboration,
+ Pending_Strong_Predecessors, Pending_Weak_Predecessors,
+ Update_Pending_Predecessors): New routines.
+ (Update_Pending_Predecessors_Of_Components): Update the
+ increment of pending predecessors.
+ * bindo-graphs.ads: Update the components of type
+ Component_Attributes. Update the components of type
+ Library_Graph_Attributes. Update the components of type
+ Library_Graph_Vertex_Attributes. Update the initialization of
+ No_Component_Attributes. Update the initialization of
+ No_Library_Graph_Vertex_Attributes.
+ (Complementary_Vertex, Contains_Weak_Static_Successor): New
+ routines.
+ (Create): Update the parameter profile and the comment on usage.
+ (Decrement_Pending_Predecessors, Is_Dynamically_Elaborated):
+ Update the parameter profile and the comment on usage.
+ (Is_Elaborate_Body_Pair, Is_Weakly_Elaborable_Vertex): New
+ routines.
+ (Pending_Predecessors): Removed.
+ (Pending_Predecessors_For_Elaboration,
+ Pending_Strong_Predecessors, Pending_Weak_Predecessors): New
+ routines.
+ * bindo-writers.adb (Write_Components): Moved from the spec.
+ (Write_Component): Output the strong and weak predecessors.
+ (Write_Library_Graph): Output the components as part of the
+ graph.
+ (Write_Library_Graph_Vertex): Output the strong and weak
+ predecessors.
+ * bindo-writers.ads (Write_Components): Moved to the body.
+ * debug.adb: Add and document new GNATbind switches -d_a, -d_b,
+ -d_e.
+ * bindo-validators.adb: Minor reformattings.
+
+2019-07-08 Bob Duff <duff@adacore.com>
+
+ * libgnat/g-sercom.ads, libgnat/g-sercom__linux.adb (Data_Rate):
+ Support additional data rates.
+
+2019-07-08 Olivier Hainque <hainque@adacore.com>
+
+ * gcc-interface/trans.c (Compilation_Unit_to_gnu): Don't request
+ DECL_ARTIFICIAL_P on elab proc declarations.
+
+2019-07-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * repinfo.adb (List_Record_Info): Declare Incomplete_Layout and
+ Not_In_Extended_Main local exceptions.
+ (List_Structural_Record_Layout): For an extension, raise the
+ former if the parent subtype has not been built and the latter
+ if it is not declared in the main source unit. Fall back to the
+ flat layout if either exception has been raised.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * libgnat/a-strfix.adb (Delete): The RM describes the semantics
+ of Delete as equivalent to that of Replace_String with a null
+ argument. As a result, deleting a null string that starts past
+ the end of its argument is a noop and must not raise
+ Index_Error.
+
+2019-07-08 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb (Register_Primitive): When registering a
+ primitive in the secondary dispatch table, handle primitive
+ inherited through several levels of type derivation (required to
+ properly handle inherited 'null' primitive).
+
+2019-07-08 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Document handling of
+ preprocessor directives in GNATpp.
+
+2019-07-08 Javier Miranda <miranda@adacore.com>
+
+ * gnat1drv.adb (Post_Compilation_Validation_Checks:
+ Validate_Compile_Time_Warning_Errors is now located in sem_prag
+ (instead of sem_ch13).
+ * sem_ch13.ads (Validate_Compile_Time_Warning_Error,
+ Validate_Compile_Time_Warning_Errors): Move to sem_prag.
+ * sem_ch13.adb
+ (Compile_Time_Warnings_Errors): Move to sem_prag.
+ (Initialize): Remove initialization of table
+ Compile_Time_Warning_Errors.
+ (Validate_Compile_Time_Warning_Error,
+ Validate_Compile_Time_Warning_Errors): Move to sem_prag.
+ * sem_prag.ads (Validate_Compile_Time_Warning_Errors): New
+ procedure.
+ * sem_prag.adb (Initialize): Initialize table
+ Compile_Time_Warning_Errors.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch13.adb (Analyze_Aspect_Specifications): For a
+ pre/postcondition of a generic subprogram declaration, do not
+ use Relocate_Node on the aspect expression to construct the
+ corresponding attribute specification, to prevent tree anomalies
+ when the expression is a call with named actual parameters.
+
+2019-07-08 Javier Miranda <miranda@adacore.com>
+
+ * sem_attr.adb (Analyze_Attribute [Attribute_Size]): For pragmas
+ used to report user defined compile time warning or errors
+ handle 'Size for types with known static RM size.
+
+2019-07-08 Justin Squirek <squirek@adacore.com>
+
+ * exp_imgv.adb (Build_Enumeration_Image_Tables): Default SSO for
+ the building of image tables.
+ (Expand_Image_Attribute): Minor cleanup.
+
+2019-07-08 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-socket.ads, libgnat/g-socket.adb: Improve
+ documentation.
+ (Get_Socket_Option, Set_Socket_Option): Remove default value for
+ the Level formal.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch13.adb (Check_Aspect_At_End_Of_Declarations): For an
+ unanalized aspect in a generic context that has not been
+ analyzed yet, if the aspect applies to a type, place the type on
+ the scope stack to make its components visible, before checking
+ conformance with the version of the expression analyzed at the
+ freeze point.
+
+2019-07-05 Justin Squirek <squirek@adacore.com>
+
+ * checks.adb (Apply_Accessibility_Check): Add logic to fetch the
+ function result accessibility level if one is required within
+ the generated check.
+ * exp_ch6.adb (Needs_Result_Accessibility_Level): Modify
+ controlling elsif block to handle more cases such as anonymous
+ access results and disable checking for coextensions.
+
+2019-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch9.adb (Analyze_Accept_Statement): If this is an illegal
+ accept statement for an enclosing entry abandon analysis to
+ prevent scope mismatches and potential infinite loops in
+ compiler.
+
+2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * ali.adb (For_Each_Invocation_Construct,
+ For_Each_Invocation_Relation): New version.
+ (Scan_ALI): Initialize field Invocation_Graph_Encoding.
+ (Set_Invocation_Graph_Encoding): Update the setting of the
+ invocation graph encoding.
+ * ali.ads: Move field Invocation_Graph_Encoding from Unit_Record
+ to ALI_Record because the encoding applies to the whole ALI,
+ rather than one of the units (spec or body) for which the ALI
+ file was created.
+ (For_Each_Invocation_Construct, For_Each_Invocation_Relation):
+ New version.
+ * bindo.adb: Update the section on switches. Complete the
+ section of debugging elaboration order issues.
+ (Find_Elaboration_Order): Prepare the routine for the switch
+ from the old to the new elaboration order mechanism.
+ * bindo-diagnostics.adb (Find_And_Output_Invocation_Paths):
+ Manage a visited set used by Visit_Vertex.
+ (Output_All_Cycles_Suggestions,
+ Output_Dynamic_Model_Suggestions): Clarify the nature of the
+ suggested switch.
+ (Output_Elaborate_Body_Transition): Update the diagnostic to
+ emit a better message.
+ (Output_Forced_Suggestions, Output_Full_Encoding_Suggestions):
+ Clarify the nature of the suggested switch.
+ (Visit_Vertex): Update the parameter profile to add a set of
+ invokers visited during the transition. This set prevents
+ infinite exploration of the graph in case the invocations are
+ recursive.
+ * bindo-elaborators.adb: Add a use clause for
+ Bindo.Writers.Dependency_Writers.
+ (Elaborate_Units_Common): Output the library graph after it has
+ been augmented with invocation edges. Output just the components
+ instead of outputting the whole library graph again.
+ (Elaborate_Units_Dynamic, Elaborate_Units_Static): Output the
+ dependencies as expressed in the library graph.
+ * bindo-units.adb (Invocation_Graph_Encoding): Update the
+ extraction of the invocation graph encoding.
+ * bindo-writers.adb: Add with and use clauses for Binderr and
+ Butil.
+ (palgc, plgc): New debug routine.
+ (Write_Components): Moved to the spec. Add a header for the
+ output.
+ (Write_Dependencies, Write_Dependencies_Of_Vertex,
+ Write_Dependency_Edge): New routine.
+ (Write_Elaboration_Order): Update the logic to follow the format
+ of Binde's order output.
+ (Write_Library_Graph): Do not output the components every time
+ the graph is written.
+ (Write_Unit): Output the invocation graph encoding of the unit.
+ Output the invocation constructs and relations for the unit
+ only.
+ * bindo-writers.ads (Write_Components): Moved from the body.
+ (Write_Dependencies): New routine.
+ * bindusg.adb: Prepare the routine for the switch from the old
+ to the new elaboration order mechanism.
+ * debug.adb: Binder switch -d_O is now not associated with any
+ functionality.
+ * einfo.adb (Is_Elaboration_Target): The attribute applies to
+ packages, as specified by the comment on the attribute usage.
+ * opt.ads: Add a global flag which controls the choice between
+ the new and the legacy elaboration order mechanism.
+ * sem_elab.adb: Add Package_Target to type Target_Kind.
+ (Build_Elaborate_Body_Procedure, Build_Elaborate_Procedure,
+ Build_Elaborate_Spec_Procedure, Check_Elaboration_Scenarios,
+ Check_SPARK_Model_In_Effect): Use Main_Unit_Entity to obtain the
+ entity of the main unit.
+ (Create_Package_Rep): New routine.
+ (Create_Target_Rep): Add processing for packages.
+ (Declaration_Placement_Of_Node, Has_Prior_Elaboration): Use
+ Main_Unit_Entity to obtain the entity of the main
+ unit.
+ (Invocation_Graph_Recording_OK): Prepare the routine for the
+ switch from the old to the new elaboration order mechanism.
+ (Main_Unit_Entity): New routine.
+ (Meet_Elaboration_Requirement,
+ Process_Conditional_ABE_Variable_Reference): Use
+ Main_Unit_Entity to obtain the entity of the main unit.
+ (Process_Invocation_Instantiation): New routine.
+ (Process_Invocation_Scenario): Add processing for
+ instantiations.
+ * switch-b.adb (Scan_Binder_Switches): Prepare the routine for
+ the switch from the old to the new elaboration order mechanism.
+
+2019-07-05 Joffrey Huguet <huguet@adacore.com>
+
+ * libgnat/a-textio.adb: Add abstract state refinment.
+ * libgnat/a-textio.ads: Add File_System abstract state. Add
+ global contracts, contract cases, preconditions and
+ postconditions to procedures and functions.
+ (Set_Input, Set_Output, Set_Error, Standard_Input,
+ Standard_Output, Standard_Error, Current_Input, Current_Output,
+ Current_Error): Turn SPARK_Mode off.
+ (Get_Line): Turn SPARK_Mode off on Get_Line functions.
+ * libgnat/a-tideio.ads, libgnat/a-tienio.ads,
+ libgnat/a-tifiio.ads, libgnat/a-tiflio.ads,
+ libgnat/a-tiinio.ads, libgnat/a-timoio.ads: Add global
+ contracts, contract cases, preconditions and postconditions to
+ procedures and functions.
+
+2019-07-05 Arnaud Charlet <charlet@adacore.com>
+
+ * doc/gnat_ugn/platform_specific_information.rst: Refresh doc on
+ installing from the command line on Windows. Remove obsolete
+ part.
+ * gnat_ugn.texi: Regenerate.
+
+2019-07-05 Vasiliy Fofanov <fofanov@adacore.com>
+
+ * libgnat/a-wichha.ads (Is_Alphanumeric): Replace comment with
+ the correct one. Also capitalize references to False
+ throughout.
+
+2019-07-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Indexed_Component): Do not expand actual
+ parameters of function calls here either.
+
+2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * bindo-units.adb, checks.adb, exp_attr.adb, exp_ch3.adb,
+ exp_ch4.adb, exp_pakd.adb, lib-writ.adb, libgnat/g-traceb.adb,
+ libgnat/g-traceb.ads, libgnat/s-stratt.ads, sem_aux.ads,
+ sem_util.adb: Minor reformatting.
+
+2019-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch13.adb (Build_Predicate_Functions): If a subtype that
+ carries a static predicate aspect is frozen immediately after
+ its declaration, ensure that the generated function body created
+ for predicate checking is inserted after the corresponding
+ subprogram declaration, which is created at the point the
+ declaration is elaborated.
+
+2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch7.adb (Cleanup_Record): Use the underlying type when
+ checking for components with tasks.
+
+2019-07-05 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnarl/s-osinte__linux.ads: Link with -lrt before -lpthread.
+
+2019-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_pakd.adb (Expand_Bit_Packed_Element_Set): Add explicit
+ range checks when the index type of the bit-packed array is an
+ enumeration type with a non-standard representation,
+
+2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_res.adb (Is_Control_Flow_Statement): Delay statements
+ contain an expression, which in turn may have side effects and
+ affect the infinite recursion. As a result, delay statements
+ should not be treated specially.
+
+2019-07-05 Arnaud Charlet <charlet@adacore.com>
+
+ * libgnarl/s-linux.ads, libgnarl/s-linux__alpha.ads,
+ libgnarl/s-linux__android.ads, libgnarl/s-linux__hppa.ads,
+ libgnarl/s-linux__mips.ads, libgnarl/s-linux__riscv.ads,
+ libgnarl/s-linux__sparc.ads: Fix typos in comments.
+
+2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_res.adb (Check_Infinite_Recursion): Reimplemented.
+ (Enclosing_Declaration_Or_Statement,
+ Invoked_With_Different_Arguments, Is_Conditional_Statement,
+ Is_Control_Flow_Statement, Is_Immediately_Within_Body,
+ Is_Raise_Idiom, Is_Raise_Statement, Is_Sole_Statement,
+ Preceded_By_Control_Flow_Statement,
+ Within_Conditional_Statement): New routines.
+
+2019-07-05 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Type_Conversion): Do not apply an
+ accessibility check when the conversion is an access to
+ class-wide interface type and it is an actual parameter.
+ * exp_ch6.adb (Expand_Call_Helper): Add documentation on the
+ accessibility level of an anonymous allocator defining the value
+ of an access parameter.
+ * sem_util.ads, sem_util.adb (Dynamic_Accessibility_Level): Add
+ support for an anonymous allocator whose type is that of a
+ stand-alone object of an anonymous access to object type.
+
+2019-07-05 Piotr Trojanek <trojanek@adacore.com>
+
+ * einfo.ads, sem_res.adb: Typo fixes in comments.
+
+2019-07-05 Bob Duff <duff@adacore.com>
+
+ * exp_ch6.adb (Is_Build_In_Place_Function): Narrow the check for
+ Has_Foreign_Convention to the imported case only. If a
+ build-in-place function is exported, and called from Ada code,
+ build-in-place protocols should be used.
+
+2019-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.adb (Encloing_Subprogram): If Enclosing_Dynamic_Scope
+ is a loop, continue climbing the scope stack to find the
+ enclosing subprogram.
+ (Gather_Components): Handle properly a choice in a record
+ aggregate that is given by a subtype with a static predicate.
+
+2019-07-05 Javier Miranda <miranda@adacore.com>
+
+ * debug.adb (-gnatd.K): Leave available this switch.
+ * contracts.adb (Build_And_Analyze_Contract_Only_Subprograms):
+ Remove.
+ * scil_ll.ads, scil_ll.adb (Contract_Only_Body_Flag,
+ Contract_Only_Body_Nodes, Get_Contract_Only_Body,
+ Is_Contract_Only_Body, Set_Contract_Only_Body): Remove.
+
+2019-07-05 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * libgnat/a-strunb.ads: Import documentation from the RM
+
+2019-07-05 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * libgnat/a-strfix.ads: Import documentation from the RM
+
+2019-07-05 Yannick Moy <moy@adacore.com>
+
+ * adabkend.adb (Scan_Back_End_Switches): Accept -Og and -Ofast
+ switches.
+
+2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * ali.adb: Relocate types Invocation_Construct_Record,
+ Invocation_Relation_Record, and Invocation_Signature_Record to
+ the body of ALI. Relocate tables Invocation_Constructs,
+ Invocation_Relations, and Invocation_Signatures to the body of
+ ALI. Remove type Body_Placement_Codes. Add new types
+ Declaration_Placement_Codes, and
+ Invocation_Graph_Encoding_Codes. Update the literals of type
+ Invocation_Graph_Line_Codes.
+ (Add_Invocation_Construct): Update the parameter profile. Add an
+ invocation construct built from all attributes provided.
+ (Add_Invocation_Relation): Update the parameter profile. Add an
+ invocation relation built from all attributes provided.
+ (Body_Placement): New routine.
+ (Body_Placement_Kind_To_Code, Code_To_Body_Placement_Kind):
+ Removed.
+ (Code_To_Declaration_Placement_Kind,
+ Code_To_Invocation_Graph_Encoding_Kind, Column,
+ Declaration_Placement_Kind_To_Code, Extra,
+ For_Each_Invocation_Construct, For_Each_Invocation_Relation,
+ Invocation_Graph_Encoding,
+ Invocation_Graph_Encoding_Kind_To_Code, Invoker, Kind, Line,
+ Locations, Name): New routine.
+ (Scan_Invocation_Construct_Line): Reimplement the scanning
+ mechanism.
+ (Scan_Invocation_Graph_Attributes_Line): New routine.
+ (Scan_Invocation_Graph_Line): Use a case statement to dispatch.
+ (Scan_Invocation_Relation_Line): Reimplement the scanning
+ mechanism.
+ (Scope): New routine.
+ (Set_Invocation_Graph_Encoding, Signature, Spec_Placement,
+ Target): New routine.
+ * ali.ads: Add new type Invocation_Graph_Encoding_Kind. Add
+ component Invocation_Graph_Encoding to type Unit_Record.
+ Relocate various types and data structures to the body of ALI.
+ (Add_Invocation_Construct, Add_Invocation_Relation): Update the
+ parameter profile.
+ (Body_Placement): New routine.
+ (Body_Placement_Kind_To_Code, Code_To_Body_Placement_Kind):
+ Removed.
+ (Code_To_Declaration_Placement_Kind,
+ Code_To_Invocation_Graph_Encoding_Kind, Column,
+ Declaration_Placement_Kind_To_Code, Extra,
+ For_Each_Invocation_Construct, For_Each_Invocation_Relation,
+ Invocation_Graph_Encoding,
+ Invocation_Graph_Encoding_Kind_To_Code, Invoker, Kind, Line,
+ Locations, Name, Scope, Set_Invocation_Graph_Encoding,
+ Signature, Spec_Placement, Target): New routine.
+ * bindo.adb: Add with clause for Binde. Add with and use
+ clauses for Debug. Update the documentation. Add new switches.
+ (Find_Elaboration_Order): Dispatch to the proper elaboration
+ mechanism.
+ * bindo-augmentors.adb:
+ Remove with and use clauses for GNAT and GNAT.Sets. Remove
+ membership set VS. Update the parameter profiles of most
+ routines to use better parameter names. Update the
+ implementation of most routine to use the new parameter names.
+ Remove various redundant assertions.
+ * bindo-builders.adb: Use better names for instantiated data
+ structures. Update all references to these names. Update the
+ parameter profiles of most routines to use better parameter
+ names. Update the implementation of most routine to use the new
+ parameter names.
+ (Build_Library_Graph): Update the parameter profile. Update the
+ call to Create.
+ (Create_Vertex): Reimplemented.
+ (Declaration_Placement_Vertex): New routine.
+ * bindo-builders.ads (Build_Library_Graph): Update the parameter
+ profile and comment on usage.
+ * bindo-diagnostics.adb: Almost a new unit.
+ * bindo-diagnostics.ads: Add a use clause for
+ Bindo.Graphs.Invocation_Graphs. Remove package
+ Cycle_Diagnostics.
+ (Diagnose_Circularities): New routine.
+ * bindo-elaborators.adb: Remove the with and use clauses for
+ Binderr and GNAT.Sets. Remove the use clause for
+ Bindo.Diagnostics.Cycle_Diagnostics. Remove membership set VS.
+ Update the parameter profiles of most routines to use better
+ parameter names. Update the implementation of most routine to
+ use the new parameter names. (Elaborate_Units_Common): Update
+ the parameter profile. Pass an infication to the library graph
+ builder whether the dynamic model is in effect.
+ (Elaborate_Units_Dynamic, Elaborate_Units_Static): Use
+ Diagnose_Circularities to provide diagnostics.
+ (Update_Successor): Use routine In_Same_Component to determine
+ whether the predecessor and successor reside in different
+ components.
+ * bindo-graphs.adb: Add with and use clauses for Butil, Debug,
+ Output, and Bindo.Writers. Remove with and use clauses for
+ GNAT.Lists. Update the parameter profiles of most routines to
+ use better parameter names. Update the implementation of most
+ routine to use the new parameter names. Remove various
+ redundant assertions. Remove doubly linked list EL. Add new
+ type Precedence_Kind.
+ (Add_Cycle): New routine.
+ (Add_Vertex): Update the parameter profile. Update the creation
+ of vertex attributes.
+ (Add_Vertex_And_Complement, Body_Vertex, Column,
+ Complementary_Vertex, Copy_Cycle_Path, Cycle_Kind_Of): New
+ routines.
+ (Destroy_Invocation_Graph_Edge, Destroy_Library_Graph_Cycle,
+ Destroy_Library_Graph_Edge, Extra, File_Name,
+ Find_All_Cycles_Through_Vertex, Find_All_Cycles_With_Edge,
+ Find_Cycles, Find_First_Lower_Precedence_Cycle,
+ Get_LGC_Attributes, Has_Next, Hash_Library_Graph_Cycle,
+ Hash_Library_Graph_Cycle_Attributes, Highest_Precedence_Cycle,
+ Highest_Precedence_Edge, In_Same_Component, Insert_And_Sort,
+ Invocation_Edge_Count, Invocation_Graph_Encoding,
+ Is_Cycle_Initiating_Edge, Is_Cyclic_Edge,
+ Is_Cyclic_Elaborate_All_Edge, Is_Cyclic_Elaborate_Body_Edge,
+ Is_Cyclic_Elaborate_Edge, Is_Cyclic_Forced_Edge,
+ Is_Cyclic_Invocation_Edge, Is_Cyclic_With_Edge,
+ Is_Dynamically_Elaborated, Is_Elaborate_All_Edge,
+ Is_Elaborate_Body_Edge, Is_Elaborate_Edge: New routines.
+ (Is_Existing_Predecessor_Successor_Relation): Removed.
+ (Is_Forced_Edge, Is_Invocation_Edge, Is_Recorded_Cycle,
+ Is_Recorded_Edge, Is_With_Edge, Iterate_Edges_Of_Cycle, Kind,
+ Length): New routine.
+ (Lib_Vertex): Removed.
+ (Line, Links_Vertices_In_Same_Component,
+ Maximum_Invocation_Edge_Count, Next, Normalize_And_Add_Cycle,
+ Normalize_Cycle_Path, Number_Of_Cycles, Path, Precedence,
+ Remove_Vertex_And_Complement, Sequence_Next_Cycle): New routines.
+ (Sequence_Next_IGE_Id): Renamed to Sequence_Next_Edge.
+ (Sequence_Next_IGV_Id): Renamed to Sequence_Next_Vertex.
+ (Sequence_Next_LGE_Id): Renamed to Sequence_Next_Edge.
+ (Sequence_Next_LGV_Id): Renamed to Sequence_Next_Vertex.
+ (Set_Is_Existing_Predecessor_Successor_Relation): Removed.
+ (Set_Is_Recorded_Cycle, Set_Is_Recorded_Edge,
+ Set_LGC_Attributes, Spec_Vertex, Trace_Cycle, Trace_Edge,
+ Trace_Eol, Trace_Vertex): New routines.
+ * bindo-graphs.ads: Add with and use clauses for Types and
+ GNAT.Lists. Update the parameter profiles of most routines to
+ use better parameter names. Update the implementation of most
+ routine to use the new parameter names. Add the new
+ instantiated data structures IGE_Lists, IGV_Sets, LGC_Lists,
+ LGE_Lists, LGE_Sets, LGV_Sets, and RC_Sets. Add new type
+ Library_Graph_Cycle_Id along with an empty and initial value.
+ Remove component Lib_Vertex and add new components Body_Vertex
+ and Spec_Vertex to type Invocation_Graph_Vertex_Attributes. Add
+ new type Library_Graph_Cycle_Kind. Add new iterators
+ All_Cycle_Iterator and Edges_Of_Cycle_Iterator. Add new type
+ Library_Graph_Cycle_Attributes. Add new components
+ Cycle_Attributes, Cycles, and Dynamically_Elaborated to type
+ Library_Graph_Attributes.
+ (Body_Vertex, Column, Destroy_Invocation_Graph_Edge,
+ Destroy_Library_Graph_Cycle_Attributes,
+ Destroy_Library_Graph_Edge, Extra, File_Name, Find_Cycles,
+ Has_Elaborate_All_Cycle, Has_Next, Hash_Library_Graph_Cycle,
+ Hash_Library_Graph_Cycle_Attributes, Highest_Precedence_Cycle,
+ In_Same_Component, Invocation_Edge_Count,
+ Invocation_Graph_Encoding, Is_Dynamically_Elaborated,
+ Is_Elaborate_All_Edge, Is_Elaborate_Body_Edge,
+ Is_Elaborate_Edge, Is_Forced_Edge, Is_Invocation_Edge,
+ Is_With_Edge, Iterate_All_Cycles, Iterate_Edges_Of_Cycle, Kind):
+ New routines.
+ (Length, Lib_Vertex, (Line, Next, Number_Of_Cycles, Present,
+ Same_Library_Graph_Cycle_Attributes, Spec_Vertex): New routines.
+ * bindo-units.adb (File_Name, Invocation_Graph_Encoding): New
+ routines.
+ * bindo-units.ads: Add new instantiated data structure
+ Unit_Sets.
+ (File_Name, Invocation_Graph_Encoding): New routine.
+ * bindo-validators.adb: Remove with and use clauses for GNAT and
+ GNAT.Sets. Remove membership set US. Update the parameter
+ profiles of most routines to use better parameter names. Update
+ the implementation of most routine to use the new parameter
+ names.
+ (Validate_Cycle, Validate_Cycle_Path, Validate_Cycles,
+ Validate_Invocation_Graph_Vertex): Remove the validation of
+ component Lib_Vertex. Add the validation of components
+ Body_Vertex and Spec_Vertex.
+ (Write_Error): New routine.
+ * bindo-validators.ads (Validate_Cycles): New routine.
+ * bindo-writers.adb: Update the parameter profiles of most
+ routines to use better parameter names. Update the
+ implementation of most routine to use the new parameter names.
+ (Write_Cycle, Write_Cyclic_Edge, Write_Cycles): New routines.
+ (Write_Invocation_Graph_Vertex): Remove the output of component
+ Lib_Vertex. Add the output of components Body_Vertex and
+ Spec_Vertex.
+ * bindo-writers.ads (Write_Cycles): New routine.
+ * debug.adb: Use binder switches -d_C and -d_P, add
+ documentation on their usage.
+ * gnatbind.adb: Remove with and use clauses for Binde. Delegate
+ the choice of elaboration mechanism to Bindo.
+ * lib-writ.adb (Column, Extra, Invoker, Kind, Line, Locations,
+ Name, Placement, Scope, Signature, Target): Removed.
+ (Write_Invocation_Graph): Moved at the top level.
+ (Write_Invocation_Graph_Attributes): New routine.
+ (Write_Invocation_Relation, Write_Invocation_Signature): Moved
+ at the top level.
+ * lib-writ.ads: Add a documentation section on invocation graph
+ attributes.
+ * sem_elab.adb (Body_Placement_Of): New routine.
+ (Declare_Invocation_Construct): Update the call to
+ Add_Invocation_Construct.
+ (Declaration_Placement_Of_Node): New routine.
+ (Get_Invocation_Attributes): Correct the retrieval of the
+ enclosing subprogram where the postcondition procedure lives.
+ (Placement_Of, Placement_Of_Node): Removed.
+ (Record_Invocation_Graph): Record the encoding format used.
+ (Record_Invocation_Graph_Encoding): New routine.
+ (Record_Invocation_Relation): Update the call to
+ Add_Invocation_Relation.
+ (Spec_Placement_Of): Removed.
+ * libgnat/g-lists.ads, libgnat/g-lists.adb (Equal): New routine.
+
+2019-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * checks.adb (Apply_Predicate_Check): Except within the
+ subprogram body that defines the formal, do not apply predicate
+ check on a formal IN parameter: such a check is redundant and
+ its expansion can lead to out-of-scope references when it is
+ originates in a function call in a precondition,
+
+2019-07-05 Yannick Moy <moy@adacore.com>
+
+ * sem_res.adb (Resolve_Call): Cannot inline in quantified
+ expressions.
+ * sem_util.adb, sem_util.ads (In_Quantified_Expression): New
+ function.
+
+2019-07-05 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_rm/standard_and_implementation_defined_restrictions.rst:
+ Fix typo.
+ * gnat_rm.texi: Regenerate.
+
+2019-07-05 Bob Duff <duff@adacore.com>
+
+ * exp_attr.adb (Input): Take the No_Stream_Optimizations
+ restriction into account.
+
+2019-07-05 Claire Dross <dross@adacore.com>
+
+ * libgnat/a-cofove.ads, libgnat/a-cofove.adb: Definite formal
+ vectors are now always bounded so that they do not need to be
+ limited anymore.
+
+2019-07-05 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-traceb.ads, libgnat/g-traceb.adb (Call_Chain): New
+ function.
+
+2019-07-04 James Clarke <jrtc27@debian.org>
+
+ * libgnarl/s-osinte__kfreebsd-gnu.ads (clockid_t): Make type
+ definition public.
+ (CLOCK_REALTIME): Make value public.
+
+2019-07-04 Javier Miranda <miranda@adacore.com>
+
+ * exp_tss.adb (Init_Proc): Adding missing support for access to
+ subprograms and access to protected subprograms of non-default
+ C++ constructors.
+
+2019-07-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat1drv.adb (Adjust_Global_Switches): Use proper interface to
+ set the validity settings in CodePeer mode.
+ * par-load.adb (Load): Remove all code dealing with validity
+ settings.
+ * validsw.ads (Validity_Check_Copies): Alphabetize.
+ * validsw.adb (Reset_Validity_Check_Options): Set all options to
+ off.
+ (Save_Validity_Check_Options): Save all options.
+
+2019-07-04 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch3.adb, exp_ch4.adb, exp_ch4.ads, exp_ch5.adb,
+ exp_ch7.adb, exp_ch9.adb, exp_ch11.adb, exp_unst.adb,
+ rtsfind.ads, sem_attr.adb, sem_ch10.adb, sem_ch12.adb,
+ sem_ch13.adb, sem_dim.adb, sem_disp.adb, xref_lib.adb: Minor
+ reformatting.
+
+2019-07-04 Joffrey Huguet <huguet@adacore.com>
+
+ * libgnarl/a-taside.ads: Add assertion policy to ignore
+ preconditions.
+ (Abort_Task, Is_Terminated, Is_Callable): Add preconditions.
+
+2019-07-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_pragmas.rst: Fix
+ capitalization and parenthesis glitches.
+ * gnat_rm.texi: Regenerate.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch10.adb (Remove_Context_Clauses): Handle properly the
+ removal of a limited_with_clause which appears in the library
+ unit oF the main unit, when some other unit in the context has a
+ regular with_clause on the same unit, to prevent spurious
+ visibility errors in the subsequent analysis of pending instance
+ bodies.
+
+2019-07-04 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_elab.adb: Add new type Elaboration_Phase_Status along with
+ a global to keep track of the elaboration phase status.
+ Initialize all internal data structures to Nil for services
+ Elaborated_Units, Internal_Representation, and Scenario_Storage.
+ (Build_Call_Marker): Do not create a call marker when the
+ elaboration phase is not active.
+ (Build_Variable_Reference_Marker): Do not create a call marker
+ when the elaboration phase is not active.
+ (Check_Elaboration_Scenarios): Destroy all internal structures
+ when the elaboration phase does not have to run. Do not execute
+ when the elaboration phase is not active.
+ (Elaboration_Phase_Active): New routine.
+ (Finalize_All_Data_Structures): New routine.
+ (Initialize): Initialize all internal data structures and signal
+ that the elaboration phase has started.
+ (Initialize_All_Data_Structures): New routine.
+ (Initialize_Elaborated_Units): Initialize all internal data
+ structures.
+ (Initialize_Internal_Representation): Initialize all internal
+ data structures.
+ (Initialize_Scenario_Storage): Initialize all internal data
+ structures.
+ (Kill_Elaboration_Scenario): Do not execute when the elaboration
+ phase is not active.
+ (Set_Elaboration_Phase): New routine.
+ (Update_Elaboration_Scenario): Do not execute when the
+ elaboration phase is not active.
+
+2019-07-04 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch6.adb (Analyze_Subprogram_Body_Helper): The special
+ treatment of calling Mask_Unfrozen_Types must also be done in
+ the case of an Ignored_Ghost_Entity, because Expander_Active is
+ False in that case.
+
+2019-07-04 Yannick Moy <moy@adacore.com>
+
+ * sem_prag.adb (Check_Library_Level_Entity): Update for new rule
+ on SPARK_Mode.
+
+2019-07-04 Justin Squirek <squirek@adacore.com>
+
+ * sem_disp.adb (Check_Controlling_Formals): Obtain the full view
+ before type comparison.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.ads, exp_ch4.adb (Build_Eq_Call): New visible
+ subprogram, extracted from Expand_Composite_Equality, to handle
+ properly the composition of equality for variant record types.
+ * exp_ch3.adb (MAke_Eq_If): Use Build_Eq_Call for each
+ component, to handle properly the case of a component with a
+ user-defined equality. Revert to predefined equality if the
+ user-defined operation is abstract, to maintain compatibility
+ with older versions,
+
+2019-07-04 Justin Squirek <squirek@adacore.com>
+
+ * exp_ch3.adb (Build_Initialization_Call): Fixup
+ *_skip_null_excluding_check argument to handle new default.
+ (Init_Formals): Make *_skip_null_excluding_check formal default
+ to False
+ * exp_ch4.adb (Expand_N_Allocator): Add comment to note heavy
+ code duplication
+
+2019-07-04 Bob Duff <duff@adacore.com>
+
+ * sem_ch3.adb (Access_Definition): Do not create a master unless
+ Tasking_Allowed. Otherwise, this fails on restricted runtimes.
+
+2019-07-04 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_util.adb (Propagate_DIC_Attributes): Do not propagate the
+ Default_Initial_Condition attributes to an incomplete type.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_attr.adb (Check_Array_Type): An array type attribute such
+ as 'First can be applied to an unconstrained array tyope when
+ the attribute reference appears within an aspect specification
+ and the prefix is a current instance, given that the prefix of
+ the attribute will become a formal of the subprogram that
+ implements the aspect (typically a predicate check).
+
+2019-07-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_util.adb (Yields_Synchronized_Object): Fix typos in
+ comments.
+
+2019-07-04 Yannick Moy <moy@adacore.com>
+
+ * sem_util.adb (Yields_Synchronized_Object): Adapt to new SPARK
+ rule.
+
+2019-07-04 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Check_Statement): Only check permission of
+ object in extended return when it is of a deep type.
+
+2019-07-04 Justin Squirek <squirek@adacore.com>
+
+ * sem_ch12.adb (Perform_Appropriate_Analysis): Added for
+ selecting which type of analysis based on wheither the
+ instantiation is a generic at the library-level. In which case
+ expansion during analysis.
+ (Preanalyze_Actuals): Modify calls to Analyze to use the new
+ routine.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_unst.adb: Handle conditional expressions.
+
+2019-07-04 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Check_Package_Spec, Check_Package_Body): Only
+ analyze parts of the code marked in SPARK.
+
+2019-07-04 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * erroutc.adb, exp_aggr.adb, inline.adb, opt.adb, sem_ch3.adb:
+ Minor reformatting.
+
+2019-07-04 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Explanation, Get_Expl): New functions to get
+ the explanation for a permission mismatch.
+ (Perm_Error, Perm_Mismatch, Perm_Error_Loop_Exit): Take
+ explanation into account for issuing a more precise error
+ message.
+ (Set_Perm_Prefixes, Set_Perm_Extensions,
+ Set_Perm_Extensions_Move): Pass suitable argument for the
+ explanation node.
+
+2019-07-04 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_aggr.adb (In_Place_Assign_OK): Moved to top level and add
+ support for record aggregates.
+ (Component_Check): Use Is_CCG_Supported_Aggregate instead of a
+ similar local predicate.
+ (Convert_To_Assignments): Take advantage of In_Place_Assign_OK
+ predicate when possible.
+ (Is_CCG_Supported_Aggregate): Return False for records with
+ representation clauses and fix the logic for dealing with nested
+ aggregates.
+
+2019-07-04 Piotr Trojanek <trojanek@adacore.com>
+
+ * opt.adb (Set_Config_Switches): Keep assertions policy as
+ enabled when analysing internal units in GNATprove mode.
+
+2019-07-04 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_ch4.adb (Expand_Short_Circuit_Operator): Strip
+ N_Variable_Reference_Marker when checking for the presence of
+ actions.
+
+2019-07-04 Arnaud Charlet <charlet@adacore.com>
+
+ * exp_aggr.adb (Check_Component): Take into account type
+ conversions.
+
+2019-07-04 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * doc/gnat_ugn/platform_specific_information.rst: Document
+ Windows socket timeout particularity.
+ * gnat_ugn.texi: Regenerate.
+ * gsocket.h: Include versionhelpers.h.
+ * socket.c (__gnat_minus_500ms): New function.
+ * libgnat/g-sothco.ads (Minus_500ms_Windows_Timeout): New
+ imported function.
+ * libgnat/g-socket.adb (Set_Socket_Option): Refactor to remove
+ 500ms from the requested timeout only on old Windows version.
+
+2019-07-04 Thomas Quinot <quinot@adacore.com>
+
+ * get_scos.adb: Remove bogus, dead code.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_dim.adb (Analyze_Dimension_Array_Aggregate): If the
+ component is an entity name, its dimensions are those of its
+ type.
+
2019-07-03 Bob Duff <duff@adacore.com>
* doc/gnat_ugn/gnat_utility_programs.rst: Document new flags in
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 916ae3e..6528df8 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -387,6 +387,7 @@ GNATRTL_NONTASKING_OBJS= \
g-arrspl$(objext) \
g-awk$(objext) \
g-binenv$(objext) \
+ g-brapre$(objext) \
g-bubsor$(objext) \
g-busora$(objext) \
g-busorg$(objext) \
@@ -867,7 +868,7 @@ GCC_SPEC_FILES=
# If what's left is null then it's a match.
# PowerPC and e500v2 VxWorks
-ifeq ($(strip $(filter-out powerpc% wrs vxworks vxworksspe vxworks7 vxworks7spe,$(target_cpu) $(target_vendor) $(target_os))),)
+ifeq ($(strip $(filter-out powerpc% wrs vxworks vxworksspe vxworks7% vxworks7spe,$(target_cpu) $(target_vendor) $(target_os))),)
ifeq ($(strip $(filter-out e500%, $(target_alias))),)
ARCH_STR=e500
@@ -1118,7 +1119,7 @@ ifeq ($(strip $(filter-out %86 wrs vxworksae,$(target_cpu) $(target_vendor) $(ta
endif
# x86/x86_64 VxWorks
-ifeq ($(strip $(filter-out %86 x86_64 wrs vxworks vxworks7,$(target_cpu) $(target_vendor) $(target_os))),)
+ifeq ($(strip $(filter-out %86 x86_64 wrs vxworks vxworks7%,$(target_cpu) $(target_vendor) $(target_os))),)
EH_MECHANISM=-gcc
@@ -1521,7 +1522,6 @@ ifeq ($(strip $(filter-out %86 linux%,$(target_cpu) $(target_os))),)
s-intman.adb<libgnarl/s-intman__posix.adb \
s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \
$(TRASYM_DWARF_UNIX_PAIRS) \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
s-tsmona.adb<libgnat/s-tsmona__linux.adb \
a-exetim.adb<libgnarl/a-exetim__posix.adb \
a-exetim.ads<libgnarl/a-exetim__default.ads \
@@ -2046,7 +2046,6 @@ ifeq ($(strip $(filter-out mips% linux%,$(target_cpu) $(target_os))),)
s-tasinf.adb<libgnarl/s-tasinf__linux.adb \
s-taspri.ads<libgnarl/s-taspri__posix-noaltstack.ads \
s-tpopsp.adb<libgnarl/s-tpopsp__posix-foreign.adb \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
system.ads<libgnat/system-linux-mips.ads
TOOLS_TARGET_PAIRS = indepsw.adb<indepsw-gnu.adb
@@ -2072,7 +2071,6 @@ ifeq ($(strip $(filter-out powerpc% linux%,$(target_cpu) $(target_os))),)
s-linux.ads<libgnarl/s-linux.ads \
s-osinte.adb<libgnarl/s-osinte__posix.adb \
s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
$(TRASYM_DWARF_UNIX_PAIRS) \
s-tsmona.adb<libgnat/s-tsmona__linux.adb \
$(ATOMICS_TARGET_PAIRS) \
@@ -2151,7 +2149,6 @@ ifeq ($(strip $(filter-out aarch64% linux%,$(target_cpu) $(target_os))),)
s-tasinf.adb<libgnarl/s-tasinf__linux.adb \
s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \
s-taspri.ads<libgnarl/s-taspri__posix.ads \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
$(ATOMICS_TARGET_PAIRS) \
$(ATOMICS_BUILTINS_TARGET_PAIRS) \
system.ads<libgnat/system-linux-arm.ads
@@ -2296,7 +2293,6 @@ ifeq ($(strip $(filter-out %ia64 linux%,$(target_cpu) $(target_os))),)
s-tasinf.adb<libgnarl/s-tasinf__linux.adb \
s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \
s-taspri.ads<libgnarl/s-taspri__posix-noaltstack.ads \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
$(TRASYM_DWARF_UNIX_PAIRS) \
s-tsmona.adb<libgnat/s-tsmona__linux.adb \
$(ATOMICS_TARGET_PAIRS) \
@@ -2393,7 +2389,6 @@ ifeq ($(strip $(filter-out %x86_64 linux%,$(target_cpu) $(target_os))),)
s-tasinf.adb<libgnarl/s-tasinf__linux.adb \
s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \
s-taspri.ads<libgnarl/s-taspri__posix.ads \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
$(TRASYM_DWARF_UNIX_PAIRS) \
s-tsmona.adb<libgnat/s-tsmona__linux.adb \
$(ATOMICS_TARGET_PAIRS) \
@@ -2435,7 +2430,6 @@ ifeq ($(strip $(filter-out %x32 linux%,$(target_cpu) $(target_os))),)
s-tasinf.adb<libgnarl/s-tasinf__linux.adb \
s-tpopsp.adb<libgnarl/s-tpopsp__tls.adb \
s-taspri.ads<libgnarl/s-taspri__posix.ads \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
$(ATOMICS_TARGET_PAIRS) \
$(X86_64_TARGET_PAIRS) \
system.ads<libgnat/system-linux-x86.ads
@@ -2466,7 +2460,6 @@ ifeq ($(strip $(filter-out riscv% linux%,$(target_cpu) $(target_os))),)
s-tasinf.adb<libgnarl/s-tasinf__linux.adb \
s-taspri.ads<libgnarl/s-taspri__posix-noaltstack.ads \
s-tpopsp.adb<libgnarl/s-tpopsp__posix-foreign.adb \
- g-sercom.adb<libgnat/g-sercom__linux.adb \
system.ads<libgnat/system-linux-riscv.ads
TOOLS_TARGET_PAIRS = indepsw.adb<indepsw-gnu.adb
@@ -2594,6 +2587,11 @@ ifeq ($(EH_MECHANISM),-arm)
EXTRA_GNATRTL_NONTASKING_OBJS+=g-cppexc.o s-excmac.o
endif
+ifeq ($(strip $(filter-out linux%,$(target_os))),)
+ LIBGNAT_TARGET_PAIRS += \
+ g-sercom.adb<libgnat/g-sercom__linux.adb
+endif
+
# LIBGNAT_SRCS is the list of all C files (including headers) of the runtime
# library. LIBGNAT_OBJS is the list of object files for libgnat.
# thread.c is special as put into GNATRTL_TASKING_OBJS
@@ -2612,7 +2610,7 @@ LIBGNAT_OBJS = adadecode.o adaint.o argv.o aux-io.o \
LIBGNAT_SRCS = $(patsubst %.o,%.c,$(LIBGNAT_OBJS)) \
adadecode.h adaint.h env.h gsocket.h raise.h standard.ads.h \
- tb-gcc.c libgnarl/thread.c $(EXTRA_LIBGNAT_SRCS)
+ tb-gcc.c runtime.h libgnarl/thread.c $(EXTRA_LIBGNAT_SRCS)
# memtrack.o is special as not put into libgnat.
GNATRTL_OBJS = $(GNATRTL_NONTASKING_OBJS) $(GNATRTL_TASKING_OBJS) \
@@ -2689,9 +2687,15 @@ setup-rts: force
$(LN_S) $(GNAT_SRC)/$(word 2,$(subst <, ,$(PAIR))) \
$(RTSDIR)/$(word 1,$(subst <, ,$(PAIR)));)
-# Special flags
+# Special flags. It is recommended not to change the compilation flags
+# without a careful analysis of the consequences because (part of) the
+# runtime implements low-level support that is outside of the semantics
+# of the language and therefore needs to be treated differently from the
+# other units. For example, the part of the runtime implementing the
+# propagation of exceptions cannot itself be compiled with checks that
+# may give rise to exceptions, e.g. stack overflow checks.
-# force no sibling call optimization on s-traceb.o so the number of stack
+# Force no sibling call optimization on s-traceb.o so the number of stack
# frames to be skipped when computing a call chain is not modified by
# optimization. We don't want inlining, either.
@@ -2700,14 +2704,14 @@ s-traceb.o : s-traceb.adb s-traceb.ads
$(NO_INLINE_ADAFLAGS) $(NO_SIBLING_ADAFLAGS) $(ADA_INCLUDES) $< \
$(OUTPUT_OPTION)
-# compile s-tasdeb.o without optimization and with debug info so that it is
+# Compile s-tasdeb.o without optimization and with debug info so that it is
# always possible to set conditional breakpoints on tasks.
s-tasdeb.o : s-tasdeb.adb s-tasdeb.ads
$(ADAC) -c $(ALL_ADAFLAGS) $(FORCE_DEBUG_ADAFLAGS) -O0 $(ADA_INCLUDES) \
$< $(OUTPUT_OPTION)
-# force no function reordering on a-except.o because of the exclusion bounds
+# Force no function reordering on a-except.o because of the exclusion bounds
# mechanism (see the source file for more detailed information).
# force debugging information on a-except.o so that it is always
# possible to set conditional breakpoints on exceptions.
@@ -2718,7 +2722,7 @@ a-except.o : a-except.adb a-except.ads
$(NO_INLINE_ADAFLAGS) $(NO_REORDER_ADAFLAGS) -O1 $(ADA_INCLUDES) \
$< $(OUTPUT_OPTION)
-# compile s-excdeb.o without optimization and with debug info to let the
+# Compile s-excdeb.o without optimization and with debug info to let the
# debugger set breakpoints and inspect subprogram parameters on exception
# related events.
@@ -2726,21 +2730,21 @@ s-excdeb.o : s-excdeb.adb s-excdeb.ads s-except.ads
$(ADAC) -c $(ALL_ADAFLAGS) $(FORCE_DEBUG_ADAFLAGS) -O0 \
$(ADA_INCLUDES) $< $(OUTPUT_OPTION)
-# force debugging information on s-assert.o so that it is always
+# Force debugging information on s-assert.o so that it is always
# possible to set breakpoint on assert failures.
s-assert.o : s-assert.adb s-assert.ads
$(ADAC) -c $(ALL_ADAFLAGS) $(FORCE_DEBUG_ADAFLAGS) $(ADA_INCLUDES) \
$< $(OUTPUT_OPTION)
-# force debugging information on a-tags.o so that the debugger can find
+# Force debugging information on a-tags.o so that the debugger can find
# the description of Ada.Tags.Type_Specific_Data.
a-tags.o : a-tags.adb a-tags.ads
$(ADAC) -c $(ALL_ADAFLAGS) $(FORCE_DEBUG_ADAFLAGS) $(ADA_INCLUDES) \
$< $(OUTPUT_OPTION)
-# force no sibling call optimization on s-memory.o to avoid turning the
+# Force no sibling call optimization on s-memory.o to avoid turning the
# tail recursion in Alloc into a loop that confuses branch prediction.
s-memory.o : s-memory.adb s-memory.ads
diff --git a/gcc/ada/adabkend.adb b/gcc/ada/adabkend.adb
index c42f3bd..3e1b14d 100644
--- a/gcc/ada/adabkend.adb
+++ b/gcc/ada/adabkend.adb
@@ -117,9 +117,11 @@ package body Adabkend is
-- Set optimization indicators appropriately. In gcc-based GNAT this
-- is picked up from imported variables set by the gcc driver, but
- -- for compilers with non-gcc back ends we do it here to allow use
- -- of these switches by the front end. Allowed optimization switches
- -- are -Os (optimize for size), -O[0123], and -O (same as -O1).
+ -- for compilers with non-gcc back ends we do it here to allow use of
+ -- these switches by the front end. Allowed optimization switches are
+ -- -Os (optimize for size), -O[0123], -O (same as -O1), -Ofast
+ -- (disregard strict standards compliance), and -Og (optimize
+ -- debugging experience).
elsif Switch_Chars (First) = 'O' then
if First = Last then
@@ -134,10 +136,21 @@ package body Adabkend is
Optimization_Level :=
Character'Pos (Switch_Chars (Last)) - Character'Pos ('0');
+ -- Switch -Og is between -O0 and -O1 in GCC. Consider it like
+ -- -O0 for other back ends.
+
+ elsif Switch_Chars (Last) = 'g' then
+ Optimization_Level := 0;
+
else
Fail ("invalid switch: " & Switch_Chars);
end if;
+ -- Switch -Ofast enables -O3
+
+ elsif Switch_Chars (First + 1 .. Last) = "fast" then
+ Optimization_Level := 3;
+
else
Fail ("invalid switch: " & Switch_Chars);
end if;
@@ -169,7 +182,7 @@ package body Adabkend is
return;
- -- Special check, the back end switch -fno-inline also sets the
+ -- Special check, the back-end switch -fno-inline also sets the
-- front end flags to entirely inhibit all inlining. So we store it
-- and set the appropriate flags.
@@ -206,7 +219,7 @@ package body Adabkend is
end case;
end if;
- -- Ignore all other back end switches
+ -- Ignore all other back-end switches
elsif Is_Back_End_Switch (Switch_Chars) then
null;
diff --git a/gcc/ada/adadecode.c b/gcc/ada/adadecode.c
index a574f3c..f87d421 100644
--- a/gcc/ada/adadecode.c
+++ b/gcc/ada/adadecode.c
@@ -29,15 +29,7 @@
* *
****************************************************************************/
-
-#if defined(IN_RTS)
-#include "tconfig.h"
-#include "tsystem.h"
-#elif defined(IN_GCC)
-#include "config.h"
-#include "system.h"
-#endif
-
+#include "runtime.h"
#include <string.h>
#include <stdio.h>
#include <ctype.h>
diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
index 4a75b59..fe8d955 100644
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -88,8 +88,26 @@
#endif
#ifdef IN_RTS
+
+#ifdef STANDALONE
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* for CPU_SET/CPU_ZERO */
+#define _GNU_SOURCE
+#define __USE_GNU
+
+#include "runtime.h"
+
+#else
#include "tconfig.h"
#include "tsystem.h"
+#endif
+
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
diff --git a/gcc/ada/adaint.h b/gcc/ada/adaint.h
index 2ae8766..311e240 100644
--- a/gcc/ada/adaint.h
+++ b/gcc/ada/adaint.h
@@ -51,7 +51,7 @@ extern "C" {
determine at compile time what support the system offers for large files.
For now we just list the platforms we have manually tested. */
-#if defined (__GLIBC__) || defined (__sun__) || defined (__QNX__)
+#if (defined (__GLIBC__) && !defined(STANDALONE)) || defined (__sun__) || defined (__QNX__)
#define GNAT_FOPEN fopen64
#define GNAT_OPEN open64
#define GNAT_STAT stat64
diff --git a/gcc/ada/ali.adb b/gcc/ada/ali.adb
index 978fb3d..feea73f 100644
--- a/gcc/ada/ali.adb
+++ b/gcc/ada/ali.adb
@@ -39,10 +39,115 @@ package body ALI is
use ASCII;
-- Make control characters visible
+ -----------
+ -- Types --
+ -----------
+
+ -- The following type represents an invocation construct
+
+ type Invocation_Construct_Record is record
+ Body_Placement : Declaration_Placement_Kind := No_Declaration_Placement;
+ -- The location of the invocation construct's body with respect to the
+ -- unit where it is declared.
+
+ Kind : Invocation_Construct_Kind := Regular_Construct;
+ -- The nature of the invocation construct
+
+ Signature : Invocation_Signature_Id := No_Invocation_Signature;
+ -- The invocation signature that uniquely identifies the invocation
+ -- construct in the ALI space.
+
+ Spec_Placement : Declaration_Placement_Kind := No_Declaration_Placement;
+ -- The location of the invocation construct's spec with respect to the
+ -- unit where it is declared.
+ end record;
+
+ -- The following type represents an invocation relation. It associates an
+ -- invoker that activates/calls/instantiates with a target.
+
+ type Invocation_Relation_Record is record
+ Extra : Name_Id := No_Name;
+ -- The name of an additional entity used in error diagnostics
+
+ Invoker : Invocation_Signature_Id := No_Invocation_Signature;
+ -- The invocation signature that uniquely identifies the invoker within
+ -- the ALI space.
+
+ Kind : Invocation_Kind := No_Invocation;
+ -- The nature of the invocation
+
+ Target : Invocation_Signature_Id := No_Invocation_Signature;
+ -- The invocation signature that uniquely identifies the target within
+ -- the ALI space.
+ end record;
+
+ -- The following type represents an invocation signature. Its purpose is
+ -- to uniquely identify an invocation construct within the ALI space. The
+ -- signature comprises several pieces, some of which are used in error
+ -- diagnostics by the binder. Identification issues are resolved as
+ -- follows:
+ --
+ -- * The Column, Line, and Locations attributes together differentiate
+ -- between homonyms. In most cases, the Column and Line are sufficient
+ -- except when generic instantiations are involved. Together, the three
+ -- attributes offer a sequence of column-line pairs that eventually
+ -- reflect the location within the generic template.
+ --
+ -- * The Name attribute differentiates between invocation constructs at
+ -- the scope level. Since it is illegal for two entities with the same
+ -- name to coexist in the same scope, the Name attribute is sufficient
+ -- to distinguish them. Overloaded entities are already handled by the
+ -- Column, Line, and Locations attributes.
+ --
+ -- * The Scope attribute differentiates between invocation constructs at
+ -- various levels of nesting.
+
+ type Invocation_Signature_Record is record
+ Column : Nat := 0;
+ -- The column number where the invocation construct is declared
+
+ Line : Nat := 0;
+ -- The line number where the invocation construct is declared
+
+ Locations : Name_Id := No_Name;
+ -- Sequence of column and line numbers within nested instantiations
+
+ Name : Name_Id := No_Name;
+ -- The name of the invocation construct
+
+ Scope : Name_Id := No_Name;
+ -- The qualified name of the scope where the invocation construct is
+ -- declared.
+ end record;
+
---------------------
-- Data structures --
---------------------
+ package Invocation_Constructs is new Table.Table
+ (Table_Index_Type => Invocation_Construct_Id,
+ Table_Component_Type => Invocation_Construct_Record,
+ Table_Low_Bound => First_Invocation_Construct,
+ Table_Initial => 2500,
+ Table_Increment => 200,
+ Table_Name => "Invocation_Constructs");
+
+ package Invocation_Relations is new Table.Table
+ (Table_Index_Type => Invocation_Relation_Id,
+ Table_Component_Type => Invocation_Relation_Record,
+ Table_Low_Bound => First_Invocation_Relation,
+ Table_Initial => 2500,
+ Table_Increment => 200,
+ Table_Name => "Invocation_Relation");
+
+ package Invocation_Signatures is new Table.Table
+ (Table_Index_Type => Invocation_Signature_Id,
+ Table_Component_Type => Invocation_Signature_Record,
+ Table_Low_Bound => First_Invocation_Signature,
+ Table_Initial => 2500,
+ Table_Increment => 200,
+ Table_Name => "Invocation_Signatures");
+
procedure Destroy (IS_Id : in out Invocation_Signature_Id);
-- Destroy an invocation signature with id IS_Id
@@ -68,14 +173,19 @@ package body ALI is
Sig_To_Sig_Map : constant Sig_Map.Dynamic_Hash_Table :=
Sig_Map.Create (500);
- -- The folowing table maps body placement kinds to character codes for
- -- invocation construct encoding in ALI files.
+ -- The folowing table maps declaration placement kinds to character codes
+ -- for invocation construct encoding in ALI files.
+
+ Declaration_Placement_Codes :
+ constant array (Declaration_Placement_Kind) of Character :=
+ (In_Body => 'b',
+ In_Spec => 's',
+ No_Declaration_Placement => 'Z');
- Body_Placement_Codes :
- constant array (Body_Placement_Kind) of Character :=
- (In_Body => 'b',
- In_Spec => 's',
- No_Body_Placement => 'Z');
+ Compile_Time_Invocation_Graph_Encoding : Invocation_Graph_Encoding_Kind :=
+ No_Encoding;
+ -- The invocation-graph encoding format as specified at compile time. Do
+ -- not manipulate this value directly.
-- The following table maps invocation kinds to character codes for
-- invocation relation encoding in ALI files.
@@ -112,13 +222,23 @@ package body ALI is
Elaborate_Spec_Procedure => 's',
Regular_Construct => 'Z');
- -- The following table maps invocation graph line kinds to character codes
+ -- The following table maps invocation-graph encoding kinds to character
+ -- codes for invocation-graph encoding in ALI files.
+
+ Invocation_Graph_Encoding_Codes :
+ constant array (Invocation_Graph_Encoding_Kind) of Character :=
+ (Full_Path_Encoding => 'f',
+ Endpoints_Encoding => 'e',
+ No_Encoding => 'Z');
+
+ -- The following table maps invocation-graph line kinds to character codes
-- used in ALI files.
Invocation_Graph_Line_Codes :
constant array (Invocation_Graph_Line_Kind) of Character :=
- (Invocation_Construct_Line => 'c',
- Invocation_Relation_Line => 'r');
+ (Invocation_Construct_Line => 'c',
+ Invocation_Graph_Attributes_Line => 'a',
+ Invocation_Relation_Line => 'r');
-- The following variable records which characters currently are used as
-- line type markers in the ALI file. This is used in Scan_ALI to detect
@@ -153,18 +273,22 @@ package body ALI is
------------------------------
procedure Add_Invocation_Construct
- (IC_Rec : Invocation_Construct_Record;
- Update_Units : Boolean := True)
+ (Body_Placement : Declaration_Placement_Kind;
+ Kind : Invocation_Construct_Kind;
+ Signature : Invocation_Signature_Id;
+ Spec_Placement : Declaration_Placement_Kind;
+ Update_Units : Boolean := True)
is
- IC_Id : Invocation_Construct_Id;
-
begin
- pragma Assert (Present (IC_Rec.Signature));
+ pragma Assert (Present (Signature));
-- Create a invocation construct from the scanned attributes
- Invocation_Constructs.Append (IC_Rec);
- IC_Id := Invocation_Constructs.Last;
+ Invocation_Constructs.Append
+ ((Body_Placement => Body_Placement,
+ Kind => Kind,
+ Signature => Signature,
+ Spec_Placement => Spec_Placement));
-- Update the invocation construct counter of the current unit only when
-- requested by the caller.
@@ -174,7 +298,7 @@ package body ALI is
Curr_Unit : Unit_Record renames Units.Table (Units.Last);
begin
- Curr_Unit.Last_Invocation_Construct := IC_Id;
+ Curr_Unit.Last_Invocation_Construct := Invocation_Constructs.Last;
end;
end if;
end Add_Invocation_Construct;
@@ -184,20 +308,24 @@ package body ALI is
-----------------------------
procedure Add_Invocation_Relation
- (IR_Rec : Invocation_Relation_Record;
+ (Extra : Name_Id;
+ Invoker : Invocation_Signature_Id;
+ Kind : Invocation_Kind;
+ Target : Invocation_Signature_Id;
Update_Units : Boolean := True)
is
- IR_Id : Invocation_Relation_Id;
-
begin
- pragma Assert (Present (IR_Rec.Invoker));
- pragma Assert (Present (IR_Rec.Target));
- pragma Assert (IR_Rec.Kind /= No_Invocation);
+ pragma Assert (Present (Invoker));
+ pragma Assert (Kind /= No_Invocation);
+ pragma Assert (Present (Target));
-- Create an invocation relation from the scanned attributes
- Invocation_Relations.Append (IR_Rec);
- IR_Id := Invocation_Relations.Last;
+ Invocation_Relations.Append
+ ((Extra => Extra,
+ Invoker => Invoker,
+ Kind => Kind,
+ Target => Target));
-- Update the invocation relation counter of the current unit only when
-- requested by the caller.
@@ -207,41 +335,42 @@ package body ALI is
Curr_Unit : Unit_Record renames Units.Table (Units.Last);
begin
- Curr_Unit.Last_Invocation_Relation := IR_Id;
+ Curr_Unit.Last_Invocation_Relation := Invocation_Relations.Last;
end;
end if;
end Add_Invocation_Relation;
- ---------------------------------
- -- Body_Placement_Kind_To_Code --
- ---------------------------------
+ --------------------
+ -- Body_Placement --
+ --------------------
- function Body_Placement_Kind_To_Code
- (Kind : Body_Placement_Kind) return Character
+ function Body_Placement
+ (IC_Id : Invocation_Construct_Id) return Declaration_Placement_Kind
is
begin
- return Body_Placement_Codes (Kind);
- end Body_Placement_Kind_To_Code;
+ pragma Assert (Present (IC_Id));
+ return Invocation_Constructs.Table (IC_Id).Body_Placement;
+ end Body_Placement;
- ---------------------------------
- -- Code_To_Body_Placement_Kind --
- ---------------------------------
+ ----------------------------------------
+ -- Code_To_Declaration_Placement_Kind --
+ ----------------------------------------
- function Code_To_Body_Placement_Kind
- (Code : Character) return Body_Placement_Kind
+ function Code_To_Declaration_Placement_Kind
+ (Code : Character) return Declaration_Placement_Kind
is
begin
- -- Determine which body placement kind corresponds to the character code
- -- by traversing the contents of the mapping table.
+ -- Determine which placement kind corresponds to the character code by
+ -- traversing the contents of the mapping table.
- for Kind in Body_Placement_Kind loop
- if Body_Placement_Codes (Kind) = Code then
+ for Kind in Declaration_Placement_Kind loop
+ if Declaration_Placement_Codes (Kind) = Code then
return Kind;
end if;
end loop;
raise Program_Error;
- end Code_To_Body_Placement_Kind;
+ end Code_To_Declaration_Placement_Kind;
---------------------------------------
-- Code_To_Invocation_Construct_Kind --
@@ -263,6 +392,26 @@ package body ALI is
raise Program_Error;
end Code_To_Invocation_Construct_Kind;
+ --------------------------------------------
+ -- Code_To_Invocation_Graph_Encoding_Kind --
+ --------------------------------------------
+
+ function Code_To_Invocation_Graph_Encoding_Kind
+ (Code : Character) return Invocation_Graph_Encoding_Kind
+ is
+ begin
+ -- Determine which invocation-graph encoding kind matches the character
+ -- code by traversing the contents of the mapping table.
+
+ for Kind in Invocation_Graph_Encoding_Kind loop
+ if Invocation_Graph_Encoding_Codes (Kind) = Code then
+ return Kind;
+ end if;
+ end loop;
+
+ raise Program_Error;
+ end Code_To_Invocation_Graph_Encoding_Kind;
+
-----------------------------
-- Code_To_Invocation_Kind --
-----------------------------
@@ -291,7 +440,7 @@ package body ALI is
(Code : Character) return Invocation_Graph_Line_Kind
is
begin
- -- Determine which invocation graph line kind matches the character
+ -- Determine which invocation-graph line kind matches the character
-- code by traversing the contents of the mapping table.
for Kind in Invocation_Graph_Line_Kind loop
@@ -303,6 +452,27 @@ package body ALI is
raise Program_Error;
end Code_To_Invocation_Graph_Line_Kind;
+ ------------
+ -- Column --
+ ------------
+
+ function Column (IS_Id : Invocation_Signature_Id) return Nat is
+ begin
+ pragma Assert (Present (IS_Id));
+ return Invocation_Signatures.Table (IS_Id).Column;
+ end Column;
+
+ ----------------------------------------
+ -- Declaration_Placement_Kind_To_Code --
+ ----------------------------------------
+
+ function Declaration_Placement_Kind_To_Code
+ (Kind : Declaration_Placement_Kind) return Character
+ is
+ begin
+ return Declaration_Placement_Codes (Kind);
+ end Declaration_Placement_Kind_To_Code;
+
-------------
-- Destroy --
-------------
@@ -313,6 +483,92 @@ package body ALI is
null;
end Destroy;
+ -----------
+ -- Extra --
+ -----------
+
+ function Extra (IR_Id : Invocation_Relation_Id) return Name_Id is
+ begin
+ pragma Assert (Present (IR_Id));
+ return Invocation_Relations.Table (IR_Id).Extra;
+ end Extra;
+
+ -----------------------------------
+ -- For_Each_Invocation_Construct --
+ -----------------------------------
+
+ procedure For_Each_Invocation_Construct
+ (Processor : Invocation_Construct_Processor_Ptr)
+ is
+ begin
+ pragma Assert (Processor /= null);
+
+ for IC_Id in Invocation_Constructs.First ..
+ Invocation_Constructs.Last
+ loop
+ Processor.all (IC_Id);
+ end loop;
+ end For_Each_Invocation_Construct;
+
+ -----------------------------------
+ -- For_Each_Invocation_Construct --
+ -----------------------------------
+
+ procedure For_Each_Invocation_Construct
+ (U_Id : Unit_Id;
+ Processor : Invocation_Construct_Processor_Ptr)
+ is
+ pragma Assert (Present (U_Id));
+ pragma Assert (Processor /= null);
+
+ U_Rec : Unit_Record renames Units.Table (U_Id);
+
+ begin
+ for IC_Id in U_Rec.First_Invocation_Construct ..
+ U_Rec.Last_Invocation_Construct
+ loop
+ Processor.all (IC_Id);
+ end loop;
+ end For_Each_Invocation_Construct;
+
+ ----------------------------------
+ -- For_Each_Invocation_Relation --
+ ----------------------------------
+
+ procedure For_Each_Invocation_Relation
+ (Processor : Invocation_Relation_Processor_Ptr)
+ is
+ begin
+ pragma Assert (Processor /= null);
+
+ for IR_Id in Invocation_Relations.First ..
+ Invocation_Relations.Last
+ loop
+ Processor.all (IR_Id);
+ end loop;
+ end For_Each_Invocation_Relation;
+
+ ----------------------------------
+ -- For_Each_Invocation_Relation --
+ ----------------------------------
+
+ procedure For_Each_Invocation_Relation
+ (U_Id : Unit_Id;
+ Processor : Invocation_Relation_Processor_Ptr)
+ is
+ pragma Assert (Present (U_Id));
+ pragma Assert (Processor /= null);
+
+ U_Rec : Unit_Record renames Units.Table (U_Id);
+
+ begin
+ for IR_Id in U_Rec.First_Invocation_Relation ..
+ U_Rec.Last_Invocation_Relation
+ loop
+ Processor.all (IR_Id);
+ end loop;
+ end For_Each_Invocation_Relation;
+
----------
-- Hash --
----------
@@ -428,6 +684,26 @@ package body ALI is
return Invocation_Construct_Codes (Kind);
end Invocation_Construct_Kind_To_Code;
+ -------------------------------
+ -- Invocation_Graph_Encoding --
+ -------------------------------
+
+ function Invocation_Graph_Encoding return Invocation_Graph_Encoding_Kind is
+ begin
+ return Compile_Time_Invocation_Graph_Encoding;
+ end Invocation_Graph_Encoding;
+
+ --------------------------------------------
+ -- Invocation_Graph_Encoding_Kind_To_Code --
+ --------------------------------------------
+
+ function Invocation_Graph_Encoding_Kind_To_Code
+ (Kind : Invocation_Graph_Encoding_Kind) return Character
+ is
+ begin
+ return Invocation_Graph_Encoding_Codes (Kind);
+ end Invocation_Graph_Encoding_Kind_To_Code;
+
----------------------------------------
-- Invocation_Graph_Line_Kind_To_Code --
----------------------------------------
@@ -489,6 +765,70 @@ package body ALI is
end Invocation_Signature_Of;
-------------
+ -- Invoker --
+ -------------
+
+ function Invoker
+ (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id
+ is
+ begin
+ pragma Assert (Present (IR_Id));
+ return Invocation_Relations.Table (IR_Id).Invoker;
+ end Invoker;
+
+ ----------
+ -- Kind --
+ ----------
+
+ function Kind
+ (IC_Id : Invocation_Construct_Id) return Invocation_Construct_Kind
+ is
+ begin
+ pragma Assert (Present (IC_Id));
+ return Invocation_Constructs.Table (IC_Id).Kind;
+ end Kind;
+
+ ----------
+ -- Kind --
+ ----------
+
+ function Kind (IR_Id : Invocation_Relation_Id) return Invocation_Kind is
+ begin
+ pragma Assert (Present (IR_Id));
+ return Invocation_Relations.Table (IR_Id).Kind;
+ end Kind;
+
+ ----------
+ -- Line --
+ ----------
+
+ function Line (IS_Id : Invocation_Signature_Id) return Nat is
+ begin
+ pragma Assert (Present (IS_Id));
+ return Invocation_Signatures.Table (IS_Id).Line;
+ end Line;
+
+ ---------------
+ -- Locations --
+ ---------------
+
+ function Locations (IS_Id : Invocation_Signature_Id) return Name_Id is
+ begin
+ pragma Assert (Present (IS_Id));
+ return Invocation_Signatures.Table (IS_Id).Locations;
+ end Locations;
+
+ ----------
+ -- Name --
+ ----------
+
+ function Name (IS_Id : Invocation_Signature_Id) return Name_Id is
+ begin
+ pragma Assert (Present (IS_Id));
+ return Invocation_Signatures.Table (IS_Id).Name;
+ end Name;
+
+ -------------
-- Present --
-------------
@@ -638,7 +978,7 @@ package body ALI is
--
-- If Ignore_Special is False (normal case), the scan is terminated by
-- a typeref bracket or an equal sign except for the special case of
- -- an operator name starting with a double quote which is terminated
+ -- an operator name starting with a double quote that is terminated
-- by another double quote.
--
-- If May_Be_Quoted is True and the first non blank character is '"'
@@ -674,7 +1014,7 @@ package body ALI is
-- Parse the definition of a typeref (<...>, {...} or (...))
procedure Scan_Invocation_Graph_Line;
- -- Parse a single line which encodes a piece of the invocation graph
+ -- Parse a single line that encodes a piece of the invocation graph
procedure Skip_Eol;
-- Skip past spaces, then skip past end of line (fatal error if not
@@ -1204,6 +1544,13 @@ package body ALI is
-- * Invocation_Constructs
-- * Units
+ procedure Scan_Invocation_Graph_Attributes_Line;
+ pragma Inline (Scan_Invocation_Graph_Attributes_Line);
+ -- Parse an invocation-graph attributes line. The following data
+ -- structures are updated:
+ --
+ -- * Units
+
procedure Scan_Invocation_Relation_Line;
pragma Inline (Scan_Invocation_Relation_Line);
-- Parse an invocation relation line and construct the corresponding
@@ -1225,51 +1572,78 @@ package body ALI is
------------------------------------
procedure Scan_Invocation_Construct_Line is
- IC_Rec : Invocation_Construct_Record;
+ Body_Placement : Declaration_Placement_Kind;
+ Kind : Invocation_Construct_Kind;
+ Signature : Invocation_Signature_Id;
+ Spec_Placement : Declaration_Placement_Kind;
begin
-- construct-kind
- IC_Rec.Kind := Code_To_Invocation_Construct_Kind (Getc);
+ Kind := Code_To_Invocation_Construct_Kind (Getc);
+ Checkc (' ');
+ Skip_Space;
+
+ -- construct-spec-placement
+
+ Spec_Placement := Code_To_Declaration_Placement_Kind (Getc);
Checkc (' ');
Skip_Space;
-- construct-body-placement
- IC_Rec.Placement := Code_To_Body_Placement_Kind (Getc);
+ Body_Placement := Code_To_Declaration_Placement_Kind (Getc);
Checkc (' ');
Skip_Space;
-- construct-signature
- IC_Rec.Signature := Scan_Invocation_Signature;
- pragma Assert (Present (IC_Rec.Signature));
-
+ Signature := Scan_Invocation_Signature;
Skip_Eol;
- Add_Invocation_Construct (IC_Rec);
+ Add_Invocation_Construct
+ (Body_Placement => Body_Placement,
+ Kind => Kind,
+ Signature => Signature,
+ Spec_Placement => Spec_Placement);
end Scan_Invocation_Construct_Line;
+ -------------------------------------------
+ -- Scan_Invocation_Graph_Attributes_Line --
+ -------------------------------------------
+
+ procedure Scan_Invocation_Graph_Attributes_Line is
+ begin
+ -- encoding-kind
+
+ Set_Invocation_Graph_Encoding
+ (Code_To_Invocation_Graph_Encoding_Kind (Getc));
+ Skip_Eol;
+ end Scan_Invocation_Graph_Attributes_Line;
+
-----------------------------------
-- Scan_Invocation_Relation_Line --
-----------------------------------
procedure Scan_Invocation_Relation_Line is
- IR_Rec : Invocation_Relation_Record;
+ Extra : Name_Id;
+ Invoker : Invocation_Signature_Id;
+ Kind : Invocation_Kind;
+ Target : Invocation_Signature_Id;
begin
-- relation-kind
- IR_Rec.Kind := Code_To_Invocation_Kind (Getc);
+ Kind := Code_To_Invocation_Kind (Getc);
Checkc (' ');
Skip_Space;
-- (extra-name | "none")
- IR_Rec.Extra := Get_Name;
+ Extra := Get_Name;
- if IR_Rec.Extra = Name_None then
- IR_Rec.Extra := No_Name;
+ if Extra = Name_None then
+ Extra := No_Name;
end if;
Checkc (' ');
@@ -1277,20 +1651,20 @@ package body ALI is
-- invoker-signature
- IR_Rec.Invoker := Scan_Invocation_Signature;
- pragma Assert (Present (IR_Rec.Invoker));
-
+ Invoker := Scan_Invocation_Signature;
Checkc (' ');
Skip_Space;
-- target-signature
- IR_Rec.Target := Scan_Invocation_Signature;
- pragma Assert (Present (IR_Rec.Target));
-
+ Target := Scan_Invocation_Signature;
Skip_Eol;
- Add_Invocation_Relation (IR_Rec);
+ Add_Invocation_Relation
+ (Extra => Extra,
+ Invoker => Invoker,
+ Kind => Kind,
+ Target => Target);
end Scan_Invocation_Relation_Line;
-------------------------------
@@ -1378,13 +1752,16 @@ package body ALI is
-- line-attributes
- if Line = Invocation_Construct_Line then
- Scan_Invocation_Construct_Line;
+ case Line is
+ when Invocation_Construct_Line =>
+ Scan_Invocation_Construct_Line;
- else
- pragma Assert (Line = Invocation_Relation_Line);
- Scan_Invocation_Relation_Line;
- end if;
+ when Invocation_Graph_Attributes_Line =>
+ Scan_Invocation_Graph_Attributes_Line;
+
+ when Invocation_Relation_Line =>
+ Scan_Invocation_Relation_Line;
+ end case;
end Scan_Invocation_Graph_Line;
--------------
@@ -1496,6 +1873,7 @@ package body ALI is
First_Specific_Dispatching => Specific_Dispatching.Last + 1,
First_Unit => No_Unit_Id,
GNATprove_Mode => False,
+ Invocation_Graph_Encoding => No_Encoding,
Last_Interrupt_State => Interrupt_States.Last,
Last_Sdep => No_Sdep_Id,
Last_Specific_Dispatching => Specific_Dispatching.Last,
@@ -3064,7 +3442,7 @@ package body ALI is
ALIs.Table (Id).Last_Sdep := Sdep.Last;
- -- Loop through invocation graph lines
+ -- Loop through invocation-graph lines
G_Loop : loop
Check_Unknown_Line;
@@ -3436,6 +3814,16 @@ package body ALI is
return No_ALI_Id;
end Scan_ALI;
+ -----------
+ -- Scope --
+ -----------
+
+ function Scope (IS_Id : Invocation_Signature_Id) return Name_Id is
+ begin
+ pragma Assert (Present (IS_Id));
+ return Invocation_Signatures.Table (IS_Id).Scope;
+ end Scope;
+
---------
-- SEq --
---------
@@ -3445,6 +3833,31 @@ package body ALI is
return F1.all = F2.all;
end SEq;
+ -----------------------------------
+ -- Set_Invocation_Graph_Encoding --
+ -----------------------------------
+
+ procedure Set_Invocation_Graph_Encoding
+ (Kind : Invocation_Graph_Encoding_Kind;
+ Update_Units : Boolean := True)
+ is
+ begin
+ Compile_Time_Invocation_Graph_Encoding := Kind;
+
+ -- Update the invocation-graph encoding of the current unit only when
+ -- requested by the caller.
+
+ if Update_Units then
+ declare
+ Curr_Unit : Unit_Record renames Units.Table (Units.Last);
+ Curr_ALI : ALIs_Record renames ALIs.Table (Curr_Unit.My_ALI);
+
+ begin
+ Curr_ALI.Invocation_Graph_Encoding := Kind;
+ end;
+ end if;
+ end Set_Invocation_Graph_Encoding;
+
-----------
-- SHash --
-----------
@@ -3461,4 +3874,40 @@ package body ALI is
return Vindex (Vindex'First + Vindex (H mod Vindex'Range_Length));
end SHash;
+ ---------------
+ -- Signature --
+ ---------------
+
+ function Signature
+ (IC_Id : Invocation_Construct_Id) return Invocation_Signature_Id
+ is
+ begin
+ pragma Assert (Present (IC_Id));
+ return Invocation_Constructs.Table (IC_Id).Signature;
+ end Signature;
+
+ --------------------
+ -- Spec_Placement --
+ --------------------
+
+ function Spec_Placement
+ (IC_Id : Invocation_Construct_Id) return Declaration_Placement_Kind
+ is
+ begin
+ pragma Assert (Present (IC_Id));
+ return Invocation_Constructs.Table (IC_Id).Spec_Placement;
+ end Spec_Placement;
+
+ ------------
+ -- Target --
+ ------------
+
+ function Target
+ (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id
+ is
+ begin
+ pragma Assert (Present (IR_Id));
+ return Invocation_Relations.Table (IR_Id).Target;
+ end Target;
+
end ALI;
diff --git a/gcc/ada/ali.ads b/gcc/ada/ali.ads
index 79eabb1..fc6e592 100644
--- a/gcc/ada/ali.ads
+++ b/gcc/ada/ali.ads
@@ -112,6 +112,20 @@ package ALI is
First_ALI_Entry : constant ALI_Id := No_ALI_Id + 1;
-- Id of first actual entry in table
+ -- The following type enumerates all possible invocation-graph encoding
+ -- kinds.
+
+ type Invocation_Graph_Encoding_Kind is
+ (Endpoints_Encoding,
+ -- The invocation construct and relation lines contain information for
+ -- the start construct and end target found on an invocation-graph path.
+
+ Full_Path_Encoding,
+ -- The invocation construct and relation lines contain information for
+ -- all constructs and targets found on a invocation-graph path.
+
+ No_Encoding);
+
type Main_Program_Type is (None, Proc, Func);
-- Indicator of whether unit can be used as main program
@@ -212,7 +226,7 @@ package ALI is
No_Component_Reordering : Boolean;
-- Set to True if file was compiled with a configuration pragma file
- -- containing pragma No_Component_Reordering. Not set if 'P' appears
+ -- containing pragma No_Component_Reordering. Not set if 'P' appears
-- in Ignore_Lines.
No_Object : Boolean;
@@ -259,6 +273,11 @@ package ALI is
-- Last_Specific_Dispatching = First_Specific_Dispatching - 1. That
-- is why the 'Base reference is there, it can be one less than the
-- lower bound of the subtype. Not set if 'S' appears in Ignore_Lines.
+
+ Invocation_Graph_Encoding : Invocation_Graph_Encoding_Kind;
+ -- The encoding format used to capture information about the invocation
+ -- constructs and relations within the corresponding ALI file of this
+ -- unit.
end record;
No_Main_Priority : constant Int := -1;
@@ -1087,6 +1106,20 @@ package ALI is
-- Invocation Graph Types --
----------------------------
+ -- The following type identifies an invocation construct
+
+ No_Invocation_Construct : constant Invocation_Construct_Id :=
+ Invocation_Construct_Id'First;
+ First_Invocation_Construct : constant Invocation_Construct_Id :=
+ No_Invocation_Construct + 1;
+
+ -- The following type identifies an invocation relation
+
+ No_Invocation_Relation : constant Invocation_Relation_Id :=
+ Invocation_Relation_Id'First;
+ First_Invocation_Relation : constant Invocation_Relation_Id :=
+ No_Invocation_Relation + 1;
+
-- The following type identifies an invocation signature
No_Invocation_Signature : constant Invocation_Signature_Id :=
@@ -1094,59 +1127,20 @@ package ALI is
First_Invocation_Signature : constant Invocation_Signature_Id :=
No_Invocation_Signature + 1;
- -- The following type represents an invocation signature. Its purpose is
- -- to uniquely identify an invocation construct within the ALI space. The
- -- signature is comprised out of several pieces, some of which are used in
- -- error diagnostics by the binder. Identification issues are resolved as
- -- follows:
- --
- -- * The Column, Line, and Locations attributes together differentiate
- -- between homonyms. In most cases, the Column and Line are sufficient
- -- except when generic instantiations are involved. Together, the three
- -- attributes offer a sequence of column-line pairs which eventually
- -- reflect the location within the generic template.
- --
- -- * The Name attribute differentiates between invocation constructs at
- -- the scope level. Since it is illegal for two entities with the same
- -- name to coexist in the same scope, the Name attribute is sufficient
- -- to distinguish them. Overloaded entities are already handled by the
- -- Column, Line, and Locations attributes.
- --
- -- * The Scope attribute differentiates between invocation constructs at
- -- various levels of nesting.
-
- type Invocation_Signature_Record is record
- Column : Nat := 0;
- -- The column number where the invocation construct is declared
-
- Line : Nat := 0;
- -- The line number where the invocation construct is declared
-
- Locations : Name_Id := No_Name;
- -- Sequence of column and line numbers within nested instantiations
-
- Name : Name_Id := No_Name;
- -- The name of the invocation construct
-
- Scope : Name_Id := No_Name;
- -- The qualified name of the scope where the invocation construct is
- -- declared.
- end record;
-
-- The following type enumerates all possible placements of an invocation
- -- construct's body body with respect to the unit it is declared in.
+ -- construct's spec and body with respect to the unit it is declared in.
- type Body_Placement_Kind is
+ type Declaration_Placement_Kind is
(In_Body,
- -- The body of the invocation construct is within the body of the unit
- -- it is declared in.
+ -- The declaration of the invocation construct is within the body of the
+ -- unit it is declared in.
In_Spec,
- -- The body of the invocation construct is within the spec of the unit
- -- it is declared in.
+ -- The declaration of the invocation construct is within the spec of the
+ -- unit it is declared in.
- No_Body_Placement);
- -- The invocation construct does not have a body
+ No_Declaration_Placement);
+ -- The invocation construct does not have a declaration
-- The following type enumerates all possible invocation construct kinds
@@ -1162,35 +1156,6 @@ package ALI is
Regular_Construct);
-- The invocation construct is a normal invocation construct
- -- The following type identifies an invocation construct
-
- No_Invocation_Construct : constant Invocation_Construct_Id :=
- Invocation_Construct_Id'First;
- First_Invocation_Construct : constant Invocation_Construct_Id :=
- No_Invocation_Construct + 1;
-
- -- The following type represents an invocation construct
-
- type Invocation_Construct_Record is record
- Kind : Invocation_Construct_Kind := Regular_Construct;
- -- The nature of the invocation construct
-
- Placement : Body_Placement_Kind := No_Body_Placement;
- -- The location of the invocation construct's body with respect to the
- -- body of the unit it is declared in.
-
- Signature : Invocation_Signature_Id := No_Invocation_Signature;
- -- The invocation signature which uniquely identifies the invocation
- -- construct in the ALI space.
- end record;
-
- -- The following type identifies an invocation relation
-
- No_Invocation_Relation : constant Invocation_Relation_Id :=
- Invocation_Relation_Id'First;
- First_Invocation_Relation : constant Invocation_Relation_Id :=
- No_Invocation_Relation + 1;
-
-- The following type enumerates all possible invocation kinds
type Invocation_Kind is
@@ -1220,94 +1185,60 @@ package ALI is
-- Internal_Controlled_Finalization
Internal_Controlled_Initialization;
- -- The following type represents an invocation relation. It associates an
- -- invoker which activates/calls/instantiates with a target.
-
- type Invocation_Relation_Record is record
- Extra : Name_Id := No_Name;
- -- The name of an additional entity used in error diagnostics
-
- Invoker : Invocation_Signature_Id := No_Invocation_Signature;
- -- The invocation signature which uniquely identifies the invoker within
- -- the ALI space.
-
- Kind : Invocation_Kind := No_Invocation;
- -- The nature of the invocation
-
- Target : Invocation_Signature_Id := No_Invocation_Signature;
- -- The invocation signature which uniquely identifies the target within
- -- the ALI space.
- end record;
-
- -- The following type enumerates all possible invocation graph ALI lines
+ -- The following type enumerates all possible invocation-graph ALI lines
type Invocation_Graph_Line_Kind is
(Invocation_Construct_Line,
+ Invocation_Graph_Attributes_Line,
Invocation_Relation_Line);
- --------------------------------------
- -- Invocation Graph Data Structures --
- --------------------------------------
-
- package Invocation_Constructs is new Table.Table
- (Table_Index_Type => Invocation_Construct_Id,
- Table_Component_Type => Invocation_Construct_Record,
- Table_Low_Bound => First_Invocation_Construct,
- Table_Initial => 2500,
- Table_Increment => 200,
- Table_Name => "Invocation_Constructs");
-
- package Invocation_Relations is new Table.Table
- (Table_Index_Type => Invocation_Relation_Id,
- Table_Component_Type => Invocation_Relation_Record,
- Table_Low_Bound => First_Invocation_Relation,
- Table_Initial => 2500,
- Table_Increment => 200,
- Table_Name => "Invocation_Relation");
-
- package Invocation_Signatures is new Table.Table
- (Table_Index_Type => Invocation_Signature_Id,
- Table_Component_Type => Invocation_Signature_Record,
- Table_Low_Bound => First_Invocation_Signature,
- Table_Initial => 2500,
- Table_Increment => 200,
- Table_Name => "Invocation_Signatures");
-
----------------------------------
-- Invocation Graph Subprograms --
----------------------------------
procedure Add_Invocation_Construct
- (IC_Rec : Invocation_Construct_Record;
- Update_Units : Boolean := True);
+ (Body_Placement : Declaration_Placement_Kind;
+ Kind : Invocation_Construct_Kind;
+ Signature : Invocation_Signature_Id;
+ Spec_Placement : Declaration_Placement_Kind;
+ Update_Units : Boolean := True);
pragma Inline (Add_Invocation_Construct);
- -- Add invocation construct attributes IC_Rec to internal data structures.
- -- Flag Undate_Units should be set when this addition must be reflected in
- -- the attributes of the current unit.
+ -- Add a new invocation construct described by its attributes. Update_Units
+ -- should be set when this addition must be reflected in the attributes of
+ -- the current unit.
procedure Add_Invocation_Relation
- (IR_Rec : Invocation_Relation_Record;
+ (Extra : Name_Id;
+ Invoker : Invocation_Signature_Id;
+ Kind : Invocation_Kind;
+ Target : Invocation_Signature_Id;
Update_Units : Boolean := True);
pragma Inline (Add_Invocation_Relation);
- -- Add invocation relation attributes IR_Rec to internal data structures.
- -- Flag Undate_Units should be set when this addition must be reflected in
- -- the attributes of the current unit.
+ -- Add a new invocation relation described by its attributes. Update_Units
+ -- should be set when this addition must be reflected in the attributes of
+ -- the current unit.
- function Body_Placement_Kind_To_Code
- (Kind : Body_Placement_Kind) return Character;
- pragma Inline (Body_Placement_Kind_To_Code);
- -- Obtain the character encoding of body placement kind Kind
+ function Body_Placement
+ (IC_Id : Invocation_Construct_Id) return Declaration_Placement_Kind;
+ pragma Inline (Body_Placement);
+ -- Obtain the location of invocation construct IC_Id's body with respect to
+ -- the unit where it is declared.
- function Code_To_Body_Placement_Kind
- (Code : Character) return Body_Placement_Kind;
- pragma Inline (Code_To_Body_Placement_Kind);
- -- Obtain the body placement kind of character encoding Code
+ function Code_To_Declaration_Placement_Kind
+ (Code : Character) return Declaration_Placement_Kind;
+ pragma Inline (Code_To_Declaration_Placement_Kind);
+ -- Obtain the declaration placement kind of character encoding Code
function Code_To_Invocation_Construct_Kind
(Code : Character) return Invocation_Construct_Kind;
pragma Inline (Code_To_Invocation_Construct_Kind);
-- Obtain the invocation construct kind of character encoding Code
+ function Code_To_Invocation_Graph_Encoding_Kind
+ (Code : Character) return Invocation_Graph_Encoding_Kind;
+ pragma Inline (Code_To_Invocation_Graph_Encoding_Kind);
+ -- Obtain the invocation-graph encoding kind of character encoding Code
+
function Code_To_Invocation_Kind
(Code : Character) return Invocation_Kind;
pragma Inline (Code_To_Invocation_Kind);
@@ -1316,17 +1247,70 @@ package ALI is
function Code_To_Invocation_Graph_Line_Kind
(Code : Character) return Invocation_Graph_Line_Kind;
pragma Inline (Code_To_Invocation_Graph_Line_Kind);
- -- Obtain the invocation graph line kind of character encoding Code
+ -- Obtain the invocation-graph line kind of character encoding Code
+
+ function Column (IS_Id : Invocation_Signature_Id) return Nat;
+ pragma Inline (Column);
+ -- Obtain the column number of invocation signature IS_Id
+
+ function Declaration_Placement_Kind_To_Code
+ (Kind : Declaration_Placement_Kind) return Character;
+ pragma Inline (Declaration_Placement_Kind_To_Code);
+ -- Obtain the character encoding of declaration placement kind Kind
+
+ function Extra (IR_Id : Invocation_Relation_Id) return Name_Id;
+ pragma Inline (Extra);
+ -- Obtain the name of the additional entity used in error diagnostics for
+ -- invocation relation IR_Id.
+
+ type Invocation_Construct_Processor_Ptr is
+ access procedure (IC_Id : Invocation_Construct_Id);
+
+ procedure For_Each_Invocation_Construct
+ (Processor : Invocation_Construct_Processor_Ptr);
+ pragma Inline (For_Each_Invocation_Construct);
+ -- Invoke Processor on each invocation construct
+
+ procedure For_Each_Invocation_Construct
+ (U_Id : Unit_Id;
+ Processor : Invocation_Construct_Processor_Ptr);
+ pragma Inline (For_Each_Invocation_Construct);
+ -- Invoke Processor on each invocation construct of unit U_Id
+
+ type Invocation_Relation_Processor_Ptr is
+ access procedure (IR_Id : Invocation_Relation_Id);
+
+ procedure For_Each_Invocation_Relation
+ (Processor : Invocation_Relation_Processor_Ptr);
+ pragma Inline (For_Each_Invocation_Relation);
+ -- Invoke Processor on each invocation relation
+
+ procedure For_Each_Invocation_Relation
+ (U_Id : Unit_Id;
+ Processor : Invocation_Relation_Processor_Ptr);
+ pragma Inline (For_Each_Invocation_Relation);
+ -- Invoke Processor on each invocation relation of unit U_Id
function Invocation_Construct_Kind_To_Code
(Kind : Invocation_Construct_Kind) return Character;
pragma Inline (Invocation_Construct_Kind_To_Code);
-- Obtain the character encoding of invocation kind Kind
+ function Invocation_Graph_Encoding return Invocation_Graph_Encoding_Kind;
+ pragma Inline (Invocation_Graph_Encoding);
+ -- Obtain the encoding format used to capture information about the
+ -- invocation constructs and relations within the ALI file of the main
+ -- unit.
+
+ function Invocation_Graph_Encoding_Kind_To_Code
+ (Kind : Invocation_Graph_Encoding_Kind) return Character;
+ pragma Inline (Invocation_Graph_Encoding_Kind_To_Code);
+ -- Obtain the character encoding for invocation-graph encoding kind Kind
+
function Invocation_Graph_Line_Kind_To_Code
(Kind : Invocation_Graph_Line_Kind) return Character;
pragma Inline (Invocation_Graph_Line_Kind_To_Code);
- -- Obtain the character encoding for invocation like kind Kind
+ -- Obtain the character encoding for invocation line kind Kind
function Invocation_Kind_To_Code
(Kind : Invocation_Kind) return Character;
@@ -1342,6 +1326,63 @@ package ALI is
pragma Inline (Invocation_Signature_Of);
-- Obtain the invocation signature that corresponds to the input attributes
+ function Invoker
+ (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id;
+ pragma Inline (Invoker);
+ -- Obtain the signature of the invocation relation IR_Id's invoker
+
+ function Kind
+ (IC_Id : Invocation_Construct_Id) return Invocation_Construct_Kind;
+ pragma Inline (Kind);
+ -- Obtain the nature of invocation construct IC_Id
+
+ function Kind
+ (IR_Id : Invocation_Relation_Id) return Invocation_Kind;
+ pragma Inline (Kind);
+ -- Obtain the nature of invocation relation IR_Id
+
+ function Line (IS_Id : Invocation_Signature_Id) return Nat;
+ pragma Inline (Line);
+ -- Obtain the line number of invocation signature IS_Id
+
+ function Locations (IS_Id : Invocation_Signature_Id) return Name_Id;
+ pragma Inline (Locations);
+ -- Obtain the sequence of column and line numbers within nested instances
+ -- of invocation signature IS_Id
+
+ function Name (IS_Id : Invocation_Signature_Id) return Name_Id;
+ pragma Inline (Name);
+ -- Obtain the name of invocation signature IS_Id
+
+ function Scope (IS_Id : Invocation_Signature_Id) return Name_Id;
+ pragma Inline (Scope);
+ -- Obtain the scope of invocation signature IS_Id
+
+ procedure Set_Invocation_Graph_Encoding
+ (Kind : Invocation_Graph_Encoding_Kind;
+ Update_Units : Boolean := True);
+ pragma Inline (Set_Invocation_Graph_Encoding);
+ -- Set the encoding format used to capture information about the invocation
+ -- constructs and relations within the ALI file of the main unit to Kind.
+ -- Update_Units should be set when this action must be reflected in the
+ -- attributes of the current unit.
+
+ function Signature
+ (IC_Id : Invocation_Construct_Id) return Invocation_Signature_Id;
+ pragma Inline (Signature);
+ -- Obtain the signature of invocation construct IC_Id
+
+ function Spec_Placement
+ (IC_Id : Invocation_Construct_Id) return Declaration_Placement_Kind;
+ pragma Inline (Spec_Placement);
+ -- Obtain the location of invocation construct IC_Id's spec with respect to
+ -- the unit where it is declared.
+
+ function Target
+ (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id;
+ pragma Inline (Target);
+ -- Obtain the signature of the invocation relation IR_Id's target
+
--------------------------------------
-- Subprograms for Reading ALI File --
--------------------------------------
diff --git a/gcc/ada/alloc.ads b/gcc/ada/alloc.ads
index 18bf1e4a..f5faecb 100644
--- a/gcc/ada/alloc.ads
+++ b/gcc/ada/alloc.ads
@@ -116,6 +116,9 @@ package Alloc is
Rep_Table_Initial : constant := 1000; -- Repinfo
Rep_Table_Increment : constant := 200;
+ Rep_JSON_Table_Initial : constant := 10; -- Repinfo
+ Rep_JSON_Table_Increment : constant := 200;
+
Scope_Stack_Initial : constant := 10; -- Sem
Scope_Stack_Increment : constant := 200;
diff --git a/gcc/ada/argv.c b/gcc/ada/argv.c
index 3249c32..ca82ed5 100644
--- a/gcc/ada/argv.c
+++ b/gcc/ada/argv.c
@@ -43,9 +43,8 @@
Ada.Command_Line.Environment package. */
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
-#include <sys/stat.h>
+#include "runtime.h"
+#include <string.h>
#else
#include "config.h"
#include "system.h"
diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb
index 76fa6c8..54c0e56 100644
--- a/gcc/ada/aspects.adb
+++ b/gcc/ada/aspects.adb
@@ -225,7 +225,10 @@ package body Aspects is
Owner := Root_Type (Owner);
end if;
- if Is_Private_Type (Owner) and then Present (Full_View (Owner)) then
+ if Is_Private_Type (Owner)
+ and then Present (Full_View (Owner))
+ and then not Operational_Aspect (A)
+ then
Owner := Full_View (Owner);
end if;
end if;
diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
index 9190a635..2a6acc2 100644
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -277,6 +277,20 @@ package Aspects is
Aspect_Warnings => True,
others => False);
+ -- The following array indicates aspects that specify operational
+ -- characteristics, and thus are view-specific. Representation
+ -- aspects break privacy, as they are needed during expansion and
+ -- code generation.
+ -- List is currently incomplete ???
+
+ Operational_Aspect : constant array (Aspect_Id) of Boolean :=
+ (Aspect_Constant_Indexing => True,
+ Aspect_Default_Iterator => True,
+ Aspect_Iterator_Element => True,
+ Aspect_Iterable => True,
+ Aspect_Variable_Indexing => True,
+ others => False);
+
-- The following array indicates aspects for which multiple occurrences of
-- the same aspect attached to the same declaration are allowed.
diff --git a/gcc/ada/aux-io.c b/gcc/ada/aux-io.c
index b55a6f9..e022b65 100644
--- a/gcc/ada/aux-io.c
+++ b/gcc/ada/aux-io.c
@@ -31,10 +31,7 @@
#include <stdio.h>
-#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
-#else
+#ifndef IN_RTS
#include "config.h"
#include "system.h"
#endif
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index e135540..8ea8a6b 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -1810,9 +1810,11 @@ package body Bindgen is
-- with a pragma Volatile in order to tell the compiler to preserve
-- this variable at any level of optimization.
- -- CodePeer and CCG do not need this extra code on the other hand
+ -- CodePeer and CCG do not need this extra code. The code is also not
+ -- needed if the binder is in "Minimal Binder" mode.
if Bind_Main_Program
+ and then not Minimal_Binder
and then not CodePeer_Mode
and then not Generate_C_Code
then
@@ -2354,25 +2356,27 @@ package body Bindgen is
-- program uses two Ada libraries). Also zero terminate the string
-- so that its end can be found reliably at run time.
- WBI ("");
- WBI (" GNAT_Version : constant String :=");
- WBI (" """ & Ver_Prefix &
- Gnat_Version_String &
- """ & ASCII.NUL;");
- WBI (" pragma Export (C, GNAT_Version, ""__gnat_version"");");
+ if not Minimal_Binder then
+ WBI ("");
+ WBI (" GNAT_Version : constant String :=");
+ WBI (" """ & Ver_Prefix &
+ Gnat_Version_String &
+ """ & ASCII.NUL;");
+ WBI (" pragma Export (C, GNAT_Version, ""__gnat_version"");");
- WBI ("");
- Set_String (" Ada_Main_Program_Name : constant String := """);
- Get_Name_String (Units.Table (First_Unit_Entry).Uname);
+ WBI ("");
+ Set_String (" Ada_Main_Program_Name : constant String := """);
+ Get_Name_String (Units.Table (First_Unit_Entry).Uname);
- Set_Main_Program_Name;
- Set_String (""" & ASCII.NUL;");
+ Set_Main_Program_Name;
+ Set_String (""" & ASCII.NUL;");
- Write_Statement_Buffer;
+ Write_Statement_Buffer;
- WBI
- (" pragma Export (C, Ada_Main_Program_Name, " &
- """__gnat_ada_main_program_name"");");
+ WBI
+ (" pragma Export (C, Ada_Main_Program_Name, " &
+ """__gnat_ada_main_program_name"");");
+ end if;
end if;
WBI ("");
diff --git a/gcc/ada/bindo-augmentors.adb b/gcc/ada/bindo-augmentors.adb
index f97f0d0..57fb541 100644
--- a/gcc/ada/bindo-augmentors.adb
+++ b/gcc/ada/bindo-augmentors.adb
@@ -27,10 +27,9 @@ with Debug; use Debug;
with Output; use Output;
with Types; use Types;
-with Bindo.Writers; use Bindo.Writers;
-
-with GNAT; use GNAT;
-with GNAT.Sets; use GNAT.Sets;
+with Bindo.Writers;
+use Bindo.Writers;
+use Bindo.Writers.Phase_Writers;
package body Bindo.Augmentors is
@@ -40,24 +39,6 @@ package body Bindo.Augmentors is
package body Library_Graph_Augmentors is
- -----------------
- -- Visited set --
- -----------------
-
- package VS is new Membership_Sets
- (Element_Type => Invocation_Graph_Vertex_Id,
- "=" => "=",
- Hash => Hash_Invocation_Graph_Vertex);
- use VS;
-
- -----------------
- -- Global data --
- -----------------
-
- Inv_Graph : Invocation_Graph := Invocation_Graphs.Nil;
- Lib_Graph : Library_Graph := Library_Graphs.Nil;
- Visited : Membership_Set := VS.Nil;
-
----------------
-- Statistics --
----------------
@@ -74,20 +55,10 @@ package body Bindo.Augmentors is
-- Local subprograms --
-----------------------
- function Is_Visited
- (IGV_Id : Invocation_Graph_Vertex_Id) return Boolean;
- pragma Inline (Is_Visited);
- -- Determine whether invocation graph vertex IGV_Id has been visited
- -- during the traversal.
-
- procedure Set_Is_Visited
- (IGV_Id : Invocation_Graph_Vertex_Id;
- Val : Boolean := True);
- pragma Inline (Set_Is_Visited);
- -- Mark invocation graph vertex IGV_Id as visited during the traversal
- -- depending on value Val.
-
- procedure Visit_Elaboration_Root (Root : Invocation_Graph_Vertex_Id);
+ procedure Visit_Elaboration_Root
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Root : Invocation_Graph_Vertex_Id);
pragma Inline (Visit_Elaboration_Root);
-- Start a DFS traversal from elaboration root Root to:
--
@@ -96,7 +67,9 @@ package body Bindo.Augmentors is
-- * Create invocation edges for each such transition where the
-- successor is Root.
- procedure Visit_Elaboration_Roots;
+ procedure Visit_Elaboration_Roots
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph);
pragma Inline (Visit_Elaboration_Roots);
-- Start a DFS traversal from all elaboration roots to:
--
@@ -106,26 +79,30 @@ package body Bindo.Augmentors is
-- successor is the current root.
procedure Visit_Vertex
- (Curr_IGV_Id : Invocation_Graph_Vertex_Id;
- Last_LGV_Id : Library_Graph_Vertex_Id;
- Root_LGV_Id : Library_Graph_Vertex_Id;
- Internal_Ctrl : Boolean;
- Path : Natural);
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Invoker : Invocation_Graph_Vertex_Id;
+ Last_Vertex : Library_Graph_Vertex_Id;
+ Root_Vertex : Library_Graph_Vertex_Id;
+ Visited_Invokers : IGV_Sets.Membership_Set;
+ Activates_Task : Boolean;
+ Internal_Controlled_Action : Boolean;
+ Path : Natural);
pragma Inline (Visit_Vertex);
- -- Visit invocation graph vertex Curr_IGV_Id to:
+ -- Visit invocation graph vertex Invoker to:
--
-- * Detect a transition from the last library graph vertex denoted by
- -- Last_LGV_Id to the library graph vertex of Curr_IGV_Id.
+ -- Last_Vertex to the library graph vertex of Invoker.
--
-- * Create an invocation edge in library graph Lib_Graph to reflect
-- the transition, where the predecessor is the library graph vertex
- -- or Curr_IGV_Id, and the successor is Root_LGV_Id.
+ -- or Invoker, and the successor is Root_Vertex.
--
- -- * Visit the neighbours of Curr_IGV_Id.
+ -- * Visit the neighbours of Invoker.
--
- -- Flag Internal_Ctrl should be set when the DFS traversal visited an
- -- internal controlled invocation edge. Path denotes the length of the
- -- path.
+ -- Flag Internal_Controlled_Action should be set when the DFS traversal
+ -- visited an internal controlled invocation edge. Path is the length of
+ -- the path.
procedure Write_Statistics;
pragma Inline (Write_Statistics);
@@ -137,109 +114,100 @@ package body Bindo.Augmentors is
---------------------------
procedure Augment_Library_Graph
- (Inv_G : Invocation_Graph;
- Lib_G : Library_Graph)
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph)
is
begin
- pragma Assert (Present (Lib_G));
+ pragma Assert (Present (Lib_Graph));
-- Nothing to do when there is no invocation graph
- if not Present (Inv_G) then
+ if not Present (Inv_Graph) then
return;
end if;
- -- Prepare the global data. Note that Visited is initialized for each
- -- elaboration root.
+ Start_Phase (Library_Graph_Augmentation);
+
+ -- Prepare the statistics data
- Inv_Graph := Inv_G;
- Lib_Graph := Lib_G;
Longest_Path := 0;
Total_Visited := 0;
- Visit_Elaboration_Roots;
+ Visit_Elaboration_Roots (Inv_Graph, Lib_Graph);
Write_Statistics;
- end Augment_Library_Graph;
-
- ----------------
- -- Is_Visited --
- ----------------
-
- function Is_Visited
- (IGV_Id : Invocation_Graph_Vertex_Id) return Boolean
- is
- begin
- pragma Assert (Present (Visited));
- pragma Assert (Present (IGV_Id));
-
- return Contains (Visited, IGV_Id);
- end Is_Visited;
- --------------------
- -- Set_Is_Visited --
- --------------------
-
- procedure Set_Is_Visited
- (IGV_Id : Invocation_Graph_Vertex_Id;
- Val : Boolean := True)
- is
- begin
- pragma Assert (Present (Visited));
- pragma Assert (Present (IGV_Id));
-
- if Val then
- Insert (Visited, IGV_Id);
- else
- Delete (Visited, IGV_Id);
- end if;
- end Set_Is_Visited;
+ End_Phase (Library_Graph_Augmentation);
+ end Augment_Library_Graph;
----------------------------
-- Visit_Elaboration_Root --
----------------------------
- procedure Visit_Elaboration_Root (Root : Invocation_Graph_Vertex_Id) is
+ procedure Visit_Elaboration_Root
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Root : Invocation_Graph_Vertex_Id)
+ is
pragma Assert (Present (Inv_Graph));
- pragma Assert (Present (Root));
pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Root));
- Root_LGV_Id : constant Library_Graph_Vertex_Id :=
- Lib_Vertex (Inv_Graph, Root);
+ Root_Vertex : constant Library_Graph_Vertex_Id :=
+ Body_Vertex (Inv_Graph, Root);
- pragma Assert (Present (Root_LGV_Id));
+ Visited : IGV_Sets.Membership_Set;
begin
+ -- Nothing to do when the unit where the elaboration root resides
+ -- lacks elaboration code. This implies that any invocation edges
+ -- going out of the unit are unwanted. This behavior emulates the
+ -- old elaboration order mechanism.
+
+ if Has_No_Elaboration_Code (Lib_Graph, Root_Vertex) then
+ return;
+ end if;
+
-- Prepare the global data
- Visited := Create (Number_Of_Vertices (Inv_Graph));
+ Visited := IGV_Sets.Create (Number_Of_Vertices (Inv_Graph));
Visit_Vertex
- (Curr_IGV_Id => Root,
- Last_LGV_Id => Root_LGV_Id,
- Root_LGV_Id => Root_LGV_Id,
- Internal_Ctrl => False,
- Path => 0);
-
- Destroy (Visited);
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Invoker => Root,
+ Last_Vertex => Root_Vertex,
+ Root_Vertex => Root_Vertex,
+ Visited_Invokers => Visited,
+ Activates_Task => False,
+ Internal_Controlled_Action => False,
+ Path => 0);
+
+ IGV_Sets.Destroy (Visited);
end Visit_Elaboration_Root;
-----------------------------
-- Visit_Elaboration_Roots --
-----------------------------
- procedure Visit_Elaboration_Roots is
+ procedure Visit_Elaboration_Roots
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph)
+ is
Iter : Elaboration_Root_Iterator;
Root : Invocation_Graph_Vertex_Id;
begin
pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
Iter := Iterate_Elaboration_Roots (Inv_Graph);
while Has_Next (Iter) loop
Next (Iter, Root);
- pragma Assert (Present (Root));
- Visit_Elaboration_Root (Root);
+ Visit_Elaboration_Root
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Root => Root);
end loop;
end Visit_Elaboration_Roots;
@@ -248,34 +216,39 @@ package body Bindo.Augmentors is
------------------
procedure Visit_Vertex
- (Curr_IGV_Id : Invocation_Graph_Vertex_Id;
- Last_LGV_Id : Library_Graph_Vertex_Id;
- Root_LGV_Id : Library_Graph_Vertex_Id;
- Internal_Ctrl : Boolean;
- Path : Natural)
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Invoker : Invocation_Graph_Vertex_Id;
+ Last_Vertex : Library_Graph_Vertex_Id;
+ Root_Vertex : Library_Graph_Vertex_Id;
+ Visited_Invokers : IGV_Sets.Membership_Set;
+ Activates_Task : Boolean;
+ Internal_Controlled_Action : Boolean;
+ Path : Natural)
is
New_Path : constant Natural := Path + 1;
- Curr_LGV_Id : Library_Graph_Vertex_Id;
- IGE_Id : Invocation_Graph_Edge_Id;
- Iter : Edges_To_Targets_Iterator;
- Targ : Invocation_Graph_Vertex_Id;
+ Edge : Invocation_Graph_Edge_Id;
+ Edge_Kind : Invocation_Kind;
+ Invoker_Vertex : Library_Graph_Vertex_Id;
+ Iter : Edges_To_Targets_Iterator;
begin
pragma Assert (Present (Inv_Graph));
- pragma Assert (Present (Curr_IGV_Id));
pragma Assert (Present (Lib_Graph));
- pragma Assert (Present (Last_LGV_Id));
- pragma Assert (Present (Root_LGV_Id));
+ pragma Assert (Present (Invoker));
+ pragma Assert (Present (Last_Vertex));
+ pragma Assert (Present (Root_Vertex));
+ pragma Assert (IGV_Sets.Present (Visited_Invokers));
-- Nothing to do when the current invocation graph vertex has already
-- been visited.
- if Is_Visited (Curr_IGV_Id) then
+ if IGV_Sets.Contains (Visited_Invokers, Invoker) then
return;
end if;
- Set_Is_Visited (Curr_IGV_Id);
+ IGV_Sets.Insert (Visited_Invokers, Invoker);
-- Update the statistics
@@ -287,10 +260,10 @@ package body Bindo.Augmentors is
-- indicates that elaboration is transitioning from one unit to
-- another. Add a library graph edge to capture this dependency.
- Curr_LGV_Id := Lib_Vertex (Inv_Graph, Curr_IGV_Id);
- pragma Assert (Present (Curr_LGV_Id));
+ Invoker_Vertex := Body_Vertex (Inv_Graph, Invoker);
+ pragma Assert (Present (Invoker_Vertex));
- if Curr_LGV_Id /= Last_LGV_Id then
+ if Invoker_Vertex /= Last_Vertex then
-- The path ultimately reaches back into the unit where the root
-- resides, resulting in a self dependency. In most cases this is
@@ -299,7 +272,9 @@ package body Bindo.Augmentors is
-- library graph edge because the circularity is the result of
-- expansion and thus spurious.
- if Curr_LGV_Id = Root_LGV_Id and then Internal_Ctrl then
+ if Invoker_Vertex = Root_Vertex
+ and then Internal_Controlled_Action
+ then
null;
-- Otherwise create the library graph edge, even if this results
@@ -307,33 +282,36 @@ package body Bindo.Augmentors is
else
Add_Edge
- (G => Lib_Graph,
- Pred => Curr_LGV_Id,
- Succ => Root_LGV_Id,
- Kind => Invocation_Edge);
+ (G => Lib_Graph,
+ Pred => Invoker_Vertex,
+ Succ => Root_Vertex,
+ Kind => Invocation_Edge,
+ Activates_Task => Activates_Task);
end if;
end if;
-- Extend the DFS traversal to all targets of the invocation graph
-- vertex.
- Iter := Iterate_Edges_To_Targets (Inv_Graph, Curr_IGV_Id);
+ Iter := Iterate_Edges_To_Targets (Inv_Graph, Invoker);
while Has_Next (Iter) loop
- Next (Iter, IGE_Id);
- pragma Assert (Present (IGE_Id));
-
- Targ := Target (Inv_Graph, IGE_Id);
- pragma Assert (Present (Targ));
+ Next (Iter, Edge);
+ Edge_Kind := Kind (Inv_Graph, Edge);
Visit_Vertex
- (Curr_IGV_Id => Targ,
- Last_LGV_Id => Curr_LGV_Id,
- Root_LGV_Id => Root_LGV_Id,
- Internal_Ctrl =>
- Internal_Ctrl
- or else Kind (Inv_Graph, IGE_Id) in
- Internal_Controlled_Invocation_Kind,
- Path => New_Path);
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Invoker => Target (Inv_Graph, Edge),
+ Last_Vertex => Invoker_Vertex,
+ Root_Vertex => Root_Vertex,
+ Visited_Invokers => Visited_Invokers,
+ Activates_Task =>
+ Activates_Task
+ or else Edge_Kind = Task_Activation,
+ Internal_Controlled_Action =>
+ Internal_Controlled_Action
+ or else Edge_Kind in Internal_Controlled_Invocation_Kind,
+ Path => New_Path);
end loop;
end Visit_Vertex;
diff --git a/gcc/ada/bindo-augmentors.ads b/gcc/ada/bindo-augmentors.ads
index de6317c..c00d5c0 100644
--- a/gcc/ada/bindo-augmentors.ads
+++ b/gcc/ada/bindo-augmentors.ads
@@ -43,10 +43,10 @@ package Bindo.Augmentors is
package Library_Graph_Augmentors is
procedure Augment_Library_Graph
- (Inv_G : Invocation_Graph;
- Lib_G : Library_Graph);
- -- Augment library graph Lib_G with information from invocation graph
- -- Inv_G as follows:
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph);
+ -- Augment library graph Lib_Graph with information from invocation
+ -- graph Inv_Graph as follows:
--
-- 1) Traverse the invocation graph starting from each elaboration
-- procedure of unit Root.
diff --git a/gcc/ada/bindo-builders.adb b/gcc/ada/bindo-builders.adb
index c0340c0..9919007 100644
--- a/gcc/ada/bindo-builders.adb
+++ b/gcc/ada/bindo-builders.adb
@@ -25,12 +25,22 @@
with Binderr; use Binderr;
with Butil; use Butil;
+with Debug; use Debug;
with Opt; use Opt;
with Output; use Output;
with Types; use Types;
with Bindo.Units; use Bindo.Units;
+with Bindo.Validators;
+use Bindo.Validators;
+use Bindo.Validators.Invocation_Graph_Validators;
+use Bindo.Validators.Library_Graph_Validators;
+
+with Bindo.Writers;
+use Bindo.Writers;
+use Bindo.Writers.Phase_Writers;
+
with GNAT; use GNAT;
with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
@@ -64,10 +74,10 @@ package body Bindo.Builders is
procedure Create_Vertex
(IC_Id : Invocation_Construct_Id;
- LGV_Id : Library_Graph_Vertex_Id);
+ Vertex : Library_Graph_Vertex_Id);
pragma Inline (Create_Vertex);
-- Create a new vertex for invocation construct IC_Id in invocation
- -- graph Inv_Graph. The vertex is linked to vertex LGV_Id of library
+ -- graph Inv_Graph. The vertex is linked to vertex Vertex of library
-- graph Lib_Graph.
procedure Create_Vertices (U_Id : Unit_Id);
@@ -75,6 +85,14 @@ package body Bindo.Builders is
-- Create new vertices for all invocation constructs of unit U_Id in
-- invocation graph Inv_Graph.
+ function Declaration_Placement_Vertex
+ (Vertex : Library_Graph_Vertex_Id;
+ Placement : Declaration_Placement_Kind)
+ return Library_Graph_Vertex_Id;
+ pragma Inline (Declaration_Placement_Vertex);
+ -- Obtain the spec or body of vertex Vertex depending on the requested
+ -- placement in Placement.
+
----------------------------
-- Build_Invocation_Graph --
----------------------------
@@ -85,16 +103,22 @@ package body Bindo.Builders is
begin
pragma Assert (Present (Lib_G));
+ Start_Phase (Invocation_Graph_Construction);
+
-- Prepare the global data
Inv_Graph :=
- Create (Initial_Vertices => Number_Of_Elaborable_Units,
- Initial_Edges => Number_Of_Elaborable_Units);
+ Create
+ (Initial_Vertices => Number_Of_Elaborable_Units,
+ Initial_Edges => Number_Of_Elaborable_Units);
Lib_Graph := Lib_G;
For_Each_Elaborable_Unit (Create_Vertices'Access);
For_Each_Elaborable_Unit (Create_Edges'Access);
+ Validate_Invocation_Graph (Inv_Graph);
+ End_Phase (Invocation_Graph_Construction);
+
return Inv_Graph;
end Build_Invocation_Graph;
@@ -107,33 +131,24 @@ package body Bindo.Builders is
pragma Assert (Present (Lib_Graph));
pragma Assert (Present (IR_Id));
- IR_Rec : Invocation_Relation_Record renames
- Invocation_Relations.Table (IR_Id);
+ Invoker_Sig : constant Invocation_Signature_Id := Invoker (IR_Id);
+ Target_Sig : constant Invocation_Signature_Id := Target (IR_Id);
- pragma Assert (Present (IR_Rec.Invoker));
- pragma Assert (Present (IR_Rec.Target));
-
- Invoker : Invocation_Graph_Vertex_Id;
- Target : Invocation_Graph_Vertex_Id;
+ pragma Assert (Present (Invoker_Sig));
+ pragma Assert (Present (Target_Sig));
begin
-- Nothing to do when the target denotes an invocation construct that
-- resides in a unit which will never be elaborated.
- if not Needs_Elaboration (IR_Rec.Target) then
+ if not Needs_Elaboration (Target_Sig) then
return;
end if;
- Invoker := Corresponding_Vertex (Inv_Graph, IR_Rec.Invoker);
- Target := Corresponding_Vertex (Inv_Graph, IR_Rec.Target);
-
- pragma Assert (Present (Invoker));
- pragma Assert (Present (Target));
-
Add_Edge
(G => Inv_Graph,
- Source => Invoker,
- Target => Target,
+ Source => Corresponding_Vertex (Inv_Graph, Invoker_Sig),
+ Target => Corresponding_Vertex (Inv_Graph, Target_Sig),
IR_Id => IR_Id);
end Create_Edge;
@@ -162,35 +177,25 @@ package body Bindo.Builders is
procedure Create_Vertex
(IC_Id : Invocation_Construct_Id;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id)
is
+ begin
pragma Assert (Present (Inv_Graph));
pragma Assert (Present (Lib_Graph));
pragma Assert (Present (IC_Id));
- pragma Assert (Present (LGV_Id));
-
- IC_Rec : Invocation_Construct_Record renames
- Invocation_Constructs.Table (IC_Id);
-
- Body_LGV_Id : Library_Graph_Vertex_Id;
-
- begin
- -- Determine the proper library graph vertex which holds the body of
- -- the invocation construct.
-
- if IC_Rec.Placement = In_Body then
- Body_LGV_Id := Proper_Body (Lib_Graph, LGV_Id);
- else
- pragma Assert (IC_Rec.Placement = In_Spec);
- Body_LGV_Id := Proper_Spec (Lib_Graph, LGV_Id);
- end if;
-
- pragma Assert (Present (Body_LGV_Id));
+ pragma Assert (Present (Vertex));
Add_Vertex
- (G => Inv_Graph,
- IC_Id => IC_Id,
- LGV_Id => Body_LGV_Id);
+ (G => Inv_Graph,
+ IC_Id => IC_Id,
+ Body_Vertex =>
+ Declaration_Placement_Vertex
+ (Vertex => Vertex,
+ Placement => Body_Placement (IC_Id)),
+ Spec_Vertex =>
+ Declaration_Placement_Vertex
+ (Vertex => Vertex,
+ Placement => Spec_Placement (IC_Id)));
end Create_Vertex;
---------------------
@@ -203,18 +208,37 @@ package body Bindo.Builders is
pragma Assert (Present (U_Id));
U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
- LGV_Id : constant Library_Graph_Vertex_Id :=
+ Vertex : constant Library_Graph_Vertex_Id :=
Corresponding_Vertex (Lib_Graph, U_Id);
- pragma Assert (Present (LGV_Id));
-
begin
for IC_Id in U_Rec.First_Invocation_Construct ..
U_Rec.Last_Invocation_Construct
loop
- Create_Vertex (IC_Id, LGV_Id);
+ Create_Vertex (IC_Id, Vertex);
end loop;
end Create_Vertices;
+
+ ----------------------------------
+ -- Declaration_Placement_Vertex --
+ ----------------------------------
+
+ function Declaration_Placement_Vertex
+ (Vertex : Library_Graph_Vertex_Id;
+ Placement : Declaration_Placement_Kind)
+ return Library_Graph_Vertex_Id
+ is
+ begin
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Vertex));
+
+ if Placement = In_Body then
+ return Proper_Body (Lib_Graph, Vertex);
+ else
+ pragma Assert (Placement = In_Spec);
+ return Proper_Spec (Lib_Graph, Vertex);
+ end if;
+ end Declaration_Placement_Vertex;
end Invocation_Graph_Builders;
----------------------------
@@ -235,7 +259,7 @@ package body Bindo.Builders is
pragma Inline (Hash_Unit);
-- Obtain the hash value of key U_Id
- package UL is new Dynamic_Hash_Tables
+ package Unit_Line_Tables is new Dynamic_Hash_Tables
(Key_Type => Unit_Id,
Value_Type => Logical_Line_Number,
No_Value => No_Line_Number,
@@ -253,9 +277,10 @@ package body Bindo.Builders is
Lib_Graph : Library_Graph := Library_Graphs.Nil;
- Unit_To_Line : UL.Dynamic_Hash_Table := UL.Nil;
+ Unit_To_Line : Unit_Line_Tables.Dynamic_Hash_Table :=
+ Unit_Line_Tables.Nil;
-- The map of unit name -> line number, used to detect duplicate unit
- -- names and report errors.
+ -- names in the forced-elaboration-order file and report errors.
-----------------------
-- Local subprograms --
@@ -348,7 +373,7 @@ package body Bindo.Builders is
begin
pragma Assert (Present (U_Id));
- UL.Put (Unit_To_Line, U_Id, Line);
+ Unit_Line_Tables.Put (Unit_To_Line, U_Id, Line);
end Add_Unit;
-------------------------
@@ -357,18 +382,23 @@ package body Bindo.Builders is
function Build_Library_Graph return Library_Graph is
begin
+ Start_Phase (Library_Graph_Construction);
+
-- Prepare the global data
Lib_Graph :=
- Create (Initial_Vertices => Number_Of_Elaborable_Units,
- Initial_Edges => Number_Of_Elaborable_Units);
+ Create
+ (Initial_Vertices => Number_Of_Elaborable_Units,
+ Initial_Edges => Number_Of_Elaborable_Units);
For_Each_Elaborable_Unit (Create_Vertex'Access);
For_Each_Elaborable_Unit (Create_Spec_And_Body_Edge'Access);
For_Each_Elaborable_Unit (Create_With_Edges'Access);
-
Create_Forced_Edges;
+ Validate_Library_Graph (Lib_Graph);
+ End_Phase (Library_Graph_Construction);
+
return Lib_Graph;
end Build_Library_Graph;
@@ -383,14 +413,11 @@ package body Bindo.Builders is
pragma Assert (Present (Pred));
pragma Assert (Present (Succ));
- Pred_LGV_Id : constant Library_Graph_Vertex_Id :=
+ Pred_Vertex : constant Library_Graph_Vertex_Id :=
Corresponding_Vertex (Lib_Graph, Pred);
- Succ_LGV_Id : constant Library_Graph_Vertex_Id :=
+ Succ_Vertex : constant Library_Graph_Vertex_Id :=
Corresponding_Vertex (Lib_Graph, Succ);
- pragma Assert (Present (Pred_LGV_Id));
- pragma Assert (Present (Succ_LGV_Id));
-
begin
Write_Unit_Name (Name (Pred));
Write_Str (" <-- ");
@@ -398,10 +425,11 @@ package body Bindo.Builders is
Write_Eol;
Add_Edge
- (G => Lib_Graph,
- Pred => Pred_LGV_Id,
- Succ => Succ_LGV_Id,
- Kind => Forced_Edge);
+ (G => Lib_Graph,
+ Pred => Pred_Vertex,
+ Succ => Succ_Vertex,
+ Kind => Forced_Edge,
+ Activates_Task => False);
end Create_Forced_Edge;
-------------------------
@@ -409,15 +437,15 @@ package body Bindo.Builders is
-------------------------
procedure Create_Forced_Edges is
- Curr_Unit : Unit_Id;
- Iter : Forced_Units_Iterator;
- Prev_Unit : Unit_Id;
- Unit_Line : Logical_Line_Number;
- Unit_Name : Unit_Name_Type;
+ Current_Unit : Unit_Id;
+ Iter : Forced_Units_Iterator;
+ Previous_Unit : Unit_Id;
+ Unit_Line : Logical_Line_Number;
+ Unit_Name : Unit_Name_Type;
begin
- Prev_Unit := No_Unit_Id;
- Unit_To_Line := UL.Create (20);
+ Previous_Unit := No_Unit_Id;
+ Unit_To_Line := Unit_Line_Tables.Create (20);
-- Inspect the contents of the forced-elaboration-order file supplied
-- to the binder using switch -f, and diagnose each unit accordingly.
@@ -425,36 +453,35 @@ package body Bindo.Builders is
Iter := Iterate_Forced_Units;
while Has_Next (Iter) loop
Next (Iter, Unit_Name, Unit_Line);
- pragma Assert (Present (Unit_Name));
- Curr_Unit := Corresponding_Unit (Unit_Name);
+ Current_Unit := Corresponding_Unit (Unit_Name);
- if not Present (Curr_Unit) then
+ if not Present (Current_Unit) then
Missing_Unit_Info (Unit_Name);
- elsif Is_Internal_Unit (Curr_Unit) then
+ elsif Is_Internal_Unit (Current_Unit) then
Internal_Unit_Info (Unit_Name);
- elsif Is_Duplicate_Unit (Curr_Unit) then
- Duplicate_Unit_Error (Curr_Unit, Unit_Name, Unit_Line);
+ elsif Is_Duplicate_Unit (Current_Unit) then
+ Duplicate_Unit_Error (Current_Unit, Unit_Name, Unit_Line);
-- Otherwise the unit is a valid candidate for a vertex. Create a
-- forced edge between each pair of units.
else
- Add_Unit (Curr_Unit, Unit_Line);
+ Add_Unit (Current_Unit, Unit_Line);
- if Present (Prev_Unit) then
+ if Present (Previous_Unit) then
Create_Forced_Edge
- (Pred => Prev_Unit,
- Succ => Curr_Unit);
+ (Pred => Previous_Unit,
+ Succ => Current_Unit);
end if;
- Prev_Unit := Curr_Unit;
+ Previous_Unit := Current_Unit;
end if;
end loop;
- UL.Destroy (Unit_To_Line);
+ Unit_Line_Tables.Destroy (Unit_To_Line);
end Create_Forced_Edges;
-------------------------------
@@ -462,42 +489,38 @@ package body Bindo.Builders is
-------------------------------
procedure Create_Spec_And_Body_Edge (U_Id : Unit_Id) is
- Aux_LGV_Id : Library_Graph_Vertex_Id;
- LGV_Id : Library_Graph_Vertex_Id;
+ Extra_Vertex : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
begin
pragma Assert (Present (Lib_Graph));
pragma Assert (Present (U_Id));
- LGV_Id := Corresponding_Vertex (Lib_Graph, U_Id);
- pragma Assert (Present (LGV_Id));
+ Vertex := Corresponding_Vertex (Lib_Graph, U_Id);
-- The unit denotes a body that completes a previous spec. Link the
-- spec and body. Add an edge between the predecessor spec and the
-- successor body.
- if Is_Body_With_Spec (Lib_Graph, LGV_Id) then
- Aux_LGV_Id :=
+ if Is_Body_With_Spec (Lib_Graph, Vertex) then
+ Extra_Vertex :=
Corresponding_Vertex (Lib_Graph, Corresponding_Spec (U_Id));
- pragma Assert (Present (Aux_LGV_Id));
-
- Set_Corresponding_Item (Lib_Graph, LGV_Id, Aux_LGV_Id);
+ Set_Corresponding_Item (Lib_Graph, Vertex, Extra_Vertex);
Add_Edge
- (G => Lib_Graph,
- Pred => Aux_LGV_Id,
- Succ => LGV_Id,
- Kind => Spec_Before_Body_Edge);
+ (G => Lib_Graph,
+ Pred => Extra_Vertex,
+ Succ => Vertex,
+ Kind => Spec_Before_Body_Edge,
+ Activates_Task => False);
-- The unit denotes a spec with a completing body. Link the spec and
-- body.
- elsif Is_Spec_With_Body (Lib_Graph, LGV_Id) then
- Aux_LGV_Id :=
+ elsif Is_Spec_With_Body (Lib_Graph, Vertex) then
+ Extra_Vertex :=
Corresponding_Vertex (Lib_Graph, Corresponding_Body (U_Id));
- pragma Assert (Present (Aux_LGV_Id));
-
- Set_Corresponding_Item (Lib_Graph, LGV_Id, Aux_LGV_Id);
+ Set_Corresponding_Item (Lib_Graph, Vertex, Extra_Vertex);
end if;
end Create_Spec_And_Body_Edge;
@@ -531,11 +554,8 @@ package body Bindo.Builders is
Withed_U_Id : constant Unit_Id :=
Corresponding_Unit (Withed_Rec.Uname);
- pragma Assert (Present (Withed_U_Id));
-
- Aux_LGV_Id : Library_Graph_Vertex_Id;
Kind : Library_Graph_Edge_Kind;
- Withed_LGV_Id : Library_Graph_Vertex_Id;
+ Withed_Vertex : Library_Graph_Vertex_Id;
begin
-- Nothing to do when the withed unit does not need to be elaborated.
@@ -545,34 +565,39 @@ package body Bindo.Builders is
return;
end if;
- Withed_LGV_Id := Corresponding_Vertex (Lib_Graph, Withed_U_Id);
- pragma Assert (Present (Withed_LGV_Id));
+ Withed_Vertex := Corresponding_Vertex (Lib_Graph, Withed_U_Id);
- -- The with comes with pragma Elaborate
+ -- The with comes with pragma Elaborate. Treat the edge as a with
+ -- edge when switch -d_e (ignore the effects of pragma Elaborate)
+ -- is in effect.
- if Withed_Rec.Elaborate then
+ if Withed_Rec.Elaborate
+ and then not Debug_Flag_Underscore_E
+ then
Kind := Elaborate_Edge;
-- The withed unit is a spec with a completing body. Add an edge
-- between the body of the withed predecessor and the withing
-- successor.
- if Is_Spec_With_Body (Lib_Graph, Withed_LGV_Id) then
- Aux_LGV_Id :=
- Corresponding_Vertex
- (Lib_Graph, Corresponding_Body (Withed_U_Id));
- pragma Assert (Present (Aux_LGV_Id));
-
+ if Is_Spec_With_Body (Lib_Graph, Withed_Vertex) then
Add_Edge
- (G => Lib_Graph,
- Pred => Aux_LGV_Id,
- Succ => Succ,
- Kind => Kind);
+ (G => Lib_Graph,
+ Pred =>
+ Corresponding_Vertex
+ (Lib_Graph, Corresponding_Body (Withed_U_Id)),
+ Succ => Succ,
+ Kind => Kind,
+ Activates_Task => False);
end if;
- -- The with comes with pragma Elaborate_All
+ -- The with comes with pragma Elaborate_All. Treat the edge as a with
+ -- edge when switch -d_a (ignore the effects of pragma Elaborate_All)
+ -- is in effect.
- elsif Withed_Rec.Elaborate_All then
+ elsif Withed_Rec.Elaborate_All
+ and then not Debug_Flag_Underscore_A
+ then
Kind := Elaborate_All_Edge;
-- Otherwise this is a regular with
@@ -585,10 +610,11 @@ package body Bindo.Builders is
-- successor.
Add_Edge
- (G => Lib_Graph,
- Pred => Withed_LGV_Id,
- Succ => Succ,
- Kind => Kind);
+ (G => Lib_Graph,
+ Pred => Withed_Vertex,
+ Succ => Succ,
+ Kind => Kind,
+ Activates_Task => False);
end Create_With_Edge;
-----------------------
@@ -596,18 +622,13 @@ package body Bindo.Builders is
-----------------------
procedure Create_With_Edges (U_Id : Unit_Id) is
- LGV_Id : Library_Graph_Vertex_Id;
-
begin
pragma Assert (Present (Lib_Graph));
pragma Assert (Present (U_Id));
- LGV_Id := Corresponding_Vertex (Lib_Graph, U_Id);
- pragma Assert (Present (LGV_Id));
-
Create_With_Edges
(U_Id => U_Id,
- Succ => LGV_Id);
+ Succ => Corresponding_Vertex (Lib_Graph, U_Id));
end Create_With_Edges;
-----------------------
@@ -655,7 +676,7 @@ package body Bindo.Builders is
pragma Assert (Present (Nam));
Prev_Line : constant Logical_Line_Number :=
- UL.Get (Unit_To_Line, U_Id);
+ Unit_Line_Tables.Get (Unit_To_Line, U_Id);
begin
Error_Msg_Nat_1 := Nat (Line);
@@ -698,7 +719,7 @@ package body Bindo.Builders is
begin
pragma Assert (Present (U_Id));
- return UL.Contains (Unit_To_Line, U_Id);
+ return Unit_Line_Tables.Contains (Unit_To_Line, U_Id);
end Is_Duplicate_Unit;
-------------------------
diff --git a/gcc/ada/bindo-diagnostics.adb b/gcc/ada/bindo-diagnostics.adb
index bf11d39..6f19ac0 100644
--- a/gcc/ada/bindo-diagnostics.adb
+++ b/gcc/ada/bindo-diagnostics.adb
@@ -23,50 +23,1533 @@
-- --
------------------------------------------------------------------------------
+with Binderr; use Binderr;
+with Debug; use Debug;
+with Restrict; use Restrict;
+with Rident; use Rident;
+with Types; use Types;
+
+with Bindo.Validators;
+use Bindo.Validators;
+use Bindo.Validators.Cycle_Validators;
+
+with Bindo.Writers;
+use Bindo.Writers;
+use Bindo.Writers.Cycle_Writers;
+use Bindo.Writers.Phase_Writers;
+
package body Bindo.Diagnostics is
-----------------------
- -- Cycle_Diagnostics --
+ -- Local subprograms --
+ -----------------------
+
+ procedure Diagnose_All_Cycles
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph);
+ pragma Inline (Diagnose_All_Cycles);
+ -- Emit diagnostics for all cycles of library graph G
+
+ procedure Diagnose_Cycle
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id);
+ pragma Inline (Diagnose_Cycle);
+ -- Emit diagnostics for cycle Cycle of library graph G
+
+ procedure Find_And_Output_Invocation_Paths
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Destination : Library_Graph_Vertex_Id);
+ pragma Inline (Find_And_Output_Invocation_Paths);
+ -- Find all paths in invocation graph Inv_Graph that originate from vertex
+ -- Source and reach vertex Destination of library graph Lib_Graph. Output
+ -- the transitions of each such path.
+
+ function Find_Elaboration_Root
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Invocation_Graph_Vertex_Id;
+ pragma Inline (Find_Elaboration_Root);
+ -- Find the elaboration root in invocation graph Inv_Graph that corresponds
+ -- to vertex Vertex of library graph Lib_Graph.
+
+ procedure Output_All_Cycles_Suggestions (G : Library_Graph);
+ pragma Inline (Output_All_Cycles_Suggestions);
+ -- Suggest the diagnostic of all cycles in library graph G if circumstances
+ -- allow it.
+
+ procedure Output_Elaborate_All_Suggestions
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id);
+ pragma Inline (Output_Elaborate_All_Suggestions);
+ -- Suggest ways to break a cycle that involves an Elaborate_All edge that
+ -- links predecessor Pred and successor Succ of library graph G.
+
+ procedure Output_Elaborate_All_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id);
+ pragma Inline (Output_Elaborate_All_Transition);
+ -- Output a transition through an Elaborate_All edge of library graph G
+ -- with successor Source and predecessor Actual_Destination. Parameter
+ -- Expected_Destination denotes the predecessor as specified by the next
+ -- edge in a cycle.
+
+ procedure Output_Elaborate_Body_Suggestions
+ (G : Library_Graph;
+ Succ : Library_Graph_Vertex_Id);
+ pragma Inline (Output_Elaborate_Body_Suggestions);
+ -- Suggest ways to break a cycle that involves an edge where successor Succ
+ -- is either a spec subject to pragma Elaborate_Body or the body of such a
+ -- spec.
+
+ procedure Output_Elaborate_Body_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean);
+ pragma Inline (Output_Elaborate_Body_Transition);
+ -- Output a transition through an edge of library graph G with successor
+ -- Source and predecessor Actual_Destination. Vertex Source is either
+ -- a spec subject to pragma Elaborate_Body or denotes the body of such
+ -- a spec. Expected_Destination denotes the predecessor as specified by
+ -- the next edge in a cycle. Elaborate_All_Active should be set when the
+ -- transition occurs within a cycle that involves an Elaborate_All edge.
+
+ procedure Output_Elaborate_Suggestions
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id);
+ pragma Inline (Output_Elaborate_Suggestions);
+ -- Suggest ways to break a cycle that involves an Elaborate edge that links
+ -- predecessor Pred and successor Succ of library graph G.
+
+ procedure Output_Elaborate_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id);
+ pragma Inline (Output_Elaborate_Transition);
+ -- Output a transition through an Elaborate edge of library graph G
+ -- with successor Source and predecessor Actual_Destination. Parameter
+ -- Expected_Destination denotes the predecessor as specified by the next
+ -- edge in a cycle.
+
+ procedure Output_Forced_Suggestions
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id);
+ pragma Inline (Output_Forced_Suggestions);
+ -- Suggest ways to break a cycle that involves a Forced edge that links
+ -- predecessor Pred with successor Succ of library graph G.
+
+ procedure Output_Forced_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean);
+ pragma Inline (Output_Forced_Transition);
+ -- Output a transition through a Forced edge of library graph G with
+ -- successor Source and predecessor Actual_Destination. Parameter
+ -- Expected_Destination denotes the predecessor as specified by the
+ -- next edge in a cycle. Elaborate_All_Active should be set when the
+ -- transition occurs within a cycle that involves an Elaborate_All edge.
+
+ procedure Output_Full_Encoding_Suggestions
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ First_Edge : Library_Graph_Edge_Id);
+ pragma Inline (Output_Full_Encoding_Suggestions);
+ -- Suggest the use of the full path invocation graph encoding to break
+ -- cycle Cycle with initial edge First_Edge of library graph G.
+
+ procedure Output_Invocation_Path
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Elaborated_Vertex : Library_Graph_Vertex_Id;
+ Path : IGE_Lists.Doubly_Linked_List;
+ Path_Id : in out Nat);
+ pragma Inline (Output_Invocation_Path);
+ -- Output path Path, which consists of invocation graph Inv_Graph edges.
+ -- Elaborated_Vertex is the vertex of library graph Lib_Graph whose
+ -- elaboration initiated the path. Path_Id is the unique id of the path.
+
+ procedure Output_Invocation_Path_Transition
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Edge : Invocation_Graph_Edge_Id);
+ pragma Inline (Output_Invocation_Path_Transition);
+ -- Output a transition through edge Edge of invocation graph G, which is
+ -- part of an invocation path. Lib_Graph is the related library graph.
+
+ procedure Output_Invocation_Related_Suggestions
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id);
+ pragma Inline (Output_Invocation_Related_Suggestions);
+ -- Suggest ways to break cycle Cycle of library graph G that involves at
+ -- least one invocation edge.
+
+ procedure Output_Invocation_Transition
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Destination : Library_Graph_Vertex_Id);
+ pragma Inline (Output_Invocation_Transition);
+ -- Output a transition through an invocation edge of library graph G with
+ -- successor Source and predecessor Destination. Inv_Graph is the related
+ -- invocation graph.
+
+ procedure Output_Reason_And_Circularity_Header
+ (G : Library_Graph;
+ First_Edge : Library_Graph_Edge_Id);
+ pragma Inline (Output_Reason_And_Circularity_Header);
+ -- Output the reason and circularity header for a circularity of library
+ -- graph G with initial edge First_Edge.
+
+ procedure Output_Suggestions
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ First_Edge : Library_Graph_Edge_Id);
+ pragma Inline (Output_Suggestions);
+ -- Suggest various ways to break cycle Cycle with initial edge First_Edge
+ -- of library graph G.
+
+ procedure Output_Transition
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Current_Edge : Library_Graph_Edge_Id;
+ Next_Edge : Library_Graph_Edge_Id;
+ Elaborate_All_Active : Boolean);
+ pragma Inline (Output_Transition);
+ -- Output a transition described by edge Current_Edge, which is followed by
+ -- edge Next_Edge of library graph Lib_Graph. Inv_Graph denotes the related
+ -- invocation graph. Elaborate_All_Active should be set when the transition
+ -- occurs within a cycle that involves an Elaborate_All edge.
+
+ procedure Output_With_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean);
+ pragma Inline (Output_With_Transition);
+ -- Output a transition through a regular with edge of library graph G
+ -- with successor Source and predecessor Actual_Destination. Parameter
+ -- Expected_Destination denotes the predecessor as specified by the next
+ -- edge in a cycle. Elaborate_All_Active should be set when the transition
+ -- occurs within a cycle that involves an Elaborate_All edge.
+
+ procedure Visit_Vertex
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Invoker : Invocation_Graph_Vertex_Id;
+ Invoker_Vertex : Library_Graph_Vertex_Id;
+ Last_Vertex : Library_Graph_Vertex_Id;
+ Elaborated_Vertex : Library_Graph_Vertex_Id;
+ End_Vertex : Library_Graph_Vertex_Id;
+ Visited_Invokers : IGV_Sets.Membership_Set;
+ Path : IGE_Lists.Doubly_Linked_List;
+ Path_Id : in out Nat);
+ pragma Inline (Visit_Vertex);
+ -- Visit invocation graph vertex Invoker that resides in library graph
+ -- vertex Invoker_Vertex as part of a DFS traversal. Last_Vertex denotes
+ -- the previous vertex in the traversal. Elaborated_Vertex is the vertex
+ -- whose elaboration started the traversal. End_Vertex is the vertex that
+ -- terminates the traversal. Visited_Invoker is the set of all invokers
+ -- visited so far. All edges along the path are recorded in Path. Path_Id
+ -- is the id of the path.
+
+ -------------------------
+ -- Diagnose_All_Cycles --
+ -------------------------
+
+ procedure Diagnose_All_Cycles
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph)
+ is
+ Cycle : Library_Graph_Cycle_Id;
+ Iter : All_Cycle_Iterator;
+
+ begin
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+
+ Iter := Iterate_All_Cycles (Lib_Graph);
+ while Has_Next (Iter) loop
+ Next (Iter, Cycle);
+
+ Diagnose_Cycle
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Cycle => Cycle);
+ end loop;
+ end Diagnose_All_Cycles;
+
+ ----------------------------
+ -- Diagnose_Circularities --
+ ----------------------------
+
+ procedure Diagnose_Circularities
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph)
+ is
+ begin
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+
+ -- Find, validate, and output all cycles of the library graph
+
+ Find_Cycles (Lib_Graph);
+ Validate_Cycles (Lib_Graph);
+ Write_Cycles (Lib_Graph);
+
+ -- Diagnose all cycles in the graph regardless of their importance when
+ -- switch -d_C (diagnose all cycles) is in effect.
+
+ if Debug_Flag_Underscore_CC then
+ Diagnose_All_Cycles (Inv_Graph, Lib_Graph);
+
+ -- Otherwise diagnose the most important cycle in the graph
+
+ else
+ Diagnose_Cycle
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Cycle => Highest_Precedence_Cycle (Lib_Graph));
+ end if;
+ end Diagnose_Circularities;
+
+ --------------------
+ -- Diagnose_Cycle --
+ --------------------
+
+ procedure Diagnose_Cycle
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id)
+ is
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Cycle));
+
+ Elaborate_All_Active : constant Boolean :=
+ Contains_Elaborate_All_Edge
+ (G => Lib_Graph,
+ Cycle => Cycle);
+
+ Current_Edge : Library_Graph_Edge_Id;
+ First_Edge : Library_Graph_Edge_Id;
+ Iter : Edges_Of_Cycle_Iterator;
+ Next_Edge : Library_Graph_Edge_Id;
+
+ begin
+ Start_Phase (Cycle_Diagnostics);
+
+ First_Edge := No_Library_Graph_Edge;
+
+ -- Inspect the edges of the cycle in pairs, emitting diagnostics based
+ -- on their successors and predecessors.
+
+ Iter := Iterate_Edges_Of_Cycle (Lib_Graph, Cycle);
+ while Has_Next (Iter) loop
+
+ -- Emit the reason for the cycle using the initial edge, which is the
+ -- most important edge in the cycle.
+
+ if not Present (First_Edge) then
+ Next (Iter, Current_Edge);
+
+ First_Edge := Current_Edge;
+ Output_Reason_And_Circularity_Header
+ (G => Lib_Graph,
+ First_Edge => First_Edge);
+ end if;
+
+ -- Obtain the other edge of the pair
+
+ exit when not Has_Next (Iter);
+ Next (Iter, Next_Edge);
+
+ -- Describe the transition from the current edge to the next edge by
+ -- taking into account the predecessors and successors involved, as
+ -- well as the nature of the edge.
+
+ Output_Transition
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Current_Edge => Current_Edge,
+ Next_Edge => Next_Edge,
+ Elaborate_All_Active => Elaborate_All_Active);
+
+ Current_Edge := Next_Edge;
+ end loop;
+
+ -- Describe the transition from the last edge to the first edge
+
+ Output_Transition
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Current_Edge => Current_Edge,
+ Next_Edge => First_Edge,
+ Elaborate_All_Active => Elaborate_All_Active);
+
+ -- Suggest various alternatives for breaking the cycle
+
+ Output_Suggestions
+ (G => Lib_Graph,
+ Cycle => Cycle,
+ First_Edge => First_Edge);
+
+ End_Phase (Cycle_Diagnostics);
+ end Diagnose_Cycle;
+
+ --------------------------------------
+ -- Find_And_Output_Invocation_Paths --
+ --------------------------------------
+
+ procedure Find_And_Output_Invocation_Paths
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Destination : Library_Graph_Vertex_Id)
+ is
+ Path : IGE_Lists.Doubly_Linked_List;
+ Path_Id : Nat;
+ Visited : IGV_Sets.Membership_Set;
+
+ begin
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Source));
+ pragma Assert (Present (Destination));
+
+ -- Nothing to do when the invocation graph encoding format of the source
+ -- vertex does not contain detailed information about invocation paths.
+
+ if Invocation_Graph_Encoding (Lib_Graph, Source) /=
+ Full_Path_Encoding
+ then
+ return;
+ end if;
+
+ Path := IGE_Lists.Create;
+ Path_Id := 1;
+ Visited := IGV_Sets.Create (Number_Of_Vertices (Inv_Graph));
+
+ -- Start a DFS traversal over the invocation graph, in an attempt to
+ -- reach Destination from Source. The actual start of the path is the
+ -- elaboration root invocation vertex that corresponds to the Source.
+ -- Each unique path is emitted as part of the current cycle diagnostic.
+
+ Visit_Vertex
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Invoker =>
+ Find_Elaboration_Root
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Vertex => Source),
+ Invoker_Vertex => Source,
+ Last_Vertex => Source,
+ Elaborated_Vertex => Source,
+ End_Vertex => Destination,
+ Visited_Invokers => Visited,
+ Path => Path,
+ Path_Id => Path_Id);
+
+ IGE_Lists.Destroy (Path);
+ IGV_Sets.Destroy (Visited);
+ end Find_And_Output_Invocation_Paths;
+
+ ---------------------------
+ -- Find_Elaboration_Root --
+ ---------------------------
+
+ function Find_Elaboration_Root
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Invocation_Graph_Vertex_Id
+ is
+ Current_Vertex : Invocation_Graph_Vertex_Id;
+ Iter : Elaboration_Root_Iterator;
+ Root_Vertex : Invocation_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Vertex));
+
+ -- Assume that the vertex does not have a corresponding elaboration root
+
+ Root_Vertex := No_Invocation_Graph_Vertex;
+
+ -- Inspect all elaboration roots trying to find the one that resides in
+ -- the input vertex.
+ --
+ -- IMPORTANT:
+ --
+ -- * The iterator must run to completion in order to unlock the
+ -- invocation graph.
+
+ Iter := Iterate_Elaboration_Roots (Inv_Graph);
+ while Has_Next (Iter) loop
+ Next (Iter, Current_Vertex);
+
+ if not Present (Root_Vertex)
+ and then Body_Vertex (Inv_Graph, Current_Vertex) = Vertex
+ then
+ Root_Vertex := Current_Vertex;
+ end if;
+ end loop;
+
+ return Root_Vertex;
+ end Find_Elaboration_Root;
+
+ -----------------------------------
+ -- Output_All_Cycles_Suggestions --
+ -----------------------------------
+
+ procedure Output_All_Cycles_Suggestions (G : Library_Graph) is
+ begin
+ pragma Assert (Present (G));
+
+ -- The library graph contains at least one cycle and only the highest
+ -- priority cycle was diagnosed. Diagnosing all cycles may yield extra
+ -- information for decision making.
+
+ if Number_Of_Cycles (G) > 1 and then not Debug_Flag_Underscore_CC then
+ Error_Msg_Info
+ (" diagnose all circularities (binder switch -d_C)");
+ end if;
+ end Output_All_Cycles_Suggestions;
+
+ --------------------------------------
+ -- Output_Elaborate_All_Suggestions --
+ --------------------------------------
+
+ procedure Output_Elaborate_All_Suggestions
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Pred));
+ pragma Assert (Present (Succ));
+
+ Error_Msg_Unit_1 := Name (G, Pred);
+ Error_Msg_Unit_2 := Name (G, Succ);
+ Error_Msg_Info
+ (" change pragma Elaborate_All for unit $ to Elaborate in unit $");
+ Error_Msg_Info
+ (" remove pragma Elaborate_All for unit $ in unit $");
+ end Output_Elaborate_All_Suggestions;
+
+ -------------------------------------
+ -- Output_Elaborate_All_Transition --
+ -------------------------------------
+
+ procedure Output_Elaborate_All_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Source));
+ pragma Assert (Present (Actual_Destination));
+ pragma Assert (Present (Expected_Destination));
+
+ -- The actual and expected destination vertices match, and denote the
+ -- initial declaration of a unit.
+ --
+ -- Elaborate_All Actual_Destination
+ -- Source ---------------> spec -->
+ -- Expected_Destination
+ --
+ -- Elaborate_All Actual_Destination
+ -- Source ---------------> stand-alone body -->
+ -- Expected_Destination
+
+ if Actual_Destination = Expected_Destination then
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause and pragma Elaborate_All for unit $");
+
+ -- Otherwise the actual destination vertex denotes the spec of a unit,
+ -- while the expected destination is the corresponding body.
+ --
+ -- Elaborate_All Actual_Destination
+ -- Source ---------------> spec
+ --
+ -- body -->
+ -- Expected_Destination
+
+ else
+ pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
+ pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
+ pragma Assert
+ (Proper_Body (G, Actual_Destination) = Expected_Destination);
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause and pragma Elaborate_All for unit $");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate_All");
+ end if;
+ end Output_Elaborate_All_Transition;
+
+ ---------------------------------------
+ -- Output_Elaborate_Body_Suggestions --
+ ---------------------------------------
+
+ procedure Output_Elaborate_Body_Suggestions
+ (G : Library_Graph;
+ Succ : Library_Graph_Vertex_Id)
+ is
+ Spec : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Succ));
+
+ -- Find the initial declaration of the unit because it is the one
+ -- subject to pragma Elaborate_Body.
+
+ if Is_Body_With_Spec (G, Succ) then
+ Spec := Proper_Spec (G, Succ);
+ else
+ Spec := Succ;
+ end if;
+
+ Error_Msg_Unit_1 := Name (G, Spec);
+ Error_Msg_Info
+ (" remove pragma Elaborate_Body in unit $");
+ end Output_Elaborate_Body_Suggestions;
+
+ --------------------------------------
+ -- Output_Elaborate_Body_Transition --
+ --------------------------------------
+
+ procedure Output_Elaborate_Body_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Source));
+ pragma Assert (Present (Actual_Destination));
+ pragma Assert (Present (Expected_Destination));
+
+ -- The actual and expected destination vertices match
+ --
+ -- Actual_Destination
+ -- Source --------> spec -->
+ -- Elaborate_Body Expected_Destination
+ --
+ -- spec
+ --
+ -- Actual_Destination
+ -- Source --------> body -->
+ -- Elaborate_Body Expected_Destination
+
+ if Actual_Destination = Expected_Destination then
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause for unit $");
+
+ -- The actual destination vertex denotes the spec of a unit while the
+ -- expected destination is the corresponding body, and the unit is in
+ -- the closure of an earlier Elaborate_All pragma.
+ --
+ -- Actual_Destination
+ -- Source --------> spec
+ -- Elaborate_Body
+ -- body -->
+ -- Expected_Destination
+
+ elsif Elaborate_All_Active then
+ pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
+ pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
+ pragma Assert
+ (Proper_Body (G, Actual_Destination) = Expected_Destination);
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause for unit $");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate_All");
+
+ -- Otherwise the actual destination vertex is the spec of a unit subject
+ -- to pragma Elaborate_Body and the expected destination vertex is the
+ -- completion body.
+ --
+ -- Actual_Destination
+ -- Source --------> spec Elaborate_Body
+ -- Elaborate_Body
+ -- body -->
+ -- Expected_Destination
+
+ else
+ pragma Assert
+ (Is_Elaborate_Body_Pair
+ (G => G,
+ Spec_Vertex => Actual_Destination,
+ Body_Vertex => Expected_Destination));
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause for unit $");
+
+ Error_Msg_Unit_1 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ is subject to pragma Elaborate_Body");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate_Body");
+ end if;
+ end Output_Elaborate_Body_Transition;
+
+ ----------------------------------
+ -- Output_Elaborate_Suggestions --
+ ----------------------------------
+
+ procedure Output_Elaborate_Suggestions
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Pred));
+ pragma Assert (Present (Succ));
+
+ Error_Msg_Unit_1 := Name (G, Pred);
+ Error_Msg_Unit_2 := Name (G, Succ);
+ Error_Msg_Info
+ (" remove pragma Elaborate for unit $ in unit $");
+ end Output_Elaborate_Suggestions;
+
+ ---------------------------------
+ -- Output_Elaborate_Transition --
+ ---------------------------------
+
+ procedure Output_Elaborate_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id)
+ is
+ Spec : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Source));
+ pragma Assert (Present (Actual_Destination));
+ pragma Assert (Present (Expected_Destination));
+
+ -- The actual and expected destination vertices match, and denote the
+ -- initial declaration of a unit.
+ --
+ -- Elaborate Actual_Destination
+ -- Source -----------> spec -->
+ -- Expected_Destination
+ --
+ -- Elaborate Actual_Destination
+ -- Source -----------> stand-alone body -->
+ -- Expected_Destination
+ --
+ -- The processing of pragma Elaborate body generates an edge between a
+ -- successor and predecessor body.
+ --
+ -- spec
+ --
+ -- Elaborate Actual_Destination
+ -- Source -----------> body -->
+ -- Expected_Destination
+
+ if Actual_Destination = Expected_Destination then
+
+ -- Find the initial declaration of the unit because it is the one
+ -- subject to pragma Elaborate.
+
+ if Is_Body_With_Spec (G, Actual_Destination) then
+ Spec := Proper_Spec (G, Actual_Destination);
+ else
+ Spec := Actual_Destination;
+ end if;
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Spec);
+ Error_Msg_Info
+ (" unit $ has with clause and pragma Elaborate for unit $");
+
+ if Actual_Destination /= Spec then
+ Error_Msg_Unit_1 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate");
+ end if;
+
+ -- Otherwise the actual destination vertex denotes the spec of a unit
+ -- while the expected destination vertex is the corresponding body.
+ --
+ -- Elaborate Actual_Destination
+ -- Source -----------> spec
+ --
+ -- body -->
+ -- Expected_Destination
+
+ else
+ pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
+ pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
+ pragma Assert
+ (Proper_Body (G, Actual_Destination) = Expected_Destination);
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause and pragma Elaborate for unit $");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate");
+ end if;
+ end Output_Elaborate_Transition;
+
+ -------------------------------
+ -- Output_Forced_Suggestions --
+ -------------------------------
+
+ procedure Output_Forced_Suggestions
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Pred));
+ pragma Assert (Present (Succ));
+
+ Error_Msg_Unit_1 := Name (G, Succ);
+ Error_Msg_Unit_2 := Name (G, Pred);
+ Error_Msg_Info
+ (" remove the dependency of unit $ on unit $ from the argument of "
+ & "switch -f");
+ Error_Msg_Info
+ (" remove switch -f");
+ end Output_Forced_Suggestions;
+
+ ------------------------------
+ -- Output_Forced_Transition --
+ ------------------------------
+
+ procedure Output_Forced_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Source));
+ pragma Assert (Present (Actual_Destination));
+ pragma Assert (Present (Expected_Destination));
+
+ -- The actual and expected destination vertices match
+ --
+ -- Forced Actual_Destination
+ -- Source --------> spec -->
+ -- Expected_Destination
+ --
+ -- Forced Actual_Destination
+ -- Source --------> body -->
+ -- Expected_Destination
+
+ if Actual_Destination = Expected_Destination then
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has a dependency on unit $ forced by -f switch");
+
+ -- The actual destination vertex denotes the spec of a unit while the
+ -- expected destination is the corresponding body, and the unit is in
+ -- the closure of an earlier Elaborate_All pragma.
+ --
+ -- Forced Actual_Destination
+ -- Source --------> spec
+ --
+ -- body -->
+ -- Expected_Destination
+
+ elsif Elaborate_All_Active then
+ pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
+ pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
+ pragma Assert
+ (Proper_Body (G, Actual_Destination) = Expected_Destination);
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has a dependency on unit $ forced by -f switch");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate_All");
+
+ -- Otherwise the actual destination vertex denotes a spec subject to
+ -- pragma Elaborate_Body while the expected destination denotes the
+ -- corresponding body.
+ --
+ -- Forced Actual_Destination
+ -- Source --------> spec Elaborate_Body
+ --
+ -- body -->
+ -- Expected_Destination
+
+ else
+ pragma Assert
+ (Is_Elaborate_Body_Pair
+ (G => G,
+ Spec_Vertex => Actual_Destination,
+ Body_Vertex => Expected_Destination));
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has a dependency on unit $ forced by -f switch");
+
+ Error_Msg_Unit_1 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ is subject to pragma Elaborate_Body");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate_Body");
+ end if;
+ end Output_Forced_Transition;
+
+ --------------------------------------
+ -- Output_Full_Encoding_Suggestions --
+ --------------------------------------
+
+ procedure Output_Full_Encoding_Suggestions
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ First_Edge : Library_Graph_Edge_Id)
+ is
+ Succ : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+ pragma Assert (Present (First_Edge));
+
+ if Is_Invocation_Edge (G, First_Edge) then
+ Succ := Successor (G, First_Edge);
+
+ if Invocation_Graph_Encoding (G, Succ) /= Full_Path_Encoding then
+ Error_Msg_Info
+ (" use detailed invocation information (compiler switch "
+ & "-gnatd_F)");
+ end if;
+ end if;
+ end Output_Full_Encoding_Suggestions;
+
+ ----------------------------
+ -- Output_Invocation_Path --
+ -----------------------------
+
+ procedure Output_Invocation_Path
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Elaborated_Vertex : Library_Graph_Vertex_Id;
+ Path : IGE_Lists.Doubly_Linked_List;
+ Path_Id : in out Nat)
+ is
+ Edge : Invocation_Graph_Edge_Id;
+ Iter : IGE_Lists.Iterator;
+
+ begin
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Elaborated_Vertex));
+ pragma Assert (IGE_Lists.Present (Path));
+
+ Error_Msg_Nat_1 := Path_Id;
+ Error_Msg_Info (" path #:");
+
+ Error_Msg_Unit_1 := Name (Lib_Graph, Elaborated_Vertex);
+ Error_Msg_Info (" elaboration of unit $");
+
+ Iter := IGE_Lists.Iterate (Path);
+ while IGE_Lists.Has_Next (Iter) loop
+ IGE_Lists.Next (Iter, Edge);
+
+ Output_Invocation_Path_Transition
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Edge => Edge);
+ end loop;
+
+ Path_Id := Path_Id + 1;
+ end Output_Invocation_Path;
+
+ ---------------------------------------
+ -- Output_Invocation_Path_Transition --
+ ---------------------------------------
+
+ procedure Output_Invocation_Path_Transition
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Edge : Invocation_Graph_Edge_Id)
+ is
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Edge));
+
+ Declared : constant String := "declared at {:#:#";
+
+ Targ : constant Invocation_Graph_Vertex_Id :=
+ Target (Inv_Graph, Edge);
+ Targ_Extra : constant Name_Id :=
+ Extra (Inv_Graph, Edge);
+ Targ_Vertex : constant Library_Graph_Vertex_Id :=
+ Spec_Vertex (Inv_Graph, Targ);
+
+ begin
+ Error_Msg_Name_1 := Name (Inv_Graph, Targ);
+ Error_Msg_Nat_1 := Line (Inv_Graph, Targ);
+ Error_Msg_Nat_2 := Column (Inv_Graph, Targ);
+ Error_Msg_File_1 := File_Name (Lib_Graph, Targ_Vertex);
+
+ case Kind (Inv_Graph, Edge) is
+ when Accept_Alternative =>
+ Error_Msg_Info
+ (" selection of entry % "
+ & Declared);
+
+ when Access_Taken =>
+ Error_Msg_Info
+ (" aliasing of subprogram % "
+ & Declared);
+
+ when Call =>
+ Error_Msg_Info
+ (" call to subprogram % "
+ & Declared);
+
+ when Controlled_Adjustment
+ | Internal_Controlled_Adjustment
+ =>
+ Error_Msg_Name_1 := Targ_Extra;
+ Error_Msg_Info
+ (" adjustment actions for type % "
+ & Declared);
+
+ when Controlled_Finalization
+ | Internal_Controlled_Finalization
+ =>
+ Error_Msg_Name_1 := Targ_Extra;
+ Error_Msg_Info
+ (" finalization actions for type % "
+ & Declared);
+
+ when Controlled_Initialization
+ | Internal_Controlled_Initialization
+ | Type_Initialization
+ =>
+ Error_Msg_Name_1 := Targ_Extra;
+ Error_Msg_Info
+ (" initialization actions for type % "
+ & Declared);
+
+ when Default_Initial_Condition_Verification =>
+ Error_Msg_Name_1 := Targ_Extra;
+ Error_Msg_Info
+ (" verification of Default_Initial_Condition for type % "
+ & Declared);
+
+ when Initial_Condition_Verification =>
+ Error_Msg_Info
+ (" verification of Initial_Condition "
+ & Declared);
+
+ when Instantiation =>
+ Error_Msg_Info
+ (" instantiation % "
+ & Declared);
+
+ when Invariant_Verification =>
+ Error_Msg_Name_1 := Targ_Extra;
+ Error_Msg_Info
+ (" verification of invariant for type % "
+ & Declared);
+
+ when Postcondition_Verification =>
+ Error_Msg_Name_1 := Targ_Extra;
+ Error_Msg_Info
+ (" verification of postcondition for subprogram % "
+ & Declared);
+
+ when Protected_Entry_Call =>
+ Error_Msg_Info
+ (" call to protected entry % "
+ & Declared);
+
+ when Protected_Subprogram_Call =>
+ Error_Msg_Info
+ (" call to protected subprogram % "
+ & Declared);
+
+ when Task_Activation =>
+ Error_Msg_Info
+ (" activation of local task "
+ & Declared);
+
+ when Task_Entry_Call =>
+ Error_Msg_Info
+ (" call to task entry % "
+ & Declared);
+
+ when others =>
+ pragma Assert (False);
+ null;
+ end case;
+ end Output_Invocation_Path_Transition;
+
+ -------------------------------------------
+ -- Output_Invocation_Related_Suggestions --
+ -------------------------------------------
+
+ procedure Output_Invocation_Related_Suggestions
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ -- Nothing to do when the cycle does not contain an invocation edge
+
+ if Invocation_Edge_Count (G, Cycle) = 0 then
+ return;
+ end if;
+
+ -- The cycle contains at least one invocation edge, where at least
+ -- one of the paths the edge represents activates a task. The use of
+ -- restriction No_Entry_Calls_In_Elaboration_Code may halt the flow
+ -- within the task body on a select or accept statement, eliminating
+ -- subsequent invocation edges, thus breaking the cycle.
+
+ if not Restriction_Active (No_Entry_Calls_In_Elaboration_Code)
+ and then Contains_Task_Activation (G, Cycle)
+ then
+ Error_Msg_Info
+ (" use pragma Restrictions "
+ & "(No_Entry_Calls_In_Elaboration_Code)");
+ end if;
+
+ -- The cycle contains at least one invocation edge where the successor
+ -- was statically elaborated. The use of the dynamic model may remove
+ -- one of the invocation edges in the cycle, thus breaking the cycle.
+
+ if Contains_Static_Successor_Edge (G, Cycle) then
+ Error_Msg_Info
+ (" use the dynamic elaboration model (compiler switch -gnatE)");
+ end if;
+ end Output_Invocation_Related_Suggestions;
+
+ ----------------------------------
+ -- Output_Invocation_Transition --
+ ----------------------------------
+
+ procedure Output_Invocation_Transition
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Destination : Library_Graph_Vertex_Id)
+ is
+ begin
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Source));
+ pragma Assert (Present (Destination));
+
+ Error_Msg_Unit_1 := Name (Lib_Graph, Source);
+ Error_Msg_Unit_2 := Name (Lib_Graph, Destination);
+ Error_Msg_Info
+ (" unit $ invokes a construct of unit $ at elaboration time");
+
+ Find_And_Output_Invocation_Paths
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Source => Source,
+ Destination => Destination);
+ end Output_Invocation_Transition;
+
+ ------------------------------------------
+ -- Output_Reason_And_Circularity_Header --
+ ------------------------------------------
+
+ procedure Output_Reason_And_Circularity_Header
+ (G : Library_Graph;
+ First_Edge : Library_Graph_Edge_Id)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (First_Edge));
+
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, First_Edge);
+
+ begin
+ Error_Msg_Unit_1 := Name (G, Succ);
+ Error_Msg ("Elaboration circularity detected");
+ Error_Msg_Info ("");
+ Error_Msg_Info (" Reason:");
+ Error_Msg_Info ("");
+ Error_Msg_Info (" unit $ depends on its own elaboration");
+ Error_Msg_Info ("");
+ Error_Msg_Info (" Circularity:");
+ Error_Msg_Info ("");
+ end Output_Reason_And_Circularity_Header;
+
+ ------------------------
+ -- Output_Suggestions --
+ ------------------------
+
+ procedure Output_Suggestions
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ First_Edge : Library_Graph_Edge_Id)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+ pragma Assert (Present (First_Edge));
+
+ Pred : constant Library_Graph_Vertex_Id := Predecessor (G, First_Edge);
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, First_Edge);
+
+ begin
+ Error_Msg_Info ("");
+ Error_Msg_Info (" Suggestions:");
+ Error_Msg_Info ("");
+
+ -- Output edge-specific suggestions
+
+ if Is_Elaborate_All_Edge (G, First_Edge) then
+ Output_Elaborate_All_Suggestions
+ (G => G,
+ Pred => Pred,
+ Succ => Succ);
+
+ elsif Is_Elaborate_Body_Edge (G, First_Edge) then
+ Output_Elaborate_Body_Suggestions
+ (G => G,
+ Succ => Succ);
+
+ elsif Is_Elaborate_Edge (G, First_Edge) then
+ Output_Elaborate_Suggestions
+ (G => G,
+ Pred => Pred,
+ Succ => Succ);
+
+ elsif Is_Forced_Edge (G, First_Edge) then
+ Output_Forced_Suggestions
+ (G => G,
+ Pred => Pred,
+ Succ => Succ);
+ end if;
+
+ -- Output general purpose suggestions
+
+ Output_Invocation_Related_Suggestions
+ (G => G,
+ Cycle => Cycle);
+
+ Output_Full_Encoding_Suggestions
+ (G => G,
+ Cycle => Cycle,
+ First_Edge => First_Edge);
+
+ Output_All_Cycles_Suggestions (G);
+
+ Error_Msg_Info ("");
+ end Output_Suggestions;
+
+ -----------------------
+ -- Output_Transition --
-----------------------
- package body Cycle_Diagnostics is
+ procedure Output_Transition
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Current_Edge : Library_Graph_Edge_Id;
+ Next_Edge : Library_Graph_Edge_Id;
+ Elaborate_All_Active : Boolean)
+ is
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Current_Edge));
+ pragma Assert (Present (Next_Edge));
+
+ Actual_Destination : constant Library_Graph_Vertex_Id :=
+ Predecessor (Lib_Graph, Current_Edge);
+ Expected_Destination : constant Library_Graph_Vertex_Id :=
+ Successor (Lib_Graph, Next_Edge);
+ Source : constant Library_Graph_Vertex_Id :=
+ Successor (Lib_Graph, Current_Edge);
+
+ begin
+ if Is_Elaborate_All_Edge (Lib_Graph, Current_Edge) then
+ Output_Elaborate_All_Transition
+ (G => Lib_Graph,
+ Source => Source,
+ Actual_Destination => Actual_Destination,
+ Expected_Destination => Expected_Destination);
+
+ elsif Is_Elaborate_Body_Edge (Lib_Graph, Current_Edge) then
+ Output_Elaborate_Body_Transition
+ (G => Lib_Graph,
+ Source => Source,
+ Actual_Destination => Actual_Destination,
+ Expected_Destination => Expected_Destination,
+ Elaborate_All_Active => Elaborate_All_Active);
- -----------------------------
- -- Has_Elaborate_All_Cycle --
- -----------------------------
+ elsif Is_Elaborate_Edge (Lib_Graph, Current_Edge) then
+ Output_Elaborate_Transition
+ (G => Lib_Graph,
+ Source => Source,
+ Actual_Destination => Actual_Destination,
+ Expected_Destination => Expected_Destination);
- function Has_Elaborate_All_Cycle (G : Library_Graph) return Boolean is
- Has_Cycle : Boolean;
- Iter : All_Edge_Iterator;
- LGE_Id : Library_Graph_Edge_Id;
+ elsif Is_Forced_Edge (Lib_Graph, Current_Edge) then
+ Output_Forced_Transition
+ (G => Lib_Graph,
+ Source => Source,
+ Actual_Destination => Actual_Destination,
+ Expected_Destination => Expected_Destination,
+ Elaborate_All_Active => Elaborate_All_Active);
- begin
- pragma Assert (Present (G));
+ elsif Is_Invocation_Edge (Lib_Graph, Current_Edge) then
+ Output_Invocation_Transition
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Source => Source,
+ Destination => Expected_Destination);
- -- Assume that the graph lacks a cycle
+ else
+ pragma Assert (Is_With_Edge (Lib_Graph, Current_Edge));
- Has_Cycle := False;
+ Output_With_Transition
+ (G => Lib_Graph,
+ Source => Source,
+ Actual_Destination => Actual_Destination,
+ Expected_Destination => Expected_Destination,
+ Elaborate_All_Active => Elaborate_All_Active);
+ end if;
+ end Output_Transition;
- -- The library graph has an Elaborate_All cycle when one of its edges
- -- represents a with clause for a unit with pragma Elaborate_All, and
- -- both the predecessor and successor reside in the same component.
- -- Note that the iteration must run to completion in order to unlock
- -- the graph.
+ ----------------------------
+ -- Output_With_Transition --
+ ----------------------------
- Iter := Iterate_All_Edges (G);
+ procedure Output_With_Transition
+ (G : Library_Graph;
+ Source : Library_Graph_Vertex_Id;
+ Actual_Destination : Library_Graph_Vertex_Id;
+ Expected_Destination : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Source));
+ pragma Assert (Present (Actual_Destination));
+ pragma Assert (Present (Expected_Destination));
+
+ -- The actual and expected destination vertices match, and denote the
+ -- initial declaration of a unit.
+ --
+ -- with Actual_Destination
+ -- Source ------> spec -->
+ -- Expected_Destination
+ --
+ -- with Actual_Destination
+ -- Source ------> stand-alone body -->
+ -- Expected_Destination
+
+ if Actual_Destination = Expected_Destination then
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause for unit $");
+
+ -- The actual destination vertex denotes the spec of a unit while the
+ -- expected destination is the corresponding body, and the unit is in
+ -- the closure of an earlier Elaborate_All pragma.
+ --
+ -- with Actual_Destination
+ -- Source ------> spec
+ --
+ -- body -->
+ -- Expected_Destination
+
+ elsif Elaborate_All_Active then
+ pragma Assert (Is_Spec_With_Body (G, Actual_Destination));
+ pragma Assert (Is_Body_With_Spec (G, Expected_Destination));
+ pragma Assert
+ (Proper_Body (G, Actual_Destination) = Expected_Destination);
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause for unit $");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate_All");
+
+ -- Otherwise the actual destination vertex denotes a spec subject to
+ -- pragma Elaborate_Body while the expected destination denotes the
+ -- corresponding body.
+ --
+ -- with Actual_Destination
+ -- Source ------> spec Elaborate_Body
+ --
+ -- body -->
+ -- Expected_Destination
+
+ else
+ pragma Assert
+ (Is_Elaborate_Body_Pair
+ (G => G,
+ Spec_Vertex => Actual_Destination,
+ Body_Vertex => Expected_Destination));
+
+ Error_Msg_Unit_1 := Name (G, Source);
+ Error_Msg_Unit_2 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ has with clause for unit $");
+
+ Error_Msg_Unit_1 := Name (G, Actual_Destination);
+ Error_Msg_Info
+ (" unit $ is subject to pragma Elaborate_Body");
+
+ Error_Msg_Unit_1 := Name (G, Expected_Destination);
+ Error_Msg_Info
+ (" unit $ is in the closure of pragma Elaborate_Body");
+ end if;
+ end Output_With_Transition;
+
+ ------------------
+ -- Visit_Vertex --
+ ------------------
+
+ procedure Visit_Vertex
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Invoker : Invocation_Graph_Vertex_Id;
+ Invoker_Vertex : Library_Graph_Vertex_Id;
+ Last_Vertex : Library_Graph_Vertex_Id;
+ Elaborated_Vertex : Library_Graph_Vertex_Id;
+ End_Vertex : Library_Graph_Vertex_Id;
+ Visited_Invokers : IGV_Sets.Membership_Set;
+ Path : IGE_Lists.Doubly_Linked_List;
+ Path_Id : in out Nat)
+ is
+ Edge : Invocation_Graph_Edge_Id;
+ Iter : Edges_To_Targets_Iterator;
+ Targ : Invocation_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (Inv_Graph));
+ pragma Assert (Present (Lib_Graph));
+ pragma Assert (Present (Invoker));
+ pragma Assert (Present (Invoker_Vertex));
+ pragma Assert (Present (Last_Vertex));
+ pragma Assert (Present (Elaborated_Vertex));
+ pragma Assert (Present (End_Vertex));
+ pragma Assert (IGV_Sets.Present (Visited_Invokers));
+ pragma Assert (IGE_Lists.Present (Path));
+
+ -- The current invocation vertex resides within the end library vertex.
+ -- Emit the path that started from some elaboration root and ultimately
+ -- reached the desired library vertex.
+
+ if Body_Vertex (Inv_Graph, Invoker) = End_Vertex
+ and then Invoker_Vertex /= Last_Vertex
+ then
+ Output_Invocation_Path
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Elaborated_Vertex => Elaborated_Vertex,
+ Path => Path,
+ Path_Id => Path_Id);
+
+ -- Otherwise extend the search for the end library vertex via all edges
+ -- to targets.
+
+ elsif not IGV_Sets.Contains (Visited_Invokers, Invoker) then
+
+ -- Prepare for invoker backtracking
+
+ IGV_Sets.Insert (Visited_Invokers, Invoker);
+
+ -- Extend the search via all edges to targets
+
+ Iter := Iterate_Edges_To_Targets (Inv_Graph, Invoker);
while Has_Next (Iter) loop
- Next (Iter, LGE_Id);
- pragma Assert (Present (LGE_Id));
-
- if Kind (G, LGE_Id) = Elaborate_All_Edge
- and then Links_Vertices_In_Same_Component (G, LGE_Id)
- then
- Has_Cycle := True;
- end if;
+ Next (Iter, Edge);
+
+ -- Prepare for edge backtracking
+
+ IGE_Lists.Append (Path, Edge);
+
+ -- The traversal proceeds through the library vertex that houses
+ -- the body of the target.
+
+ Targ := Target (Inv_Graph, Edge);
+
+ Visit_Vertex
+ (Inv_Graph => Inv_Graph,
+ Lib_Graph => Lib_Graph,
+ Invoker => Targ,
+ Invoker_Vertex => Body_Vertex (Inv_Graph, Targ),
+ Last_Vertex => Invoker_Vertex,
+ Elaborated_Vertex => Elaborated_Vertex,
+ End_Vertex => End_Vertex,
+ Visited_Invokers => Visited_Invokers,
+ Path => Path,
+ Path_Id => Path_Id);
+
+ -- Backtrack the edge
+
+ IGE_Lists.Delete_Last (Path);
end loop;
- return Has_Cycle;
- end Has_Elaborate_All_Cycle;
- end Cycle_Diagnostics;
+ -- Backtrack the invoker
+
+ IGV_Sets.Delete (Visited_Invokers, Invoker);
+ end if;
+ end Visit_Vertex;
end Bindo.Diagnostics;
diff --git a/gcc/ada/bindo-diagnostics.ads b/gcc/ada/bindo-diagnostics.ads
index 3b1d01c..3835a68 100644
--- a/gcc/ada/bindo-diagnostics.ads
+++ b/gcc/ada/bindo-diagnostics.ads
@@ -30,6 +30,7 @@
with Bindo.Graphs;
use Bindo.Graphs;
+use Bindo.Graphs.Invocation_Graphs;
use Bindo.Graphs.Library_Graphs;
package Bindo.Diagnostics is
@@ -46,16 +47,15 @@ package Bindo.Diagnostics is
Order_Has_Elaborate_All_Circularity,
Order_OK);
- -----------------------
- -- Cycle_Diagnostics --
- -----------------------
+ ---------
+ -- API --
+ ---------
- package Cycle_Diagnostics is
- function Has_Elaborate_All_Cycle (G : Library_Graph) return Boolean;
- pragma Inline (Has_Elaborate_All_Cycle);
- -- Determine whether library graph G contains a cycle where pragma
- -- Elaborate_All appears within a component.
-
- end Cycle_Diagnostics;
+ procedure Diagnose_Circularities
+ (Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph);
+ pragma Inline (Diagnose_Circularities);
+ -- Diagnose all cycles of library graph Lib_Graph with matching invocation
+ -- graph Inv_Graph.
end Bindo.Diagnostics;
diff --git a/gcc/ada/bindo-elaborators.adb b/gcc/ada/bindo-elaborators.adb
index b11598c..9e207e1 100644
--- a/gcc/ada/bindo-elaborators.adb
+++ b/gcc/ada/bindo-elaborators.adb
@@ -23,11 +23,10 @@
-- --
------------------------------------------------------------------------------
-with Binderr; use Binderr;
-with Butil; use Butil;
-with Debug; use Debug;
-with Output; use Output;
-with Types; use Types;
+with Butil; use Butil;
+with Debug; use Debug;
+with Output; use Output;
+with Types; use Types;
with Bindo.Augmentors;
use Bindo.Augmentors;
@@ -40,7 +39,6 @@ use Bindo.Builders.Library_Graph_Builders;
with Bindo.Diagnostics;
use Bindo.Diagnostics;
-use Bindo.Diagnostics.Cycle_Diagnostics;
with Bindo.Units;
use Bindo.Units;
@@ -48,20 +46,19 @@ use Bindo.Units;
with Bindo.Validators;
use Bindo.Validators;
use Bindo.Validators.Elaboration_Order_Validators;
-use Bindo.Validators.Invocation_Graph_Validators;
-use Bindo.Validators.Library_Graph_Validators;
with Bindo.Writers;
use Bindo.Writers;
use Bindo.Writers.ALI_Writers;
+use Bindo.Writers.Dependency_Writers;
use Bindo.Writers.Elaboration_Order_Writers;
use Bindo.Writers.Invocation_Graph_Writers;
use Bindo.Writers.Library_Graph_Writers;
+use Bindo.Writers.Phase_Writers;
use Bindo.Writers.Unit_Closure_Writers;
with GNAT; use GNAT;
with GNAT.Graphs; use GNAT.Graphs;
-with GNAT.Sets; use GNAT.Sets;
package body Bindo.Elaborators is
@@ -78,86 +75,61 @@ package body Bindo.Elaborators is
----------------------------------------------
package body Invocation_And_Library_Graph_Elaborators is
- Add_To_All_Candidates_Msg : aliased String :=
- "add vertex to all candidates";
- Add_To_Comp_Candidates_Msg : aliased String :=
- "add vertex to component candidates";
-
- -----------
- -- Types --
- -----------
-
- type String_Ptr is access all String;
-
- -----------------
- -- Visited set --
- -----------------
-
- package VS is new Membership_Sets
- (Element_Type => Library_Graph_Vertex_Id,
- "=" => "=",
- Hash => Hash_Library_Graph_Vertex);
- use VS;
-----------------------
-- Local subprograms --
-----------------------
- procedure Add_Vertex
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Set : Membership_Set;
- Msg : String;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level);
- pragma Inline (Add_Vertex);
- -- Add vertex LGV_Id of library graph G to membership set Set. Msg is
- -- a message emitted for tracing purposes. Step is the current step in
- -- the elaboration order. Indent is the desired indentation level for
- -- tracing.
-
- procedure Add_Vertex_If_Elaborable
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Set : Membership_Set;
- Msg : String;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level);
- pragma Inline (Add_Vertex_If_Elaborable);
- -- Add vertex LGV_Id of library graph G to membership set Set if it can
- -- be elaborated. Msg is a message emitted for tracing purposes. Step is
- -- the current step in the elaboration order. Indent is the desired
- -- indentation level for tracing.
-
- function Create_All_Candidates_Set
- (G : Library_Graph;
- Step : Elaboration_Order_Step) return Membership_Set;
- pragma Inline (Create_All_Candidates_Set);
- -- Collect all elaborable candidate vertices of library graph G in a
- -- set. Step is the current step in the elaboration order.
-
- function Create_Component_Candidates_Set
- (G : Library_Graph;
- Comp : Component_Id;
- Step : Elaboration_Order_Step) return Membership_Set;
- pragma Inline (Create_Component_Candidates_Set);
- -- Collect all elaborable candidate vertices that appear in component
- -- Comp of library graph G in a set. Step is the current step in the
- -- elaboration order.
+ procedure Create_Component_Vertex_Sets
+ (G : Library_Graph;
+ Comp : Component_Id;
+ Elaborable_Vertices : out LGV_Sets.Membership_Set;
+ Waiting_Vertices : out LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step);
+ pragma Inline (Create_Component_Vertex_Sets);
+ -- Split all vertices of component Comp of library graph G as follows:
+ --
+ -- * Elaborable vertices are added to set Elaborable_Vertices.
+ --
+ -- * Vertices that are still waiting on their predecessors to be
+ -- elaborated are added to set Waiting_Vertices.
+ --
+ -- Step is the current step in the elaboration order.
+
+ procedure Create_Vertex_Sets
+ (G : Library_Graph;
+ Elaborable_Vertices : out LGV_Sets.Membership_Set;
+ Waiting_Vertices : out LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step);
+ pragma Inline (Create_Vertex_Sets);
+ -- Split all vertices of library graph G as follows:
+ --
+ -- * Elaborable vertices are added to set Elaborable_Vertices.
+ --
+ -- * Vertices that are still waiting on their predecessors to be
+ -- elaborated are added to set Waiting_Vertices.
+ --
+ -- Step is the current step in the elaboration order.
procedure Elaborate_Component
- (G : Library_Graph;
- Comp : Component_Id;
- All_Candidates : Membership_Set;
- Remaining_Vertices : in out Natural;
- Order : in out Unit_Id_Table;
- Step : Elaboration_Order_Step);
+ (G : Library_Graph;
+ Comp : Component_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Order : in out Unit_Id_Table;
+ Step : Elaboration_Order_Step);
pragma Inline (Elaborate_Component);
- -- Elaborate as many vertices as possible that appear in component
- -- Comp of library graph G. All_Candidates is the set of all elaborable
- -- vertices across the whole library graph. Remaining_Vertices is the
- -- number of vertices that remain to be elaborated. Order denotes the
- -- elaboration order. Step is the current step in the elaboration order.
+ -- Elaborate as many vertices as possible that appear in component Comp
+ -- of library graph G. The sets contain vertices arranged as follows:
+ --
+ -- * All_Elaborable_Vertices - all elaborable vertices in the library
+ -- graph.
+ --
+ -- * All_Waiting_Vertices - all vertices in the library graph that are
+ -- waiting on predecessors to be elaborated.
+ --
+ -- Order is the elaboration order. Step denotes the current step in the
+ -- elaboration order.
procedure Elaborate_Library_Graph
(G : Library_Graph;
@@ -168,78 +140,144 @@ package body Bindo.Elaborators is
-- the elaboration order. Status is the condition of the elaboration
-- order.
- procedure Elaborate_Units_Common
- (Use_Inv_Graph : Boolean;
- Inv_Graph : out Invocation_Graph;
- Lib_Graph : out Library_Graph;
- Order : out Unit_Id_Table;
- Status : out Elaboration_Order_Status);
- pragma Inline (Elaborate_Units_Common);
- -- Find the elaboration order of all units in the bind. Use_Inv_Graph
- -- should be set when library graph Lib_Graph is to be augmented with
- -- information from invocation graph Inv_Graph. Order is the elaboration
- -- order. Status is the condition of the elaboration order.
-
- procedure Elaborate_Units_Dynamic (Order : out Unit_Id_Table);
- pragma Inline (Elaborate_Units_Dynamic);
- -- Find the elaboration order of all units in the bind using the dynamic
- -- model. Order is the elaboration order. In the event where no ordering
- -- is possible, this routine diagnoses the issue(s) and raises exception
- -- Unrecoverable_Error.
-
- procedure Elaborate_Units_Static (Order : out Unit_Id_Table);
- pragma Inline (Elaborate_Units_Static);
- -- Find the elaboration order of all units in the bind using the static
- -- model. Order is the elaboration order. In the event where no ordering
- -- is possible, this routine diagnoses the issue(s) and raises exception
- -- Unrecoverable_Error.
-
procedure Elaborate_Vertex
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- All_Candidates : Membership_Set;
- Comp_Candidates : Membership_Set;
- Remaining_Vertices : in out Natural;
- Order : in out Unit_Id_Table;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level);
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Order : in out Unit_Id_Table;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level);
pragma Inline (Elaborate_Vertex);
- -- Elaborate vertex LGV_Id of library graph G by adding its unit to
+ -- Elaborate vertex Vertex of library graph G by adding its unit to
-- elaboration order Order. The routine updates awaiting successors
- -- where applicable. All_Candidates denotes the set of all elaborable
- -- vertices across the whole library graph. Comp_Candidates is the set
- -- of all elaborable vertices in the component of LGV_Id. Parameter
- -- Remaining_Vertices denotes the number of vertices that remain to
- -- be elaborated. Step is the current step in the elaboration order.
+ -- where applicable. The sets contain vertices arranged as follows:
+ --
+ -- * All_Elaborable_Vertices - all elaborable vertices in the library
+ -- graph.
+ --
+ -- * All_Waiting_Vertices - all vertices in the library graph that are
+ -- waiting on predecessors to be elaborated.
+ --
+ -- * Comp_Elaborable_Vertices - all elaborable vertices found in the
+ -- component of Vertex.
+ --
+ -- * Comp_Waiting_Vertices - all vertices found in the component of
+ -- Vertex that are still waiting on predecessors to be elaborated.
+ --
+ -- Order denotes the elaboration order. Step is the current step in the
+ -- elaboration order. Indent denotes the desired indentation level for
+ -- tracing.
+
+ function Find_Best_Elaborable_Vertex
+ (G : Library_Graph;
+ Set : LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level) return Library_Graph_Vertex_Id;
+ pragma Inline (Find_Best_Elaborable_Vertex);
+ -- Find the best vertex of library graph G from membership set S that
+ -- can be elaborated. Step is the current step in the elaboration order.
-- Indent is the desired indentation level for tracing.
- function Find_Best_Candidate
+ function Find_Best_Vertex
+ (G : Library_Graph;
+ Set : LGV_Sets.Membership_Set;
+ Is_Suitable_Vertex : LGV_Predicate_Ptr;
+ Compare_Vertices : LGV_Comparator_Ptr;
+ Initial_Best_Msg : String;
+ Subsequent_Best_Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
+ return Library_Graph_Vertex_Id;
+ pragma Inline (Find_Best_Vertex);
+ -- Find the best vertex of library graph G from membership set S which
+ -- satisfies predicate Is_Suitable_Vertex and is preferred by comparator
+ -- Compare_Vertices. Initial_Best_Msg is emitted on the first candidate
+ -- vertex. Subsequent_Best_Msg is emitted whenever a better vertex is
+ -- discovered. Step is the current step in the elaboration order. Indent
+ -- is the desired indentation level for tracing.
+
+ function Find_Best_Weakly_Elaborable_Vertex
(G : Library_Graph;
- Set : Membership_Set;
+ Set : LGV_Sets.Membership_Set;
Step : Elaboration_Order_Step;
Indent : Indentation_Level) return Library_Graph_Vertex_Id;
- pragma Inline (Find_Best_Candidate);
- -- Find the most suitable vertex of library graph G for elaboration from
- -- membership set Set. Step denotes the current step in the elaboration
+ pragma Inline (Find_Best_Weakly_Elaborable_Vertex);
+ -- Find the best vertex of library graph G from membership set S that
+ -- can be weakly elaborated. Step is the current step in the elaboration
-- order. Indent is the desired indentation level for tracing.
- function Is_Better_Candidate
+ function Has_Elaborable_Body
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Has_Elaborable_Body);
+ -- Determine whether vertex Vertex of library graph G has a body that is
+ -- elaborable. It is assumed that the vertex has been elaborated.
+
+ procedure Insert_Elaborable_Successor
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level);
+ pragma Inline (Insert_Elaborable_Successor);
+ -- Add elaborable successor Vertex of library graph G to membership set
+ -- Elaborable_Vertices and remove it from both All_Waiting_Vertices and
+ -- Comp_Waiting_Vertices. Msg is a message emitted for tracing purposes.
+ -- Step is the current step in the elaboration order. Indent denotes the
+ -- desired indentation level for tracing.
+
+ procedure Insert_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Set : LGV_Sets.Membership_Set;
+ Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level);
+ pragma Inline (Insert_Vertex);
+ -- Add vertex Vertex of library graph G to membership set Set. Msg is
+ -- a message emitted for tracing purposes. Step is the current step in
+ -- the elaboration order. Indent is the desired indentation level for
+ -- tracing.
+
+ function Is_Better_Elaborable_Vertex
(G : Library_Graph;
- Best_Candid : Library_Graph_Vertex_Id;
- New_Candid : Library_Graph_Vertex_Id) return Boolean;
- pragma Inline (Is_Better_Candidate);
- -- Determine whether new candidate vertex New_Candid of library graph
- -- G is a more suitable choice for elaboration compared to the current
- -- best candidate Best_Candid.
-
- procedure Trace_Candidate_Vertices
- (G : Library_Graph;
- Set : Membership_Set;
- Step : Elaboration_Order_Step);
- pragma Inline (Trace_Candidate_Vertices);
- -- Write the candidate vertices of library graph G present in membership
- -- set Set to standard output. Formal Step denotes the current step in
- -- the elaboration order.
+ Vertex : Library_Graph_Vertex_Id;
+ Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind;
+ pragma Inline (Is_Better_Elaborable_Vertex);
+ -- Determine whether vertex Vertex of library graph G is a better choice
+ -- for elaboration compared to vertex Compared_To.
+
+ function Is_Better_Weakly_Elaborable_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind;
+ pragma Inline (Is_Better_Weakly_Elaborable_Vertex);
+ -- Determine whether vertex Vertex of library graph G is a better choice
+ -- for weak elaboration compared to vertex Compared_To.
+
+ function Is_Suitable_Elaborable_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Is_Suitable_Elaborable_Vertex);
+ -- Determine whether vertex Vertex of library graph G is suitable for
+ -- elaboration.
+
+ function Is_Suitable_Weakly_Elaborable_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Is_Suitable_Weakly_Elaborable_Vertex);
+ -- Determine whether vertex Vertex of library graph G is suitable for
+ -- weak elaboration.
+
+ procedure Set_Unit_Elaboration_Positions (Order : Unit_Id_Table);
+ pragma Inline (Set_Unit_Elaboration_Positions);
+ -- Set the ALI.Units positions of all elaboration units in order Order
procedure Trace_Component
(G : Library_Graph;
@@ -255,243 +293,214 @@ package body Bindo.Elaborators is
pragma Inline (Trace_Step);
-- Write current step Step of the elaboration order to standard output
- procedure Trace_Unelaborated_Vertices
- (G : Library_Graph;
- Count : Natural;
- Step : Elaboration_Order_Step);
- pragma Inline (Trace_Unelaborated_Vertices);
- -- Write the remaining unelaborated vertices of library graph G to
- -- standard output. Count is the number of vertices that remain to
- -- be elaborated. Step is the current step in the elaboration order.
-
procedure Trace_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Msg : String;
Step : Elaboration_Order_Step;
Indent : Indentation_Level);
pragma Inline (Trace_Vertex);
- -- Write elaboration-related information for vertex LGV_Id of library
+ -- Write elaboration-related information for vertex Vertex of library
-- graph G to standard output, starting with message Msg. Step is the
-- current step in the elaboration order. Indent denotes the desired
-- indentation level for tracing.
+ procedure Trace_Vertices
+ (G : Library_Graph;
+ Set : LGV_Sets.Membership_Set;
+ Set_Msg : String;
+ Vertex_Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level);
+ pragma Inline (Trace_Vertices);
+ -- Write the candidate vertices of library graph G present in membership
+ -- set Set to standard output, starting with message Set_Msg. Vertex_Msg
+ -- is the message emitted prior to each vertex. Step denotes the current
+ -- step in the elaboration order. Indent denotes the desired indentation
+ -- level for tracing.
+
procedure Update_Successor
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- Succ : Library_Graph_Vertex_Id;
- All_Candidates : Membership_Set;
- Comp_Candidates : Membership_Set;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level);
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level);
pragma Inline (Update_Successor);
- -- Notify successor vertex Succ of library graph G along with its
- -- component that their predecessor Pred has just been elaborated.
- -- This may cause new vertices to become elaborable, and thus be added
- -- to one of the two sets. All_Candidates is the set of all elaborable
- -- vertices across the whole library graph. Comp_Candidates is the set
- -- of all elaborable vertices in the component of Pred. Step is the
- -- current step in the elaboration order. Indent denotes the desired
- -- indentation level for tracing.
+ -- Notify the successor of edge Edge of library graph G along with its
+ -- component that their predecessor has just been elaborated. This may
+ -- cause new vertices to become elaborable. The sets contain vertices
+ -- arranged as follows:
+ --
+ -- * All_Elaborable_Vertices - all elaborable vertices in the library
+ -- graph.
+ --
+ -- * All_Waiting_Vertices - all vertices in the library graph that are
+ -- waiting on predecessors to be elaborated.
+ --
+ -- * Comp_Elaborable_Vertices - all elaborable vertices found in the
+ -- component of Vertex.
+ --
+ -- * Comp_Waiting_Vertices - all vertices found in the component of
+ -- Vertex that are still waiting on predecessors to be elaborated.
+ --
+ -- Step is the current step in the elaboration order. Indent denotes the
+ -- desired indentation level for tracing.
procedure Update_Successors
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- All_Candidates : Membership_Set;
- Comp_Candidates : Membership_Set;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level);
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level);
pragma Inline (Update_Successors);
- -- Notify all successors along with their components that their
- -- predecessor vertex Pred of ligrary graph G has just been elaborated.
- -- This may cause new vertices to become elaborable, and thus be added
- -- to one of the two sets. All_Candidates is the set of all elaborable
- -- vertices across the whole library graph. Comp_Candidates is the set
- -- of all elaborable vertices in the component of Pred. Step is the
- -- current step in the elaboration order. Indent denotes the desired
- -- indentation level for tracing.
-
- ----------------
- -- Add_Vertex --
- ----------------
-
- procedure Add_Vertex
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Set : Membership_Set;
- Msg : String;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level)
- is
- begin
- pragma Assert (Present (LGV_Id));
- pragma Assert (Needs_Elaboration (G, LGV_Id));
- pragma Assert (Present (Set));
-
- -- Add vertex only when it is not present in the set. This is not
- -- strictly necessary because the set implementation handles this
- -- case, however the check eliminates spurious traces.
-
- if not Contains (Set, LGV_Id) then
- Trace_Vertex
- (G => G,
- LGV_Id => LGV_Id,
- Msg => Msg,
- Step => Step,
- Indent => Indent);
-
- Insert (Set, LGV_Id);
- end if;
- end Add_Vertex;
-
- ------------------------------
- -- Add_Vertex_If_Elaborable --
- ------------------------------
-
- procedure Add_Vertex_If_Elaborable
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Set : Membership_Set;
- Msg : String;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level)
+ -- Notify all successors of vertex Vertex of library graph G along with
+ -- their components that their predecessor has just been elaborated.
+ -- This may cause new vertices to become elaborable. The sets contain
+ -- vertices arranged as follows:
+ --
+ -- * All_Elaborable_Vertices - all elaborable vertices in the library
+ -- graph.
+ --
+ -- * All_Waiting_Vertices - all vertices in the library graph that are
+ -- waiting on predecessors to be elaborated.
+ --
+ -- * Comp_Elaborable_Vertices - all elaborable vertices found in the
+ -- component of Vertex.
+ --
+ -- * Comp_Waiting_Vertices - all vertices found in the component of
+ -- Vertex that are still waiting on predecessors to be elaborated.
+ --
+ -- Step is the current step in the elaboration order. Indent denotes the
+ -- desired indentation level for tracing.
+
+ ----------------------------------
+ -- Create_Component_Vertex_Sets --
+ ----------------------------------
+
+ procedure Create_Component_Vertex_Sets
+ (G : Library_Graph;
+ Comp : Component_Id;
+ Elaborable_Vertices : out LGV_Sets.Membership_Set;
+ Waiting_Vertices : out LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step)
is
- Aux_LGV_Id : Library_Graph_Vertex_Id;
-
- begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
- pragma Assert (Needs_Elaboration (G, LGV_Id));
- pragma Assert (Present (Set));
-
- if Is_Elaborable_Vertex (G, LGV_Id) then
- Add_Vertex
- (G => G,
- LGV_Id => LGV_Id,
- Set => Set,
- Msg => Msg,
- Step => Step,
- Indent => Indent);
+ pragma Assert (Present (Comp));
- -- Assume that there is no extra vertex that needs to be added
+ Num_Of_Vertices : constant Natural :=
+ Number_Of_Component_Vertices (G, Comp);
- Aux_LGV_Id := No_Library_Graph_Vertex;
+ Iter : Component_Vertex_Iterator;
+ Vertex : Library_Graph_Vertex_Id;
- -- A spec-body pair where the spec carries pragma Elaborate_Body
- -- must be treated as one vertex for elaboration purposes. If one
- -- of them is elaborable, then the other is also elaborable. This
- -- property is guaranteed by predicate Is_Elaborable_Vertex.
+ begin
+ Elaborable_Vertices := LGV_Sets.Create (Num_Of_Vertices);
+ Waiting_Vertices := LGV_Sets.Create (Num_Of_Vertices);
- if Is_Body_Of_Spec_With_Elaborate_Body (G, LGV_Id) then
- Aux_LGV_Id := Proper_Spec (G, LGV_Id);
- pragma Assert (Present (Aux_LGV_Id));
+ Iter := Iterate_Component_Vertices (G, Comp);
+ while Has_Next (Iter) loop
+ Next (Iter, Vertex);
- elsif Is_Spec_With_Elaborate_Body (G, LGV_Id) then
- Aux_LGV_Id := Proper_Body (G, LGV_Id);
- pragma Assert (Present (Aux_LGV_Id));
- end if;
+ -- Add the vertex to the proper set depending on whether it can be
+ -- elaborated.
- if Present (Aux_LGV_Id) then
- pragma Assert (Needs_Elaboration (G, Aux_LGV_Id));
+ if Is_Elaborable_Vertex (G, Vertex) then
+ Insert_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Set => Elaborable_Vertices,
+ Msg => "add elaborable component vertex",
+ Step => Step,
+ Indent => No_Indentation);
- Add_Vertex
+ else
+ Insert_Vertex
(G => G,
- LGV_Id => Aux_LGV_Id,
- Set => Set,
- Msg => Msg,
+ Vertex => Vertex,
+ Set => Waiting_Vertices,
+ Msg => "add waiting component vertex",
Step => Step,
- Indent => Indent);
+ Indent => No_Indentation);
end if;
- end if;
- end Add_Vertex_If_Elaborable;
+ end loop;
+ end Create_Component_Vertex_Sets;
- -------------------------------
- -- Create_All_Candidates_Set --
- -------------------------------
+ ------------------------
+ -- Create_Vertex_Sets --
+ ------------------------
- function Create_All_Candidates_Set
- (G : Library_Graph;
- Step : Elaboration_Order_Step) return Membership_Set
+ procedure Create_Vertex_Sets
+ (G : Library_Graph;
+ Elaborable_Vertices : out LGV_Sets.Membership_Set;
+ Waiting_Vertices : out LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step)
is
+ pragma Assert (Present (G));
+
+ Num_Of_Vertices : constant Natural := Number_Of_Vertices (G);
+
Iter : Library_Graphs.All_Vertex_Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
- Set : Membership_Set;
+ Vertex : Library_Graph_Vertex_Id;
begin
- pragma Assert (Present (G));
+ Elaborable_Vertices := LGV_Sets.Create (Num_Of_Vertices);
+ Waiting_Vertices := LGV_Sets.Create (Num_Of_Vertices);
- Set := Create (Number_Of_Vertices (G));
Iter := Iterate_All_Vertices (G);
while Has_Next (Iter) loop
- Next (Iter, LGV_Id);
- pragma Assert (Present (LGV_Id));
-
- Add_Vertex_If_Elaborable
- (G => G,
- LGV_Id => LGV_Id,
- Set => Set,
- Msg => Add_To_All_Candidates_Msg,
- Step => Step,
- Indent => No_Indentation);
- end loop;
+ Next (Iter, Vertex);
- return Set;
- end Create_All_Candidates_Set;
+ -- Add the vertex to the proper set depending on whether it can be
+ -- elaborated.
- -------------------------------------
- -- Create_Component_Candidates_Set --
- -------------------------------------
-
- function Create_Component_Candidates_Set
- (G : Library_Graph;
- Comp : Component_Id;
- Step : Elaboration_Order_Step) return Membership_Set
- is
- Iter : Component_Vertex_Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
- Set : Membership_Set;
-
- begin
- pragma Assert (Present (G));
- pragma Assert (Present (Comp));
-
- Set := Create (Number_Of_Component_Vertices (G, Comp));
- Iter := Iterate_Component_Vertices (G, Comp);
- while Has_Next (Iter) loop
- Next (Iter, LGV_Id);
- pragma Assert (Present (LGV_Id));
+ if Is_Elaborable_Vertex (G, Vertex) then
+ Insert_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Set => Elaborable_Vertices,
+ Msg => "add elaborable vertex",
+ Step => Step,
+ Indent => No_Indentation);
- Add_Vertex_If_Elaborable
- (G => G,
- LGV_Id => LGV_Id,
- Set => Set,
- Msg => Add_To_Comp_Candidates_Msg,
- Step => Step,
- Indent => No_Indentation);
+ else
+ Insert_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Set => Waiting_Vertices,
+ Msg => "add waiting vertex",
+ Step => Step,
+ Indent => No_Indentation);
+ end if;
end loop;
-
- return Set;
- end Create_Component_Candidates_Set;
+ end Create_Vertex_Sets;
-------------------------
-- Elaborate_Component --
-------------------------
procedure Elaborate_Component
- (G : Library_Graph;
- Comp : Component_Id;
- All_Candidates : Membership_Set;
- Remaining_Vertices : in out Natural;
- Order : in out Unit_Id_Table;
- Step : Elaboration_Order_Step)
+ (G : Library_Graph;
+ Comp : Component_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Order : in out Unit_Id_Table;
+ Step : Elaboration_Order_Step)
is
- Candidate : Library_Graph_Vertex_Id;
- Comp_Candidates : Membership_Set;
+ Comp_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Vertex : Library_Graph_Vertex_Id;
begin
pragma Assert (Present (G));
pragma Assert (Present (Comp));
- pragma Assert (Present (All_Candidates));
+ pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (All_Waiting_Vertices));
Trace_Component
(G => G,
@@ -499,35 +508,81 @@ package body Bindo.Elaborators is
Msg => "elaborating component",
Step => Step);
- Comp_Candidates := Create_Component_Candidates_Set (G, Comp, Step);
+ -- Divide all vertices of the component into an elaborable and
+ -- waiting vertex set.
+
+ Create_Component_Vertex_Sets
+ (G => G,
+ Comp => Comp,
+ Elaborable_Vertices => Comp_Elaborable_Vertices,
+ Waiting_Vertices => Comp_Waiting_Vertices,
+ Step => Step);
loop
- Candidate :=
- Find_Best_Candidate
+ Trace_Vertices
+ (G => G,
+ Set => Comp_Elaborable_Vertices,
+ Set_Msg => "elaborable component vertices",
+ Vertex_Msg => "elaborable component vertex",
+ Step => Step,
+ Indent => Nested_Indentation);
+
+ Trace_Vertices
+ (G => G,
+ Set => Comp_Waiting_Vertices,
+ Set_Msg => "waiting component vertices",
+ Vertex_Msg => "waiting component vertex",
+ Step => Step,
+ Indent => Nested_Indentation);
+
+ Vertex :=
+ Find_Best_Elaborable_Vertex
(G => G,
- Set => Comp_Candidates,
+ Set => Comp_Elaborable_Vertices,
Step => Step,
Indent => Nested_Indentation);
- -- Stop the elaboration of the component when there is no suitable
- -- candidate. This indicates that either all vertices within the
- -- component have been elaborated, or the library graph contains a
- -- circularity.
+ -- The component lacks an elaborable vertex. This indicates that
+ -- either all vertices of the component have been elaborated or
+ -- the graph has a circularity. Locate the best weak vertex that
+ -- was compiled with the dynamic model to elaborate from the set
+ -- waiting vertices. This action assumes that certain invocations
+ -- will not take place at elaboration time. An order produced in
+ -- this fashion may fail an ABE check at run time.
+
+ if not Present (Vertex) then
+ Vertex :=
+ Find_Best_Weakly_Elaborable_Vertex
+ (G => G,
+ Set => Comp_Waiting_Vertices,
+ Step => Step,
+ Indent => Nested_Indentation);
+ end if;
+
+ -- Stop the elaboration when either all vertices of the component
+ -- have been elaborated, or the graph contains a circularity.
- exit when not Present (Candidate);
+ exit when not Present (Vertex);
+
+ -- Try to elaborate as many vertices within the component as
+ -- possible. Each successful elaboration signals the appropriate
+ -- successors and components that they have one less predecessor
+ -- to wait on.
Elaborate_Vertex
- (G => G,
- LGV_Id => Candidate,
- All_Candidates => All_Candidates,
- Comp_Candidates => Comp_Candidates,
- Remaining_Vertices => Remaining_Vertices,
- Order => Order,
- Step => Step,
- Indent => Nested_Indentation);
+ (G => G,
+ Vertex => Vertex,
+ All_Elaborable_Vertices => All_Elaborable_Vertices,
+ All_Waiting_Vertices => All_Waiting_Vertices,
+ Comp_Elaborable_Vertices => Comp_Elaborable_Vertices,
+ Comp_Waiting_Vertices => Comp_Waiting_Vertices,
+ Order => Order,
+ Step => Step,
+ Indent => Nested_Indentation);
end loop;
- Destroy (Comp_Candidates);
+ LGV_Sets.Destroy (Comp_Elaborable_Vertices);
+ LGV_Sets.Destroy (Comp_Waiting_Vertices);
end Elaborate_Component;
-----------------------------
@@ -539,77 +594,97 @@ package body Bindo.Elaborators is
Order : out Unit_Id_Table;
Status : out Elaboration_Order_Status)
is
- All_Candidates : Membership_Set;
- Candidate : Library_Graph_Vertex_Id;
- Comp : Component_Id;
- Remaining_Vertices : Natural;
- Step : Elaboration_Order_Step;
+ Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step;
+ Vertex : Library_Graph_Vertex_Id;
+ Waiting_Vertices : LGV_Sets.Membership_Set;
begin
pragma Assert (Present (G));
Step := Initial_Step;
- All_Candidates := Create_All_Candidates_Set (G, Step);
- Remaining_Vertices := Number_Of_Vertices (G);
+ -- Divide all vertices of the library graph into an elaborable and
+ -- waiting vertex set.
+
+ Create_Vertex_Sets
+ (G => G,
+ Elaborable_Vertices => Elaborable_Vertices,
+ Waiting_Vertices => Waiting_Vertices,
+ Step => Step);
loop
Step := Step + 1;
- Trace_Candidate_Vertices
- (G => G,
- Set => All_Candidates,
- Step => Step);
-
- Trace_Unelaborated_Vertices
- (G => G,
- Count => Remaining_Vertices,
- Step => Step);
-
- Candidate :=
- Find_Best_Candidate
+ Trace_Vertices
+ (G => G,
+ Set => Elaborable_Vertices,
+ Set_Msg => "elaborable vertices",
+ Vertex_Msg => "elaborable vertex",
+ Step => Step,
+ Indent => No_Indentation);
+
+ Trace_Vertices
+ (G => G,
+ Set => Waiting_Vertices,
+ Set_Msg => "waiting vertices",
+ Vertex_Msg => "waiting vertex",
+ Step => Step,
+ Indent => No_Indentation);
+
+ Vertex :=
+ Find_Best_Elaborable_Vertex
(G => G,
- Set => All_Candidates,
+ Set => Elaborable_Vertices,
Step => Step,
Indent => No_Indentation);
- -- Stop the elaboration when there is no suitable candidate. This
- -- indicates that either all units were elaborated or the library
- -- graph contains a circularity.
+ -- The graph lacks an elaborable vertex. This indicates that
+ -- either all vertices have been elaborated or the graph has a
+ -- circularity. Find the best weak vertex that was compiled with
+ -- the dynamic model to elaborate from set of waiting vertices.
+ -- This action assumes that certain invocations will not take
+ -- place at elaboration time. An order produced in this fashion
+ -- may fail an ABE check at run time.
+
+ if not Present (Vertex) then
+ Vertex :=
+ Find_Best_Weakly_Elaborable_Vertex
+ (G => G,
+ Set => Waiting_Vertices,
+ Step => Step,
+ Indent => No_Indentation);
+ end if;
- exit when not Present (Candidate);
+ -- Stop the elaboration when either all vertices of the graph have
+ -- been elaborated, or the graph contains a circularity.
- -- Elaborate the component of the candidate vertex by trying to
- -- elaborate as many vertices within the component as possible.
- -- Each successful elaboration signals the appropriate successors
- -- and their components that they have one less predecessor to
- -- wait on. This may add new candidates to set All_Candidates.
+ exit when not Present (Vertex);
- Comp := Component (G, Candidate);
- pragma Assert (Present (Comp));
+ -- Elaborate the component of the vertex by trying to elaborate as
+ -- many vertices within the component as possible. Each successful
+ -- elaboration signals the appropriate successors and components
+ -- that they have one less predecessor to wait on.
Elaborate_Component
- (G => G,
- Comp => Comp,
- All_Candidates => All_Candidates,
- Remaining_Vertices => Remaining_Vertices,
- Order => Order,
- Step => Step);
+ (G => G,
+ Comp => Component (G, Vertex),
+ All_Elaborable_Vertices => Elaborable_Vertices,
+ All_Waiting_Vertices => Waiting_Vertices,
+ Order => Order,
+ Step => Step);
end loop;
- Destroy (All_Candidates);
-
- -- The library graph contains an Elaborate_All circularity when
- -- at least one edge subject to the related pragma appears in a
- -- component.
+ -- The graph contains an Elaborate_All circularity when at least one
+ -- edge subject to the related pragma appears in a component.
if Has_Elaborate_All_Cycle (G) then
Status := Order_Has_Elaborate_All_Circularity;
- -- The library contains a circularity when at least one vertex failed
+ -- The graph contains a circularity when at least one vertex failed
-- to elaborate.
- elsif Remaining_Vertices /= 0 then
+ elsif LGV_Sets.Size (Waiting_Vertices) /= 0 then
Status := Order_Has_Circularity;
-- Otherwise the elaboration order is satisfactory
@@ -617,6 +692,9 @@ package body Bindo.Elaborators is
else
Status := Order_OK;
end if;
+
+ LGV_Sets.Destroy (Elaborable_Vertices);
+ LGV_Sets.Destroy (Waiting_Vertices);
end Elaborate_Library_Graph;
---------------------
@@ -627,11 +705,14 @@ package body Bindo.Elaborators is
(Order : out Unit_Id_Table;
Main_Lib_File : File_Name_Type)
is
- Main_Lib_Unit : constant Unit_Id :=
- Corresponding_Unit (Unit_Name_Type (Main_Lib_File));
+ pragma Unreferenced (Main_Lib_File);
+
+ Inv_Graph : Invocation_Graph;
+ Lib_Graph : Library_Graph;
+ Status : Elaboration_Order_Status;
begin
- pragma Assert (Present (Main_Lib_Unit));
+ Start_Phase (Unit_Elaboration);
-- Initialize all unit-related data structures and gather all units
-- that need elaboration.
@@ -639,71 +720,14 @@ package body Bindo.Elaborators is
Initialize_Units;
Collect_Elaborable_Units;
- Write_ALI_Tables;
-
- -- Choose the proper elaboration strategy based on whether the main
- -- library unit was compiled with dynamic elaboration checks.
-
- if Is_Dynamically_Elaborated (Main_Lib_Unit) then
- Elaborate_Units_Dynamic (Order);
- else
- Elaborate_Units_Static (Order);
- end if;
-
- Validate_Elaboration_Order (Order);
- Write_Elaboration_Order (Order);
-
- -- Enumerate the sources referenced in the closure of the order
-
- Write_Unit_Closure (Order);
-
- -- Destroy all unit-delated data structures
-
- Finalize_Units;
-
- exception
- when others =>
- Finalize_Units;
- raise;
- end Elaborate_Units;
-
- ----------------------------
- -- Elaborate_Units_Common --
- ----------------------------
-
- procedure Elaborate_Units_Common
- (Use_Inv_Graph : Boolean;
- Inv_Graph : out Invocation_Graph;
- Lib_Graph : out Library_Graph;
- Order : out Unit_Id_Table;
- Status : out Elaboration_Order_Status)
- is
- begin
- -- Create, validate, and output the library graph that captures the
- -- dependencies between library items.
+ -- Create the library graph that captures the dependencies between
+ -- library items.
Lib_Graph := Build_Library_Graph;
- Validate_Library_Graph (Lib_Graph);
- Write_Library_Graph (Lib_Graph);
-
- -- Create, validate, output, and use the invocation graph that
- -- represents the flow of execusion only when requested by the
- -- caller.
- if Use_Inv_Graph then
- Inv_Graph := Build_Invocation_Graph (Lib_Graph);
- Validate_Invocation_Graph (Inv_Graph);
- Write_Invocation_Graph (Inv_Graph);
+ -- Create the invocation graph that represents the flow of execution
- -- Otherwise the invocation graph is not used. Create a dummy graph
- -- as this allows for a uniform behavior on the caller side.
-
- else
- Inv_Graph :=
- Invocation_Graphs.Create
- (Initial_Vertices => 1,
- Initial_Edges => 1);
- end if;
+ Inv_Graph := Build_Invocation_Graph (Lib_Graph);
-- Traverse the invocation graph starting from elaboration code in
-- order to discover transitions of the execution flow from a unit
@@ -711,398 +735,604 @@ package body Bindo.Elaborators is
Augment_Library_Graph (Inv_Graph, Lib_Graph);
- -- Create and output the component graph by collapsing all library
- -- items into library units and traversing the library graph.
-
- Find_Components (Lib_Graph);
- Write_Library_Graph (Lib_Graph);
-
- -- Traverse the library graph to determine the elaboration order of
- -- units.
+ -- Create the component graph by collapsing all library items into
+ -- library units and traversing the library graph.
- Elaborate_Library_Graph
- (G => Lib_Graph,
- Order => Order,
- Status => Status);
- end Elaborate_Units_Common;
+ Find_Components (Lib_Graph);
- -----------------------------
- -- Elaborate_Units_Dynamic --
- -----------------------------
+ -- Output the contents of the ALI tables and both graphs to standard
+ -- output now that they have been fully decorated.
- procedure Elaborate_Units_Dynamic (Order : out Unit_Id_Table) is
- Dyn_Inv_Graph : Invocation_Graph;
- Dyn_Lib_Graph : Library_Graph;
- Dyn_Order : Unit_Id_Table;
- Mix_Inv_Graph : Invocation_Graph;
- Mix_Lib_Graph : Library_Graph;
- Mix_Order : Unit_Id_Table;
- Status : Elaboration_Order_Status;
+ Write_ALI_Tables;
+ Write_Invocation_Graph (Inv_Graph);
+ Write_Library_Graph (Lib_Graph);
- begin
- -- Attempt to elaborate the units in the library graph by mixing in
- -- the information from the invocation graph. This assumes that all
- -- invocations will take place at elaboration time.
+ -- Traverse the library graph to determine the elaboration order of
+ -- units.
- Elaborate_Units_Common
- (Use_Inv_Graph => True,
- Inv_Graph => Mix_Inv_Graph,
- Lib_Graph => Mix_Lib_Graph,
- Order => Mix_Order,
- Status => Status);
+ Elaborate_Library_Graph (Lib_Graph, Order, Status);
-- The elaboration order is satisfactory
if Status = Order_OK then
- Order := Mix_Order;
+ Validate_Elaboration_Order (Order);
- -- The library graph contains an Elaborate_All circularity. There is
- -- no point in re-elaborating the units without the information from
- -- the invocation graph because the circularity will persist.
+ -- Set attribute Elab_Position of table ALI.Units for all units in
+ -- the elaboration order.
- elsif Status = Order_Has_Elaborate_All_Circularity then
- Error_Msg ("elaboration circularity detected");
+ Set_Unit_Elaboration_Positions (Order);
- -- Report error here
+ -- Output the dependencies among units when switch -e (output
+ -- complete list of elaboration order dependencies) is active.
- -- Otherwise the library graph contains a circularity, or the extra
- -- information provided by the invocation graph caused a circularity.
- -- Re-elaborate the units without using the invocation graph. This
- -- assumes that all invocations will not take place at elaboration
- -- time.
-
- else
- pragma Assert (Status = Order_Has_Circularity);
+ Write_Dependencies (Lib_Graph);
- Elaborate_Units_Common
- (Use_Inv_Graph => False,
- Inv_Graph => Dyn_Inv_Graph,
- Lib_Graph => Dyn_Lib_Graph,
- Order => Dyn_Order,
- Status => Status);
+ -- Output the elaboration order when switch -l (output chosen
+ -- elaboration order) is in effect.
- -- The elaboration order is satisfactory. The elaboration of the
- -- program may still fail at runtime with an ABE.
+ Write_Elaboration_Order (Order);
- if Status = Order_OK then
- Order := Dyn_Order;
+ -- Output the sources referenced in the closure of the order when
+ -- switch -R (list sources referenced in closure) is in effect.
- -- Otherwise the library graph contains a circularity without the
- -- extra information provided by the invocation graph. Diagnose
- -- the circularity.
+ Write_Unit_Closure (Order);
- else
- Error_Msg ("elaboration circularity detected");
-
- -- Report error here
- end if;
+ -- Otherwise the library graph contains at least one circularity
- Destroy (Dyn_Inv_Graph);
- Destroy (Dyn_Lib_Graph);
- end if;
-
- Destroy (Mix_Inv_Graph);
- Destroy (Mix_Lib_Graph);
-
- -- Halt the bind as there is no satisfactory elaboration order
-
- if Status /= Order_OK then
- raise Unrecoverable_Error;
- end if;
- end Elaborate_Units_Dynamic;
-
- ----------------------------
- -- Elaborate_Units_Static --
- ----------------------------
-
- procedure Elaborate_Units_Static (Order : out Unit_Id_Table) is
- Inv_Graph : Invocation_Graph;
- Lib_Graph : Library_Graph;
- Status : Elaboration_Order_Status;
-
- begin
- -- Attempt to elaborate the units in the library graph by mixing in
- -- the information from the invocation graph. This assumes that all
- -- invocations will take place at elaboration time.
-
- Elaborate_Units_Common
- (Use_Inv_Graph => True,
- Inv_Graph => Inv_Graph,
- Lib_Graph => Lib_Graph,
- Order => Order,
- Status => Status);
-
- -- The augmented library graph contains a circularity
-
- if Status /= Order_OK then
- Error_Msg ("elaboration circularity detected");
-
- -- Report error here
+ else
+ Diagnose_Circularities (Inv_Graph, Lib_Graph);
end if;
Destroy (Inv_Graph);
Destroy (Lib_Graph);
- -- Halt the bind as there is no satisfactory elaboration order
+ -- Destroy all unit-related data structures
+
+ Finalize_Units;
+ End_Phase (Unit_Elaboration);
+
+ -- Halt the bind when there is no satisfactory elaboration order
if Status /= Order_OK then
raise Unrecoverable_Error;
end if;
- end Elaborate_Units_Static;
+ end Elaborate_Units;
----------------------
-- Elaborate_Vertex --
----------------------
procedure Elaborate_Vertex
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- All_Candidates : Membership_Set;
- Comp_Candidates : Membership_Set;
- Remaining_Vertices : in out Natural;
- Order : in out Unit_Id_Table;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level)
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Order : in out Unit_Id_Table;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
is
- Body_LGV_Id : Library_Graph_Vertex_Id;
- U_Id : Unit_Id;
-
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
- pragma Assert (Needs_Elaboration (G, LGV_Id));
- pragma Assert (Present (All_Candidates));
- pragma Assert (Present (Comp_Candidates));
+ pragma Assert (Present (Vertex));
+ pragma Assert (Needs_Elaboration (G, Vertex));
+ pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (All_Waiting_Vertices));
+ pragma Assert (LGV_Sets.Present (Comp_Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices));
Trace_Vertex
(G => G,
- LGV_Id => LGV_Id,
+ Vertex => Vertex,
Msg => "elaborating vertex",
Step => Step,
Indent => Indent);
- -- Remove the vertex from both candidate sets. This is needed when
+ -- Remove the vertex from both elaborable sets. This is needed when
-- the vertex is both an overall best candidate among all vertices,
- -- and the best candidate within the component. There is no need to
- -- check that the vertex is present in either set because the set
- -- implementation handles this case.
+ -- and the best candidate within the component.
- Delete (All_Candidates, LGV_Id);
- Delete (Comp_Candidates, LGV_Id);
+ LGV_Sets.Delete (All_Elaborable_Vertices, Vertex);
+ LGV_Sets.Delete (Comp_Elaborable_Vertices, Vertex);
+
+ -- Remove the vertex from both waiting sets. This is needed when a
+ -- weakly elaborable vertex is both an overall best candidate among
+ -- all waiting vertices and the best waiting candidate within the
+ -- component.
+
+ LGV_Sets.Delete (All_Waiting_Vertices, Vertex);
+ LGV_Sets.Delete (Comp_Waiting_Vertices, Vertex);
-- Mark the vertex as elaborated in order to prevent further attempts
-- to re-elaborate it.
- Set_In_Elaboration_Order (G, LGV_Id);
+ Set_In_Elaboration_Order (G, Vertex);
-- Add the unit represented by the vertex to the elaboration order
- U_Id := Unit (G, LGV_Id);
- pragma Assert (Present (U_Id));
-
- Unit_Id_Tables.Append (Order, U_Id);
-
- -- There is now one fewer vertex to elaborate
-
- Remaining_Vertices := Remaining_Vertices - 1;
+ Unit_Id_Tables.Append (Order, Unit (G, Vertex));
-- Notify all successors and their components that they have one
-- fewer predecessor to wait on. This may cause some successors to
-- be included in one of the sets.
Update_Successors
- (G => G,
- Pred => LGV_Id,
- All_Candidates => All_Candidates,
- Comp_Candidates => Comp_Candidates,
- Step => Step,
- Indent => Indent + Nested_Indentation);
-
- -- The vertex denotes a spec with a completing body, and is subject
- -- to pragma Elaborate_Body. Elaborate the body in order to satisfy
- -- the semantics of the pragma.
-
- if Is_Spec_With_Elaborate_Body (G, LGV_Id) then
- Body_LGV_Id := Proper_Body (G, LGV_Id);
- pragma Assert (Present (Body_LGV_Id));
-
+ (G => G,
+ Vertex => Vertex,
+ All_Elaborable_Vertices => All_Elaborable_Vertices,
+ All_Waiting_Vertices => All_Waiting_Vertices,
+ Comp_Elaborable_Vertices => Comp_Elaborable_Vertices,
+ Comp_Waiting_Vertices => Comp_Waiting_Vertices,
+ Step => Step,
+ Indent => Indent + Nested_Indentation);
+
+ -- Elaborate an eligible completing body immediately after its spec.
+ -- This action satisfies the semantics of pragma Elaborate_Body. In
+ -- addition, it ensures that a body will not "drift" too far from its
+ -- spec in case invocation edges are removed from the library graph.
+
+ if Has_Elaborable_Body (G, Vertex) then
Elaborate_Vertex
- (G => G,
- LGV_Id => Body_LGV_Id,
- All_Candidates => All_Candidates,
- Comp_Candidates => Comp_Candidates,
- Remaining_Vertices => Remaining_Vertices,
- Order => Order,
- Step => Step,
- Indent => Indent);
+ (G => G,
+ Vertex => Proper_Body (G, Vertex),
+ All_Elaborable_Vertices => All_Elaborable_Vertices,
+ All_Waiting_Vertices => All_Waiting_Vertices,
+ Comp_Elaborable_Vertices => Comp_Elaborable_Vertices,
+ Comp_Waiting_Vertices => Comp_Waiting_Vertices,
+ Order => Order,
+ Step => Step,
+ Indent => Indent);
end if;
end Elaborate_Vertex;
- -------------------------
- -- Find_Best_Candidate --
- -------------------------
+ ---------------------------------
+ -- Find_Best_Elaborable_Vertex --
+ ---------------------------------
- function Find_Best_Candidate
+ function Find_Best_Elaborable_Vertex
(G : Library_Graph;
- Set : Membership_Set;
+ Set : LGV_Sets.Membership_Set;
Step : Elaboration_Order_Step;
Indent : Indentation_Level) return Library_Graph_Vertex_Id
is
- Best : Library_Graph_Vertex_Id;
- Curr : Library_Graph_Vertex_Id;
- Iter : Iterator;
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (LGV_Sets.Present (Set));
+
+ return
+ Find_Best_Vertex
+ (G => G,
+ Set => Set,
+ Is_Suitable_Vertex =>
+ Is_Suitable_Elaborable_Vertex'Access,
+ Compare_Vertices =>
+ Is_Better_Elaborable_Vertex'Access,
+ Initial_Best_Msg => "initial best elaborable vertex",
+ Subsequent_Best_Msg => "better elaborable vertex",
+ Step => Step,
+ Indent => Indent);
+ end Find_Best_Elaborable_Vertex;
+
+ ----------------------
+ -- Find_Best_Vertex --
+ ----------------------
+
+ function Find_Best_Vertex
+ (G : Library_Graph;
+ Set : LGV_Sets.Membership_Set;
+ Is_Suitable_Vertex : LGV_Predicate_Ptr;
+ Compare_Vertices : LGV_Comparator_Ptr;
+ Initial_Best_Msg : String;
+ Subsequent_Best_Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
+ return Library_Graph_Vertex_Id
+ is
+ Best_Vertex : Library_Graph_Vertex_Id;
+ Current_Vertex : Library_Graph_Vertex_Id;
+ Iter : LGV_Sets.Iterator;
begin
pragma Assert (Present (G));
- pragma Assert (Present (Set));
+ pragma Assert (LGV_Sets.Present (Set));
+ pragma Assert (Is_Suitable_Vertex /= null);
+ pragma Assert (Compare_Vertices /= null);
-- Assume that there is no candidate
- Best := No_Library_Graph_Vertex;
+ Best_Vertex := No_Library_Graph_Vertex;
+
+ -- Inspect all vertices in the set, looking for the best candidate
+ -- according to the comparator.
+
+ Iter := LGV_Sets.Iterate (Set);
+ while LGV_Sets.Has_Next (Iter) loop
+ LGV_Sets.Next (Iter, Current_Vertex);
+ pragma Assert (Needs_Elaboration (G, Current_Vertex));
+
+ if Is_Suitable_Vertex.all (G, Current_Vertex) then
+
+ -- A previous iteration already picked the best candidate.
+ -- Update the best candidate when the current vertex is a
+ -- better choice.
+
+ if Present (Best_Vertex) then
+ if Compare_Vertices.all
+ (G => G,
+ Vertex => Current_Vertex,
+ Compared_To => Best_Vertex) = Higher_Precedence
+ then
+ Best_Vertex := Current_Vertex;
+
+ Trace_Vertex
+ (G => G,
+ Vertex => Best_Vertex,
+ Msg => Subsequent_Best_Msg,
+ Step => Step,
+ Indent => Indent);
+ end if;
+
+ -- Otherwise this is the first candidate
+
+ else
+ Best_Vertex := Current_Vertex;
+
+ Trace_Vertex
+ (G => G,
+ Vertex => Best_Vertex,
+ Msg => Initial_Best_Msg,
+ Step => Step,
+ Indent => Indent);
+ end if;
+ end if;
+ end loop;
- -- Inspect all vertices in the set, looking for the best candidate to
- -- elaborate.
+ return Best_Vertex;
+ end Find_Best_Vertex;
- Iter := Iterate (Set);
- while Has_Next (Iter) loop
- Next (Iter, Curr);
+ ----------------------------------------
+ -- Find_Best_Weakly_Elaborable_Vertex --
+ ----------------------------------------
+
+ function Find_Best_Weakly_Elaborable_Vertex
+ (G : Library_Graph;
+ Set : LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level) return Library_Graph_Vertex_Id
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (LGV_Sets.Present (Set));
+
+ return
+ Find_Best_Vertex
+ (G => G,
+ Set => Set,
+ Is_Suitable_Vertex =>
+ Is_Suitable_Weakly_Elaborable_Vertex'Access,
+ Compare_Vertices =>
+ Is_Better_Weakly_Elaborable_Vertex'Access,
+ Initial_Best_Msg => "initial best weakly elaborable vertex",
+ Subsequent_Best_Msg => "better weakly elaborable vertex",
+ Step => Step,
+ Indent => Indent);
+ end Find_Best_Weakly_Elaborable_Vertex;
+
+ -------------------------
+ -- Has_Elaborable_Body --
+ -------------------------
+
+ function Has_Elaborable_Body
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
- pragma Assert (Present (Curr));
- pragma Assert (Needs_Elaboration (G, Curr));
+ -- The body of an already-elaborated spec subject to Elaborate_Body
+ -- is always elaborable.
- -- Update the best candidate when there is no such candidate
+ if Is_Spec_With_Elaborate_Body (G, Vertex) then
+ return True;
- if not Present (Best) then
- Best := Curr;
+ elsif Is_Spec_With_Body (G, Vertex) then
+ return Is_Elaborable_Vertex (G, Proper_Body (G, Vertex));
+ end if;
- Trace_Vertex
- (G => G,
- LGV_Id => Best,
- Msg => "initial best candidate vertex",
- Step => Step,
- Indent => Indent);
+ return False;
+ end Has_Elaborable_Body;
- -- Update the best candidate when the current vertex is a better
- -- choice.
+ ---------------------------------
+ -- Insert_Elaborable_Successor --
+ ---------------------------------
- elsif Is_Better_Candidate
- (G => G,
- Best_Candid => Best,
- New_Candid => Curr)
- then
- Best := Curr;
+ procedure Insert_Elaborable_Successor
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+ pragma Assert (LGV_Sets.Present (Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (All_Waiting_Vertices));
+ pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices));
- Trace_Vertex
- (G => G,
- LGV_Id => Best,
- Msg => "best candidate vertex",
- Step => Step,
- Indent => Indent);
- end if;
- end loop;
+ Complement : constant Library_Graph_Vertex_Id :=
+ Complementary_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Force_Complement => False);
- return Best;
- end Find_Best_Candidate;
+ begin
+ -- Remove the successor from both waiting vertex sets because it may
+ -- be the best vertex to elaborate across the whole graph and within
+ -- its component.
- -------------------------
- -- Is_Better_Candidate --
- -------------------------
+ LGV_Sets.Delete (All_Waiting_Vertices, Vertex);
+ LGV_Sets.Delete (Comp_Waiting_Vertices, Vertex);
+
+ Insert_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Set => Elaborable_Vertices,
+ Msg => Msg,
+ Step => Step,
+ Indent => Indent);
+
+ if Present (Complement) then
+
+ -- Remove the complement of the successor from both waiting vertex
+ -- sets because it may be the best vertex to elaborate across the
+ -- whole graph and within its component.
+
+ LGV_Sets.Delete (All_Waiting_Vertices, Complement);
+ LGV_Sets.Delete (Comp_Waiting_Vertices, Complement);
+
+ Insert_Vertex
+ (G => G,
+ Vertex => Complement,
+ Set => Elaborable_Vertices,
+ Msg => Msg,
+ Step => Step,
+ Indent => Indent);
+ end if;
+ end Insert_Elaborable_Successor;
+
+ -------------------
+ -- Insert_Vertex --
+ -------------------
+
+ procedure Insert_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Set : LGV_Sets.Membership_Set;
+ Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+ pragma Assert (Needs_Elaboration (G, Vertex));
+ pragma Assert (LGV_Sets.Present (Set));
+
+ -- Nothing to do when the vertex is already present in the set
+
+ if LGV_Sets.Contains (Set, Vertex) then
+ return;
+ end if;
+
+ Trace_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Msg => Msg,
+ Step => Step,
+ Indent => Indent);
+
+ -- Add the vertex to the set
+
+ LGV_Sets.Insert (Set, Vertex);
+ end Insert_Vertex;
+
+ ---------------------------------
+ -- Is_Better_Elaborable_Vertex --
+ ---------------------------------
- function Is_Better_Candidate
+ function Is_Better_Elaborable_Vertex
(G : Library_Graph;
- Best_Candid : Library_Graph_Vertex_Id;
- New_Candid : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id;
+ Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (Best_Candid));
- pragma Assert (Present (New_Candid));
+ pragma Assert (Present (Vertex));
+ pragma Assert (Present (Compared_To));
+
+ -- Prefer a spec with Elaborate_Body over its corresponding body
+
+ if Is_Elaborate_Body_Pair
+ (G => G,
+ Spec_Vertex => Vertex,
+ Body_Vertex => Compared_To)
+ then
+ return Higher_Precedence;
+
+ elsif Is_Elaborate_Body_Pair
+ (G => G,
+ Spec_Vertex => Compared_To,
+ Body_Vertex => Vertex)
+ then
+ return Lower_Precedence;
-- Prefer a predefined unit over a non-predefined unit
- if Is_Predefined_Unit (G, Best_Candid)
- and then not Is_Predefined_Unit (G, New_Candid)
+ elsif Is_Predefined_Unit (G, Vertex)
+ and then not Is_Predefined_Unit (G, Compared_To)
then
- return False;
+ return Higher_Precedence;
- elsif not Is_Predefined_Unit (G, Best_Candid)
- and then Is_Predefined_Unit (G, New_Candid)
+ elsif not Is_Predefined_Unit (G, Vertex)
+ and then Is_Predefined_Unit (G, Compared_To)
then
- return True;
+ return Lower_Precedence;
- -- Prefer an internal unit over a non-iternal unit
+ -- Prefer an internal unit over a non-internal unit
- elsif Is_Internal_Unit (G, Best_Candid)
- and then not Is_Internal_Unit (G, New_Candid)
+ elsif Is_Internal_Unit (G, Vertex)
+ and then not Is_Internal_Unit (G, Compared_To)
then
- return False;
+ return Higher_Precedence;
- elsif not Is_Internal_Unit (G, Best_Candid)
- and then Is_Internal_Unit (G, New_Candid)
+ elsif not Is_Internal_Unit (G, Vertex)
+ and then Is_Internal_Unit (G, Compared_To)
then
- return True;
+ return Lower_Precedence;
-- Prefer a preelaborated unit over a non-preelaborated unit
- elsif Is_Preelaborated_Unit (G, Best_Candid)
- and then not Is_Preelaborated_Unit (G, New_Candid)
+ elsif Is_Preelaborated_Unit (G, Vertex)
+ and then not Is_Preelaborated_Unit (G, Compared_To)
then
- return False;
+ return Higher_Precedence;
- elsif not Is_Preelaborated_Unit (G, Best_Candid)
- and then Is_Preelaborated_Unit (G, New_Candid)
+ elsif not Is_Preelaborated_Unit (G, Vertex)
+ and then Is_Preelaborated_Unit (G, Compared_To)
then
- return True;
+ return Lower_Precedence;
-- Otherwise default to lexicographical order to ensure deterministic
-- behavior.
+ elsif Uname_Less (Name (G, Vertex), Name (G, Compared_To)) then
+ return Higher_Precedence;
+
else
- return Uname_Less (Name (G, Best_Candid), Name (G, New_Candid));
+ return Lower_Precedence;
end if;
- end Is_Better_Candidate;
+ end Is_Better_Elaborable_Vertex;
- ------------------------------
- -- Trace_Candidate_Vertices --
- ------------------------------
+ ----------------------------------------
+ -- Is_Better_Weakly_Elaborable_Vertex --
+ ----------------------------------------
- procedure Trace_Candidate_Vertices
- (G : Library_Graph;
- Set : Membership_Set;
- Step : Elaboration_Order_Step)
+ function Is_Better_Weakly_Elaborable_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind
is
- Iter : Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
+ Comp_Strong_Preds : Natural;
+ Comp_Weak_Preds : Natural;
+ Vertex_Strong_Preds : Natural;
+ Vertex_Weak_Preds : Natural;
begin
pragma Assert (Present (G));
- pragma Assert (Present (Set));
+ pragma Assert (Present (Vertex));
+ pragma Assert (Present (Compared_To));
- -- Nothing to do when switch -d_T (output elaboration order trace
- -- information) is not in effect.
+ -- Obtain the number of pending predecessors for both candidates,
+ -- taking into account Elaborate_Body pairs.
- if not Debug_Flag_Underscore_TT then
- return;
+ Pending_Predecessors_For_Elaboration
+ (G => G,
+ Vertex => Vertex,
+ Strong_Preds => Vertex_Strong_Preds,
+ Weak_Preds => Vertex_Weak_Preds);
+
+ Pending_Predecessors_For_Elaboration
+ (G => G,
+ Vertex => Compared_To,
+ Strong_Preds => Comp_Strong_Preds,
+ Weak_Preds => Comp_Weak_Preds);
+
+ -- Neither candidate should be waiting on strong predecessors,
+ -- otherwise the candidate cannot be weakly elaborated.
+
+ pragma Assert (Vertex_Strong_Preds = 0);
+ pragma Assert (Comp_Strong_Preds = 0);
+
+ -- Prefer a unit with fewer weak predecessors over a unit with more
+ -- weak predecessors.
+
+ if Vertex_Weak_Preds < Comp_Weak_Preds then
+ return Higher_Precedence;
+
+ elsif Vertex_Weak_Preds > Comp_Weak_Preds then
+ return Lower_Precedence;
+
+ -- Otherwise default to lexicographical order to ensure deterministic
+ -- behavior.
+
+ elsif Uname_Less (Name (G, Vertex), Name (G, Compared_To)) then
+ return Higher_Precedence;
+
+ else
+ return Lower_Precedence;
end if;
+ end Is_Better_Weakly_Elaborable_Vertex;
- Trace_Step (Step);
- Write_Str ("candidate vertices: ");
- Write_Int (Int (Size (Set)));
- Write_Eol;
+ -----------------------------------
+ -- Is_Suitable_Elaborable_Vertex --
+ -----------------------------------
- Iter := Iterate (Set);
- while Has_Next (Iter) loop
- Next (Iter, LGV_Id);
- pragma Assert (Present (LGV_Id));
+ function Is_Suitable_Elaborable_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
- Trace_Vertex
- (G => G,
- LGV_Id => LGV_Id,
- Msg => "candidate vertex",
- Step => Step,
- Indent => Nested_Indentation);
+ -- A vertex is suitable for elaboration as long it is not waiting on
+ -- any predecessors, ignoring the static or dynamic model.
+
+ return Is_Elaborable_Vertex (G, Vertex);
+ end Is_Suitable_Elaborable_Vertex;
+
+ ------------------------------------------
+ -- Is_Suitable_Weakly_Elaborable_Vertex --
+ ------------------------------------------
+
+ function Is_Suitable_Weakly_Elaborable_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ -- A vertex is suitable for weak elaboration when it is waiting on
+ -- weak predecessors only, and the unit it represents was compiled
+ -- using the dynamic model.
+
+ return
+ Is_Dynamically_Elaborated (G, Vertex)
+ and then Is_Weakly_Elaborable_Vertex (G, Vertex);
+ end Is_Suitable_Weakly_Elaborable_Vertex;
+
+ ------------------------------------
+ -- Set_Unit_Elaboration_Positions --
+ ------------------------------------
+
+ procedure Set_Unit_Elaboration_Positions (Order : Unit_Id_Table) is
+ U_Id : Unit_Id;
+
+ begin
+ for Position in Unit_Id_Tables.First ..
+ Unit_Id_Tables.Last (Order)
+ loop
+ U_Id := Order.Table (Position);
+
+ ALI.Units.Table (U_Id).Elab_Position := Position;
end loop;
- end Trace_Candidate_Vertices;
+ end Set_Unit_Elaboration_Positions;
---------------------
-- Trace_Component --
@@ -1118,8 +1348,8 @@ package body Bindo.Elaborators is
pragma Assert (Present (G));
pragma Assert (Present (Comp));
- -- Nothing to do when switch -d_T (output elaboration order trace
- -- information) is not in effect.
+ -- Nothing to do when switch -d_T (output elaboration order and cycle
+ -- detection trace information) is not in effect.
if not Debug_Flag_Underscore_TT then
return;
@@ -1134,8 +1364,14 @@ package body Bindo.Elaborators is
Trace_Step (Step);
Indent_By (Nested_Indentation);
- Write_Str ("pending predecessors: ");
- Write_Num (Int (Pending_Predecessors (G, Comp)));
+ Write_Str ("pending strong predecessors: ");
+ Write_Num (Int (Pending_Strong_Predecessors (G, Comp)));
+ Write_Eol;
+
+ Trace_Step (Step);
+ Indent_By (Nested_Indentation);
+ Write_Str ("pending weak predecessors : ");
+ Write_Num (Int (Pending_Weak_Predecessors (G, Comp)));
Write_Eol;
end Trace_Component;
@@ -1145,8 +1381,8 @@ package body Bindo.Elaborators is
procedure Trace_Step (Step : Elaboration_Order_Step) is
begin
- -- Nothing to do when switch -d_T (output elaboration order trace
- -- information) is not in effect.
+ -- Nothing to do when switch -d_T (output elaboration order and cycle
+ -- detection trace information) is not in effect.
if not Debug_Flag_Underscore_TT then
return;
@@ -1158,72 +1394,27 @@ package body Bindo.Elaborators is
Write_Str (": ");
end Trace_Step;
- ---------------------------------
- -- Trace_Unelaborated_Vertices --
- ---------------------------------
-
- procedure Trace_Unelaborated_Vertices
- (G : Library_Graph;
- Count : Natural;
- Step : Elaboration_Order_Step)
- is
- Iter : Library_Graphs.All_Vertex_Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
-
- begin
- pragma Assert (Present (G));
-
- -- Nothing to do when switch -d_T (output elaboration order trace
- -- information) is not in effect.
-
- if not Debug_Flag_Underscore_TT then
- return;
- end if;
-
- Trace_Step (Step);
- Write_Str ("remaining unelaborated vertices: ");
- Write_Int (Int (Count));
- Write_Eol;
-
- Iter := Iterate_All_Vertices (G);
- while Has_Next (Iter) loop
- Next (Iter, LGV_Id);
- pragma Assert (Present (LGV_Id));
-
- if Needs_Elaboration (G, LGV_Id)
- and then not In_Elaboration_Order (G, LGV_Id)
- then
- Trace_Vertex
- (G => G,
- LGV_Id => LGV_Id,
- Msg => "remaining vertex",
- Step => Step,
- Indent => Nested_Indentation);
- end if;
- end loop;
- end Trace_Unelaborated_Vertices;
-
------------------
-- Trace_Vertex --
------------------
procedure Trace_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Msg : String;
Step : Elaboration_Order_Step;
Indent : Indentation_Level)
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- Comp : constant Component_Id := Component (G, LGV_Id);
-
- pragma Assert (Present (Comp));
+ Attr_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
+ Comp : constant Component_Id := Component (G, Vertex);
begin
- -- Nothing to do when switch -d_T (output elaboration order trace
- -- information) is not in effect.
+ -- Nothing to do when switch -d_T (output elaboration order and cycle
+ -- detection trace information) is not in effect.
if not Debug_Flag_Underscore_TT then
return;
@@ -1233,74 +1424,141 @@ package body Bindo.Elaborators is
Indent_By (Indent);
Write_Str (Msg);
Write_Str (" (LGV_Id_");
- Write_Int (Int (LGV_Id));
+ Write_Int (Int (Vertex));
Write_Str (")");
Write_Eol;
Trace_Step (Step);
- Indent_By (Indent + Nested_Indentation);
+ Indent_By (Attr_Indent);
Write_Str ("name = ");
- Write_Name (Name (G, LGV_Id));
+ Write_Name (Name (G, Vertex));
Write_Eol;
Trace_Step (Step);
- Indent_By (Indent + Nested_Indentation);
+ Indent_By (Attr_Indent);
Write_Str ("Component (Comp_Id_");
Write_Int (Int (Comp));
Write_Str (")");
Write_Eol;
Trace_Step (Step);
- Indent_By (Indent + Nested_Indentation);
- Write_Str ("pending predecessors: ");
- Write_Num (Int (Pending_Predecessors (G, LGV_Id)));
+ Indent_By (Attr_Indent);
+ Write_Str ("pending strong predecessors: ");
+ Write_Num (Int (Pending_Strong_Predecessors (G, Vertex)));
+ Write_Eol;
+
+ Trace_Step (Step);
+ Indent_By (Attr_Indent);
+ Write_Str ("pending weak predecessors : ");
+ Write_Num (Int (Pending_Weak_Predecessors (G, Vertex)));
+ Write_Eol;
+
+ Trace_Step (Step);
+ Indent_By (Attr_Indent);
+ Write_Str ("pending strong components : ");
+ Write_Num (Int (Pending_Strong_Predecessors (G, Comp)));
Write_Eol;
Trace_Step (Step);
- Indent_By (Indent + Nested_Indentation);
- Write_Str ("pending components : ");
- Write_Num (Int (Pending_Predecessors (G, Comp)));
+ Indent_By (Attr_Indent);
+ Write_Str ("pending weak components : ");
+ Write_Num (Int (Pending_Weak_Predecessors (G, Comp)));
Write_Eol;
end Trace_Vertex;
+ --------------------
+ -- Trace_Vertices --
+ --------------------
+
+ procedure Trace_Vertices
+ (G : Library_Graph;
+ Set : LGV_Sets.Membership_Set;
+ Set_Msg : String;
+ Vertex_Msg : String;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
+ is
+ Vertex_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
+
+ Iter : LGV_Sets.Iterator;
+ Vertex : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (LGV_Sets.Present (Set));
+
+ -- Nothing to do when switch -d_T (output elaboration order and cycle
+ -- detection trace information) is not in effect.
+
+ if not Debug_Flag_Underscore_TT then
+ return;
+ end if;
+
+ Trace_Step (Step);
+ Indent_By (Indent);
+ Write_Str (Set_Msg);
+ Write_Str (": ");
+ Write_Int (Int (LGV_Sets.Size (Set)));
+ Write_Eol;
+
+ Iter := LGV_Sets.Iterate (Set);
+ while LGV_Sets.Has_Next (Iter) loop
+ LGV_Sets.Next (Iter, Vertex);
+
+ Trace_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Msg => Vertex_Msg,
+ Step => Step,
+ Indent => Vertex_Indent);
+ end loop;
+ end Trace_Vertices;
+
----------------------
-- Update_Successor --
----------------------
procedure Update_Successor
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- Succ : Library_Graph_Vertex_Id;
- All_Candidates : Membership_Set;
- Comp_Candidates : Membership_Set;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level)
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
is
pragma Assert (Present (G));
- pragma Assert (Present (Pred));
+ pragma Assert (Present (Edge));
+ pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (All_Waiting_Vertices));
+ pragma Assert (LGV_Sets.Present (Comp_Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices));
+
+ Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
+
pragma Assert (Needs_Elaboration (G, Pred));
- pragma Assert (Present (Succ));
pragma Assert (Needs_Elaboration (G, Succ));
- pragma Assert (Present (All_Candidates));
- pragma Assert (Present (Comp_Candidates));
- Pred_Comp : constant Component_Id := Component (G, Pred);
- Succ_Comp : constant Component_Id := Component (G, Succ);
+ In_Different_Components : constant Boolean :=
+ not In_Same_Component
+ (G => G,
+ Left => Pred,
+ Right => Succ);
- pragma Assert (Present (Pred_Comp));
- pragma Assert (Present (Succ_Comp));
+ Succ_Comp : constant Component_Id := Component (G, Succ);
+ Vertex_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
- In_Different_Components : constant Boolean := Pred_Comp /= Succ_Comp;
-
- Candidate : Library_Graph_Vertex_Id;
- Iter : Component_Vertex_Iterator;
- Msg : String_Ptr;
- Set : Membership_Set;
+ Iter : Component_Vertex_Iterator;
+ Vertex : Library_Graph_Vertex_Id;
begin
Trace_Vertex
(G => G,
- LGV_Id => Succ,
+ Vertex => Succ,
Msg => "updating successor",
Step => Step,
Indent => Indent);
@@ -1308,45 +1566,61 @@ package body Bindo.Elaborators is
-- Notify the successor that it has one less predecessor to wait on.
-- This effectively eliminates the edge that links the two.
- Decrement_Pending_Predecessors (G, Succ);
+ Decrement_Pending_Predecessors
+ (G => G,
+ Vertex => Succ,
+ Edge => Edge);
-- The predecessor and successor reside in different components.
-- Notify the successor component it has one fewer components to
-- wait on.
if In_Different_Components then
- Decrement_Pending_Predecessors (G, Succ_Comp);
+ Decrement_Pending_Predecessors
+ (G => G,
+ Comp => Succ_Comp,
+ Edge => Edge);
end if;
-- At this point the successor may become elaborable when its final
- -- predecessor or final predecessor component is elaborated.
-
- -- The predecessor and successor reside in different components.
- -- The successor must not be added to the candidates of Pred's
- -- component because this will mix units from the two components.
- -- Instead, the successor is added to the set of all candidates
- -- that must be elaborated.
-
- if In_Different_Components then
- Msg := Add_To_All_Candidates_Msg'Access;
- Set := All_Candidates;
-
- -- Otherwise the predecessor and successor reside within the same
- -- component. Pred's component gains another elaborable node.
+ -- predecessor or final predecessor component has been elaborated.
+
+ if Is_Elaborable_Vertex (G, Succ) then
+
+ -- The predecessor and successor reside in different components.
+ -- The successor must not be added to the candidates of Pred's
+ -- component because this will mix units from the two components.
+ -- Instead, the successor is added to the set of all elaborable
+ -- vertices.
+
+ if In_Different_Components then
+ Insert_Elaborable_Successor
+ (G => G,
+ Vertex => Succ,
+ Elaborable_Vertices => All_Elaborable_Vertices,
+ All_Waiting_Vertices => All_Waiting_Vertices,
+ Comp_Waiting_Vertices => Comp_Waiting_Vertices,
+ Msg => "add elaborable successor",
+ Step => Step,
+ Indent => Vertex_Indent);
+
+ -- Otherwise the predecessor and successor reside within the same
+ -- component. Pred's component gains another elaborable vertex.
- else
- Msg := Add_To_Comp_Candidates_Msg'Access;
- Set := Comp_Candidates;
+ else
+ Insert_Elaborable_Successor
+ (G => G,
+ Vertex => Succ,
+ Elaborable_Vertices => Comp_Elaborable_Vertices,
+ All_Waiting_Vertices => All_Waiting_Vertices,
+ Comp_Waiting_Vertices => Comp_Waiting_Vertices,
+ Msg =>
+ "add elaborable component successor",
+ Step => Step,
+ Indent => Vertex_Indent);
+ end if;
end if;
- Add_Vertex_If_Elaborable
- (G => G,
- LGV_Id => Succ,
- Set => Set,
- Msg => Msg.all,
- Step => Step,
- Indent => Indent + Nested_Indentation);
-
-- At this point the successor component may become elaborable when
-- its final predecessor component is elaborated. This in turn may
-- allow vertices of the successor component to be elaborated.
@@ -1356,16 +1630,19 @@ package body Bindo.Elaborators is
then
Iter := Iterate_Component_Vertices (G, Succ_Comp);
while Has_Next (Iter) loop
- Next (Iter, Candidate);
- pragma Assert (Present (Candidate));
-
- Add_Vertex_If_Elaborable
- (G => G,
- LGV_Id => Candidate,
- Set => All_Candidates,
- Msg => Add_To_All_Candidates_Msg,
- Step => Step,
- Indent => Indent + Nested_Indentation);
+ Next (Iter, Vertex);
+
+ if Is_Elaborable_Vertex (G, Vertex) then
+ Insert_Elaborable_Successor
+ (G => G,
+ Vertex => Vertex,
+ Elaborable_Vertices => All_Elaborable_Vertices,
+ All_Waiting_Vertices => All_Waiting_Vertices,
+ Comp_Waiting_Vertices => Comp_Waiting_Vertices,
+ Msg => "add elaborable vertex",
+ Step => Step,
+ Indent => Vertex_Indent);
+ end if;
end loop;
end if;
end Update_Successor;
@@ -1375,42 +1652,41 @@ package body Bindo.Elaborators is
-----------------------
procedure Update_Successors
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- All_Candidates : Membership_Set;
- Comp_Candidates : Membership_Set;
- Step : Elaboration_Order_Step;
- Indent : Indentation_Level)
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ All_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ All_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Comp_Elaborable_Vertices : LGV_Sets.Membership_Set;
+ Comp_Waiting_Vertices : LGV_Sets.Membership_Set;
+ Step : Elaboration_Order_Step;
+ Indent : Indentation_Level)
is
- Iter : Edges_To_Successors_Iterator;
- LGE_Id : Library_Graph_Edge_Id;
- Succ : Library_Graph_Vertex_Id;
+ Edge : Library_Graph_Edge_Id;
+ Iter : Edges_To_Successors_Iterator;
begin
pragma Assert (Present (G));
- pragma Assert (Present (Pred));
- pragma Assert (Needs_Elaboration (G, Pred));
- pragma Assert (Present (All_Candidates));
- pragma Assert (Present (Comp_Candidates));
-
- Iter := Iterate_Edges_To_Successors (G, Pred);
+ pragma Assert (Present (Vertex));
+ pragma Assert (Needs_Elaboration (G, Vertex));
+ pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (All_Waiting_Vertices));
+ pragma Assert (LGV_Sets.Present (Comp_Elaborable_Vertices));
+ pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices));
+
+ Iter := Iterate_Edges_To_Successors (G, Vertex);
while Has_Next (Iter) loop
- Next (Iter, LGE_Id);
-
- pragma Assert (Present (LGE_Id));
- pragma Assert (Predecessor (G, LGE_Id) = Pred);
-
- Succ := Successor (G, LGE_Id);
- pragma Assert (Present (Succ));
+ Next (Iter, Edge);
+ pragma Assert (Predecessor (G, Edge) = Vertex);
Update_Successor
- (G => G,
- Pred => Pred,
- Succ => Succ,
- All_Candidates => All_Candidates,
- Comp_Candidates => Comp_Candidates,
- Step => Step,
- Indent => Indent);
+ (G => G,
+ Edge => Edge,
+ All_Elaborable_Vertices => All_Elaborable_Vertices,
+ All_Waiting_Vertices => All_Waiting_Vertices,
+ Comp_Elaborable_Vertices => Comp_Elaborable_Vertices,
+ Comp_Waiting_Vertices => Comp_Waiting_Vertices,
+ Step => Step,
+ Indent => Indent);
end loop;
end Update_Successors;
end Invocation_And_Library_Graph_Elaborators;
diff --git a/gcc/ada/bindo-graphs.adb b/gcc/ada/bindo-graphs.adb
index b2f458c..c2f9d6c 100644
--- a/gcc/ada/bindo-graphs.adb
+++ b/gcc/ada/bindo-graphs.adb
@@ -25,7 +25,13 @@
with Ada.Unchecked_Deallocation;
-with GNAT.Lists; use GNAT.Lists;
+with Butil; use Butil;
+with Debug; use Debug;
+with Output; use Output;
+
+with Bindo.Writers;
+use Bindo.Writers;
+use Bindo.Writers.Phase_Writers;
package body Bindo.Graphs is
@@ -33,33 +39,85 @@ package body Bindo.Graphs is
-- Local subprograms --
-----------------------
- function Sequence_Next_IGE_Id return Invocation_Graph_Edge_Id;
- pragma Inline (Sequence_Next_IGE_Id);
- -- Generate a new unique invocation graph edge handle
+ function Sequence_Next_Cycle return Library_Graph_Cycle_Id;
+ pragma Inline (Sequence_Next_Cycle);
+ -- Generate a new unique library graph cycle handle
- function Sequence_Next_IGV_Id return Invocation_Graph_Vertex_Id;
- pragma Inline (Sequence_Next_IGV_Id);
- -- Generate a new unique invocation graph vertex handle
+ function Sequence_Next_Edge return Invocation_Graph_Edge_Id;
+ pragma Inline (Sequence_Next_Edge);
+ -- Generate a new unique invocation graph edge handle
- function Sequence_Next_LGE_Id return Library_Graph_Edge_Id;
- pragma Inline (Sequence_Next_LGE_Id);
+ function Sequence_Next_Edge return Library_Graph_Edge_Id;
+ pragma Inline (Sequence_Next_Edge);
-- Generate a new unique library graph edge handle
- function Sequence_Next_LGV_Id return Library_Graph_Vertex_Id;
- pragma Inline (Sequence_Next_LGV_Id);
+ function Sequence_Next_Vertex return Invocation_Graph_Vertex_Id;
+ pragma Inline (Sequence_Next_Vertex);
+ -- Generate a new unique invocation graph vertex handle
+
+ function Sequence_Next_Vertex return Library_Graph_Vertex_Id;
+ pragma Inline (Sequence_Next_Vertex);
-- Generate a new unique library graph vertex handle
+ -----------------------------------
+ -- Destroy_Invocation_Graph_Edge --
+ -----------------------------------
+
+ procedure Destroy_Invocation_Graph_Edge
+ (Edge : in out Invocation_Graph_Edge_Id)
+ is
+ pragma Unreferenced (Edge);
+ begin
+ null;
+ end Destroy_Invocation_Graph_Edge;
+
+ ---------------------------------
+ -- Destroy_Library_Graph_Cycle --
+ ---------------------------------
+
+ procedure Destroy_Library_Graph_Cycle
+ (Cycle : in out Library_Graph_Cycle_Id)
+ is
+ pragma Unreferenced (Cycle);
+ begin
+ null;
+ end Destroy_Library_Graph_Cycle;
+
+ --------------------------------
+ -- Destroy_Library_Graph_Edge --
+ --------------------------------
+
+ procedure Destroy_Library_Graph_Edge
+ (Edge : in out Library_Graph_Edge_Id)
+ is
+ pragma Unreferenced (Edge);
+ begin
+ null;
+ end Destroy_Library_Graph_Edge;
+
+ ----------------------------------
+ -- Destroy_Library_Graph_Vertex --
+ ----------------------------------
+
+ procedure Destroy_Library_Graph_Vertex
+ (Vertex : in out Library_Graph_Vertex_Id)
+ is
+ pragma Unreferenced (Vertex);
+ begin
+ null;
+ end Destroy_Library_Graph_Vertex;
+
--------------------------------
-- Hash_Invocation_Graph_Edge --
--------------------------------
function Hash_Invocation_Graph_Edge
- (IGE_Id : Invocation_Graph_Edge_Id) return Bucket_Range_Type
+ (Edge : Invocation_Graph_Edge_Id) return Bucket_Range_Type
is
begin
- pragma Assert (Present (IGE_Id));
+ pragma Assert (Present (Edge));
- return Bucket_Range_Type (IGE_Id);
+ return Bucket_Range_Type (Edge);
end Hash_Invocation_Graph_Edge;
----------------------------------
@@ -67,25 +125,38 @@ package body Bindo.Graphs is
----------------------------------
function Hash_Invocation_Graph_Vertex
- (IGV_Id : Invocation_Graph_Vertex_Id) return Bucket_Range_Type
+ (Vertex : Invocation_Graph_Vertex_Id) return Bucket_Range_Type
is
begin
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
- return Bucket_Range_Type (IGV_Id);
+ return Bucket_Range_Type (Vertex);
end Hash_Invocation_Graph_Vertex;
+ ------------------------------
+ -- Hash_Library_Graph_Cycle --
+ ------------------------------
+
+ function Hash_Library_Graph_Cycle
+ (Cycle : Library_Graph_Cycle_Id) return Bucket_Range_Type
+ is
+ begin
+ pragma Assert (Present (Cycle));
+
+ return Bucket_Range_Type (Cycle);
+ end Hash_Library_Graph_Cycle;
+
-----------------------------
-- Hash_Library_Graph_Edge --
-----------------------------
function Hash_Library_Graph_Edge
- (LGE_Id : Library_Graph_Edge_Id) return Bucket_Range_Type
+ (Edge : Library_Graph_Edge_Id) return Bucket_Range_Type
is
begin
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Edge));
- return Bucket_Range_Type (LGE_Id);
+ return Bucket_Range_Type (Edge);
end Hash_Library_Graph_Edge;
-------------------------------
@@ -93,12 +164,12 @@ package body Bindo.Graphs is
-------------------------------
function Hash_Library_Graph_Vertex
- (LGV_Id : Library_Graph_Vertex_Id) return Bucket_Range_Type
+ (Vertex : Library_Graph_Vertex_Id) return Bucket_Range_Type
is
begin
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- return Bucket_Range_Type (LGV_Id);
+ return Bucket_Range_Type (Vertex);
end Hash_Library_Graph_Vertex;
-----------------------
@@ -116,18 +187,18 @@ package body Bindo.Graphs is
(Invocation_Graph_Attributes, Invocation_Graph);
function Get_IGE_Attributes
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id)
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id)
return Invocation_Graph_Edge_Attributes;
pragma Inline (Get_IGE_Attributes);
- -- Obtain the attributes of edge IGE_Id of invocation graph G
+ -- Obtain the attributes of edge Edge of invocation graph G
function Get_IGV_Attributes
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id)
+ Vertex : Invocation_Graph_Vertex_Id)
return Invocation_Graph_Vertex_Attributes;
pragma Inline (Get_IGV_Attributes);
- -- Obtain the attributes of vertex IGV_Id of invocation graph G
+ -- Obtain the attributes of vertex Vertex of invocation graph G
procedure Increment_Invocation_Graph_Edge_Count
(G : Invocation_Graph;
@@ -138,16 +209,16 @@ package body Bindo.Graphs is
function Is_Elaboration_Root
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Boolean;
+ Vertex : Invocation_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Elaboration_Root);
- -- Determine whether vertex IGV_Id of invocation graph denotes the
+ -- Determine whether vertex Vertex of invocation graph denotes the
-- elaboration procedure of a spec or a body.
function Is_Existing_Source_Target_Relation
(G : Invocation_Graph;
Rel : Source_Target_Relation) return Boolean;
pragma Inline (Is_Existing_Source_Target_Relation);
- -- Determine whether a source vertex and a target vertex desctibed by
+ -- Determine whether a source vertex and a target vertex described by
-- relation Rel are already related in invocation graph G.
procedure Save_Elaboration_Root
@@ -159,31 +230,31 @@ package body Bindo.Graphs is
procedure Set_Corresponding_Vertex
(G : Invocation_Graph;
IS_Id : Invocation_Signature_Id;
- IGV_Id : Invocation_Graph_Vertex_Id);
+ Vertex : Invocation_Graph_Vertex_Id);
pragma Inline (Set_Corresponding_Vertex);
- -- Associate vertex IGV_Id of invocation graph G with signature IS_Id
+ -- Associate vertex Vertex of invocation graph G with signature IS_Id
procedure Set_Is_Existing_Source_Target_Relation
(G : Invocation_Graph;
Rel : Source_Target_Relation;
Val : Boolean := True);
pragma Inline (Set_Is_Existing_Source_Target_Relation);
- -- Mark a source vertex and a target vertex desctibed by relation Rel as
+ -- Mark a source vertex and a target vertex described by relation Rel as
-- already related in invocation graph G depending on value Val.
procedure Set_IGE_Attributes
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id;
- Val : Invocation_Graph_Edge_Attributes);
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id;
+ Val : Invocation_Graph_Edge_Attributes);
pragma Inline (Set_IGE_Attributes);
- -- Set the attributes of edge IGE_Id of invocation graph G to value Val
+ -- Set the attributes of edge Edge of invocation graph G to value Val
procedure Set_IGV_Attributes
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id;
+ Vertex : Invocation_Graph_Vertex_Id;
Val : Invocation_Graph_Vertex_Attributes);
pragma Inline (Set_IGV_Attributes);
- -- Set the attributes of vertex IGV_Id of invocation graph G to value
+ -- Set the attributes of vertex Vertex of invocation graph G to value
-- Val.
--------------
@@ -205,10 +276,7 @@ package body Bindo.Graphs is
(Source => Source,
Target => Target);
- IR_Rec : Invocation_Relation_Record renames
- Invocation_Relations.Table (IR_Id);
-
- IGE_Id : Invocation_Graph_Edge_Id;
+ Edge : Invocation_Graph_Edge_Id;
begin
-- Nothing to do when the source and target are already related by an
@@ -218,22 +286,22 @@ package body Bindo.Graphs is
return;
end if;
- IGE_Id := Sequence_Next_IGE_Id;
+ Edge := Sequence_Next_Edge;
-- Add the edge to the underlying graph
DG.Add_Edge
(G => G.Graph,
- E => IGE_Id,
+ E => Edge,
Source => Source,
Destination => Target);
-- Build and save the attributes of the edge
Set_IGE_Attributes
- (G => G,
- IGE_Id => IGE_Id,
- Val => (Relation => IR_Id));
+ (G => G,
+ Edge => Edge,
+ Val => (Relation => IR_Id));
-- Mark the source and target as related by the new edge. This
-- prevents all further attempts to link the same source and target.
@@ -242,7 +310,7 @@ package body Bindo.Graphs is
-- Update the edge statistics
- Increment_Invocation_Graph_Edge_Count (G, IR_Rec.Kind);
+ Increment_Invocation_Graph_Edge_Count (G, Kind (IR_Id));
end Add_Edge;
----------------
@@ -250,67 +318,97 @@ package body Bindo.Graphs is
----------------
procedure Add_Vertex
- (G : Invocation_Graph;
- IC_Id : Invocation_Construct_Id;
- LGV_Id : Library_Graph_Vertex_Id)
+ (G : Invocation_Graph;
+ IC_Id : Invocation_Construct_Id;
+ Body_Vertex : Library_Graph_Vertex_Id;
+ Spec_Vertex : Library_Graph_Vertex_Id)
is
pragma Assert (Present (G));
pragma Assert (Present (IC_Id));
- pragma Assert (Present (LGV_Id));
-
- IC_Rec : Invocation_Construct_Record renames
- Invocation_Constructs.Table (IC_Id);
-
- pragma Assert (Present (IC_Rec.Signature));
+ pragma Assert (Present (Body_Vertex));
+ pragma Assert (Present (Spec_Vertex));
- IGV_Id : Invocation_Graph_Vertex_Id;
+ Construct_Signature : constant Invocation_Signature_Id :=
+ Signature (IC_Id);
+ Vertex : Invocation_Graph_Vertex_Id;
begin
-- Nothing to do when the construct already has a vertex
- if Present (Corresponding_Vertex (G, IC_Rec.Signature)) then
+ if Present (Corresponding_Vertex (G, Construct_Signature)) then
return;
end if;
- IGV_Id := Sequence_Next_IGV_Id;
+ Vertex := Sequence_Next_Vertex;
-- Add the vertex to the underlying graph
- DG.Add_Vertex (G.Graph, IGV_Id);
+ DG.Add_Vertex (G.Graph, Vertex);
-- Build and save the attributes of the vertex
Set_IGV_Attributes
(G => G,
- IGV_Id => IGV_Id,
- Val => (Construct => IC_Id,
- Lib_Vertex => LGV_Id));
+ Vertex => Vertex,
+ Val => (Body_Vertex => Body_Vertex,
+ Construct => IC_Id,
+ Spec_Vertex => Spec_Vertex));
-- Associate the construct with its corresponding vertex
- Set_Corresponding_Vertex (G, IC_Rec.Signature, IGV_Id);
+ Set_Corresponding_Vertex (G, Construct_Signature, Vertex);
-- Save the vertex for later processing when it denotes a spec or
-- body elaboration procedure.
- if Is_Elaboration_Root (G, IGV_Id) then
- Save_Elaboration_Root (G, IGV_Id);
+ if Is_Elaboration_Root (G, Vertex) then
+ Save_Elaboration_Root (G, Vertex);
end if;
end Add_Vertex;
+ -----------------
+ -- Body_Vertex --
+ -----------------
+
+ function Body_Vertex
+ (G : Invocation_Graph;
+ Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return Get_IGV_Attributes (G, Vertex).Body_Vertex;
+ end Body_Vertex;
+
+ ------------
+ -- Column --
+ ------------
+
+ function Column
+ (G : Invocation_Graph;
+ Vertex : Invocation_Graph_Vertex_Id) return Nat
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return Column (Signature (Construct (G, Vertex)));
+ end Column;
+
---------------
-- Construct --
---------------
function Construct
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Invocation_Construct_Id
+ Vertex : Invocation_Graph_Vertex_Id) return Invocation_Construct_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
- return Get_IGV_Attributes (G, IGV_Id).Construct;
+ return Get_IGV_Attributes (G, Vertex).Construct;
end Construct;
--------------------------
@@ -325,7 +423,7 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (IS_Id));
- return SV.Get (G.Signature_To_Vertex, IS_Id);
+ return Signature_Tables.Get (G.Signature_To_Vertex, IS_Id);
end Corresponding_Vertex;
------------
@@ -339,15 +437,15 @@ package body Bindo.Graphs is
G : constant Invocation_Graph := new Invocation_Graph_Attributes;
begin
- G.Edge_Attributes := EA.Create (Initial_Edges);
+ G.Edge_Attributes := IGE_Tables.Create (Initial_Edges);
G.Graph :=
DG.Create
(Initial_Vertices => Initial_Vertices,
Initial_Edges => Initial_Edges);
- G.Relations := ST.Create (Initial_Edges);
- G.Roots := ER.Create (Initial_Vertices);
- G.Signature_To_Vertex := SV.Create (Initial_Vertices);
- G.Vertex_Attributes := VA.Create (Initial_Vertices);
+ G.Relations := Relation_Sets.Create (Initial_Edges);
+ G.Roots := IGV_Sets.Create (Initial_Vertices);
+ G.Signature_To_Vertex := Signature_Tables.Create (Initial_Vertices);
+ G.Vertex_Attributes := IGV_Tables.Create (Initial_Vertices);
return G;
end Create;
@@ -360,12 +458,12 @@ package body Bindo.Graphs is
begin
pragma Assert (Present (G));
- EA.Destroy (G.Edge_Attributes);
- DG.Destroy (G.Graph);
- ST.Destroy (G.Relations);
- ER.Destroy (G.Roots);
- SV.Destroy (G.Signature_To_Vertex);
- VA.Destroy (G.Vertex_Attributes);
+ IGE_Tables.Destroy (G.Edge_Attributes);
+ DG.Destroy (G.Graph);
+ Relation_Sets.Destroy (G.Relations);
+ IGV_Sets.Destroy (G.Roots);
+ Signature_Tables.Destroy (G.Signature_To_Vertex);
+ IGV_Tables.Destroy (G.Vertex_Attributes);
Free (G);
end Destroy;
@@ -375,9 +473,9 @@ package body Bindo.Graphs is
-----------------------------------
procedure Destroy_Invocation_Graph_Edge
- (IGE_Id : in out Invocation_Graph_Edge_Id)
+ (Edge : in out Invocation_Graph_Edge_Id)
is
- pragma Unreferenced (IGE_Id);
+ pragma Unreferenced (Edge);
begin
null;
end Destroy_Invocation_Graph_Edge;
@@ -399,9 +497,9 @@ package body Bindo.Graphs is
-------------------------------------
procedure Destroy_Invocation_Graph_Vertex
- (IGV_Id : in out Invocation_Graph_Vertex_Id)
+ (Vertex : in out Invocation_Graph_Vertex_Id)
is
- pragma Unreferenced (IGV_Id);
+ pragma Unreferenced (Vertex);
begin
null;
end Destroy_Invocation_Graph_Vertex;
@@ -418,20 +516,35 @@ package body Bindo.Graphs is
null;
end Destroy_Invocation_Graph_Vertex_Attributes;
+ -----------
+ -- Extra --
+ -----------
+
+ function Extra
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) return Name_Id
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return Extra (Relation (G, Edge));
+ end Extra;
+
------------------------
-- Get_IGE_Attributes --
------------------------
function Get_IGE_Attributes
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id)
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id)
return Invocation_Graph_Edge_Attributes
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGE_Id));
+ pragma Assert (Present (Edge));
- return EA.Get (G.Edge_Attributes, IGE_Id);
+ return IGE_Tables.Get (G.Edge_Attributes, Edge);
end Get_IGE_Attributes;
------------------------
@@ -440,14 +553,14 @@ package body Bindo.Graphs is
function Get_IGV_Attributes
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id)
+ Vertex : Invocation_Graph_Vertex_Id)
return Invocation_Graph_Vertex_Attributes
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
- return VA.Get (G.Vertex_Attributes, IGV_Id);
+ return IGV_Tables.Get (G.Vertex_Attributes, Vertex);
end Get_IGV_Attributes;
--------------
@@ -483,7 +596,7 @@ package body Bindo.Graphs is
function Has_Next (Iter : Elaboration_Root_Iterator) return Boolean is
begin
- return ER.Has_Next (ER.Iterator (Iter));
+ return IGV_Sets.Has_Next (IGV_Sets.Iterator (Iter));
end Has_Next;
-------------------------------
@@ -552,23 +665,19 @@ package body Bindo.Graphs is
function Is_Elaboration_Root
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Boolean
+ Vertex : Invocation_Graph_Vertex_Id) return Boolean
is
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
-
- IC_Id : constant Invocation_Construct_Id := Construct (G, IGV_Id);
-
- pragma Assert (Present (IC_Id));
+ pragma Assert (Present (Vertex));
- IC_Rec : Invocation_Construct_Record renames
- Invocation_Constructs.Table (IC_Id);
+ Vertex_Kind : constant Invocation_Construct_Kind :=
+ Kind (Construct (G, Vertex));
begin
return
- IC_Rec.Kind = Elaborate_Body_Procedure
+ Vertex_Kind = Elaborate_Body_Procedure
or else
- IC_Rec.Kind = Elaborate_Spec_Procedure;
+ Vertex_Kind = Elaborate_Spec_Procedure;
end Is_Elaboration_Root;
----------------------------------------
@@ -582,7 +691,7 @@ package body Bindo.Graphs is
begin
pragma Assert (Present (G));
- return ST.Contains (G.Relations, Rel);
+ return Relation_Sets.Contains (G.Relations, Rel);
end Is_Existing_Source_Target_Relation;
-----------------------
@@ -617,15 +726,15 @@ package body Bindo.Graphs is
function Iterate_Edges_To_Targets
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Edges_To_Targets_Iterator
+ Vertex : Invocation_Graph_Vertex_Id) return Edges_To_Targets_Iterator
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
return
Edges_To_Targets_Iterator
- (DG.Iterate_Outgoing_Edges (G.Graph, IGV_Id));
+ (DG.Iterate_Outgoing_Edges (G.Graph, Vertex));
end Iterate_Edges_To_Targets;
-------------------------------
@@ -638,7 +747,7 @@ package body Bindo.Graphs is
begin
pragma Assert (Present (G));
- return Elaboration_Root_Iterator (ER.Iterate (G.Roots));
+ return Elaboration_Root_Iterator (IGV_Sets.Iterate (G.Roots));
end Iterate_Elaboration_Roots;
----------
@@ -646,37 +755,30 @@ package body Bindo.Graphs is
----------
function Kind
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id) return Invocation_Kind
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) return Invocation_Kind
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (IGE_Id));
+ pragma Assert (Present (Edge));
- IR_Id : constant Invocation_Relation_Id := Relation (G, IGE_Id);
-
- pragma Assert (Present (IR_Id));
-
- IR_Rec : Invocation_Relation_Record renames
- Invocation_Relations.Table (IR_Id);
-
- begin
- return IR_Rec.Kind;
+ return Kind (Relation (G, Edge));
end Kind;
- ----------------
- -- Lib_Vertex --
- ----------------
+ ----------
+ -- Line --
+ ----------
- function Lib_Vertex
+ function Line
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id
+ Vertex : Invocation_Graph_Vertex_Id) return Nat
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
- return Get_IGV_Attributes (G, IGV_Id).Lib_Vertex;
- end Lib_Vertex;
+ return Line (Signature (Construct (G, Vertex)));
+ end Line;
----------
-- Name --
@@ -684,25 +786,13 @@ package body Bindo.Graphs is
function Name
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Name_Id
+ Vertex : Invocation_Graph_Vertex_Id) return Name_Id
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
-
- IC_Id : constant Invocation_Construct_Id := Construct (G, IGV_Id);
-
- pragma Assert (Present (IC_Id));
-
- IC_Rec : Invocation_Construct_Record renames
- Invocation_Constructs.Table (IC_Id);
-
- pragma Assert (Present (IC_Rec.Signature));
-
- IS_Rec : Invocation_Signature_Record renames
- Invocation_Signatures.Table (IC_Rec.Signature);
+ pragma Assert (Present (Vertex));
- begin
- return IS_Rec.Name;
+ return Name (Signature (Construct (G, Vertex)));
end Name;
----------
@@ -710,11 +800,11 @@ package body Bindo.Graphs is
----------
procedure Next
- (Iter : in out All_Edge_Iterator;
- IGE_Id : out Invocation_Graph_Edge_Id)
+ (Iter : in out All_Edge_Iterator;
+ Edge : out Invocation_Graph_Edge_Id)
is
begin
- DG.Next (DG.All_Edge_Iterator (Iter), IGE_Id);
+ DG.Next (DG.All_Edge_Iterator (Iter), Edge);
end Next;
----------
@@ -723,10 +813,10 @@ package body Bindo.Graphs is
procedure Next
(Iter : in out All_Vertex_Iterator;
- IGV_Id : out Invocation_Graph_Vertex_Id)
+ Vertex : out Invocation_Graph_Vertex_Id)
is
begin
- DG.Next (DG.All_Vertex_Iterator (Iter), IGV_Id);
+ DG.Next (DG.All_Vertex_Iterator (Iter), Vertex);
end Next;
----------
@@ -734,11 +824,11 @@ package body Bindo.Graphs is
----------
procedure Next
- (Iter : in out Edges_To_Targets_Iterator;
- IGE_Id : out Invocation_Graph_Edge_Id)
+ (Iter : in out Edges_To_Targets_Iterator;
+ Edge : out Invocation_Graph_Edge_Id)
is
begin
- DG.Next (DG.Outgoing_Edge_Iterator (Iter), IGE_Id);
+ DG.Next (DG.Outgoing_Edge_Iterator (Iter), Edge);
end Next;
----------
@@ -750,7 +840,7 @@ package body Bindo.Graphs is
Root : out Invocation_Graph_Vertex_Id)
is
begin
- ER.Next (ER.Iterator (Iter), Root);
+ IGV_Sets.Next (IGV_Sets.Iterator (Iter), Root);
end Next;
---------------------
@@ -770,13 +860,13 @@ package body Bindo.Graphs is
function Number_Of_Edges_To_Targets
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Natural
+ Vertex : Invocation_Graph_Vertex_Id) return Natural
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
- return DG.Number_Of_Outgoing_Edges (G.Graph, IGV_Id);
+ return DG.Number_Of_Outgoing_Edges (G.Graph, Vertex);
end Number_Of_Edges_To_Targets;
---------------------------------
@@ -789,7 +879,7 @@ package body Bindo.Graphs is
begin
pragma Assert (Present (G));
- return ER.Size (G.Roots);
+ return IGV_Sets.Size (G.Roots);
end Number_Of_Elaboration_Roots;
------------------------
@@ -817,14 +907,14 @@ package body Bindo.Graphs is
--------------
function Relation
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id) return Invocation_Relation_Id
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) return Invocation_Relation_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGE_Id));
+ pragma Assert (Present (Edge));
- return Get_IGE_Attributes (G, IGE_Id).Relation;
+ return Get_IGE_Attributes (G, Edge).Relation;
end Relation;
---------------------------
@@ -839,7 +929,7 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (Root));
- ER.Insert (G.Roots, Root);
+ IGV_Sets.Insert (G.Roots, Root);
end Save_Elaboration_Root;
------------------------------
@@ -849,14 +939,14 @@ package body Bindo.Graphs is
procedure Set_Corresponding_Vertex
(G : Invocation_Graph;
IS_Id : Invocation_Signature_Id;
- IGV_Id : Invocation_Graph_Vertex_Id)
+ Vertex : Invocation_Graph_Vertex_Id)
is
begin
pragma Assert (Present (G));
pragma Assert (Present (IS_Id));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
- SV.Put (G.Signature_To_Vertex, IS_Id, IGV_Id);
+ Signature_Tables.Put (G.Signature_To_Vertex, IS_Id, Vertex);
end Set_Corresponding_Vertex;
--------------------------------------------
@@ -874,9 +964,9 @@ package body Bindo.Graphs is
pragma Assert (Present (Rel.Target));
if Val then
- ST.Insert (G.Relations, Rel);
+ Relation_Sets.Insert (G.Relations, Rel);
else
- ST.Delete (G.Relations, Rel);
+ Relation_Sets.Delete (G.Relations, Rel);
end if;
end Set_Is_Existing_Source_Target_Relation;
@@ -885,15 +975,15 @@ package body Bindo.Graphs is
------------------------
procedure Set_IGE_Attributes
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id;
- Val : Invocation_Graph_Edge_Attributes)
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id;
+ Val : Invocation_Graph_Edge_Attributes)
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGE_Id));
+ pragma Assert (Present (Edge));
- EA.Put (G.Edge_Attributes, IGE_Id, Val);
+ IGE_Tables.Put (G.Edge_Attributes, Edge, Val);
end Set_IGE_Attributes;
------------------------
@@ -902,29 +992,44 @@ package body Bindo.Graphs is
procedure Set_IGV_Attributes
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id;
+ Vertex : Invocation_Graph_Vertex_Id;
Val : Invocation_Graph_Vertex_Attributes)
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
- VA.Put (G.Vertex_Attributes, IGV_Id, Val);
+ IGV_Tables.Put (G.Vertex_Attributes, Vertex, Val);
end Set_IGV_Attributes;
+ -----------------
+ -- Spec_Vertex --
+ -----------------
+
+ function Spec_Vertex
+ (G : Invocation_Graph;
+ Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return Get_IGV_Attributes (G, Vertex).Spec_Vertex;
+ end Spec_Vertex;
+
------------
-- Target --
------------
function Target
(G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id) return Invocation_Graph_Vertex_Id
+ Edge : Invocation_Graph_Edge_Id) return Invocation_Graph_Vertex_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGE_Id));
+ pragma Assert (Present (Edge));
- return DG.Destination_Vertex (G.Graph, IGE_Id);
+ return DG.Destination_Vertex (G.Graph, Edge);
end Target;
end Invocation_Graphs;
@@ -934,46 +1039,95 @@ package body Bindo.Graphs is
package body Library_Graphs is
- ---------------
- -- Edge list --
- ---------------
-
- package EL is new Doubly_Linked_Lists
- (Element_Type => Library_Graph_Edge_Id,
- "=" => "=",
- Destroy_Element => Destroy_Library_Graph_Edge);
-
-----------------------
-- Local subprograms --
-----------------------
procedure Add_Body_Before_Spec_Edge
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Edges : EL.Doubly_Linked_List);
+ Vertex : Library_Graph_Vertex_Id;
+ Edges : LGE_Lists.Doubly_Linked_List);
pragma Inline (Add_Body_Before_Spec_Edge);
- -- Create a new edge in library graph G between vertex LGV_Id and its
+ -- Create a new edge in library graph G between vertex Vertex and its
-- corresponding spec or body, where the body is a predecessor and the
-- spec a successor. Add the edge to list Edges.
procedure Add_Body_Before_Spec_Edges
(G : Library_Graph;
- Edges : EL.Doubly_Linked_List);
+ Edges : LGE_Lists.Doubly_Linked_List);
pragma Inline (Add_Body_Before_Spec_Edges);
-- Create new edges in library graph G for all vertices and their
-- corresponding specs or bodies, where the body is a predecessor
-- and the spec is a successor. Add all edges to list Edges.
function Add_Edge_With_Return
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- Succ : Library_Graph_Vertex_Id;
- Kind : Library_Graph_Edge_Kind) return Library_Graph_Edge_Id;
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id;
+ Kind : Library_Graph_Edge_Kind;
+ Activates_Task : Boolean) return Library_Graph_Edge_Id;
pragma Inline (Add_Edge_With_Return);
-- Create a new edge in library graph G with source vertex Pred and
-- destination vertex Succ, and return its handle. Kind denotes the
- -- nature of the edge. If Pred and Succ are already related, no edge
- -- is created and No_Library_Graph_Edge is returned.
+ -- nature of the edge. Activates_Task should be set when the edge
+ -- involves a task activation. If Pred and Succ are already related,
+ -- no edge is created and No_Library_Graph_Edge is returned.
+
+ function At_Least_One_Edge_Satisfies
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Predicate : LGE_Predicate_Ptr) return Boolean;
+ pragma Inline (At_Least_One_Edge_Satisfies);
+ -- Determine whether at least one edge of cycle Cycle of library graph G
+ -- satisfies predicate Predicate.
+
+ function Copy_Cycle_Path
+ (Cycle_Path : LGE_Lists.Doubly_Linked_List)
+ return LGE_Lists.Doubly_Linked_List;
+ pragma Inline (Copy_Cycle_Path);
+ -- Create a deep copy of list Cycle_Path
+
+ function Cycle_End_Vertices
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean) return LGV_Sets.Membership_Set;
+ pragma Inline (Cycle_End_Vertices);
+ -- Part of Tarjan's enumeration of the elementary circuits of a directed
+ -- graph algorithm. Collect the vertices that terminate a cycle starting
+ -- from vertex Vertex of library graph G in a set. This is usually the
+ -- vertex itself, unless the vertex is part of an Elaborate_Body pair,
+ -- or flag Elaborate_All_Active is set. In that case the complementary
+ -- vertex is also added to the set.
+
+ function Cycle_Kind_Of
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Cycle_Kind;
+ pragma Inline (Cycle_Kind_Of);
+ -- Determine the cycle kind of edge Edge of library graph G if the edge
+ -- participated in a circuit.
+
+ function Cycle_Kind_Precedence
+ (Kind : Library_Graph_Cycle_Kind;
+ Compared_To : Library_Graph_Cycle_Kind) return Precedence_Kind;
+ pragma Inline (Cycle_Kind_Precedence);
+ -- Determine the precedence of cycle kind Kind compared to cycle kind
+ -- Compared_To.
+
+ function Cycle_Path_Precedence
+ (G : Library_Graph;
+ Path : LGE_Lists.Doubly_Linked_List;
+ Compared_To : LGE_Lists.Doubly_Linked_List) return Precedence_Kind;
+ pragma Inline (Cycle_Path_Precedence);
+ -- Determine the precedence of cycle path Path of library graph G
+ -- compared to path Compared_To.
+
+ function Cycle_Precedence
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Compared_To : Library_Graph_Cycle_Id) return Precedence_Kind;
+ pragma Inline (Cycle_Precedence);
+ -- Determine the precedence of cycle Cycle of library graph G compared
+ -- to cycle Compared_To.
procedure Decrement_Library_Graph_Edge_Count
(G : Library_Graph;
@@ -983,7 +1137,7 @@ package body Bindo.Graphs is
procedure Delete_Body_Before_Spec_Edges
(G : Library_Graph;
- Edges : EL.Doubly_Linked_List);
+ Edges : LGE_Lists.Doubly_Linked_List);
pragma Inline (Delete_Body_Before_Spec_Edges);
-- Delete all edges in list Edges from library graph G, that link spec
-- and bodies, where the body acts as the predecessor and the spec as a
@@ -991,9 +1145,145 @@ package body Bindo.Graphs is
procedure Delete_Edge
(G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id);
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Delete_Edge);
- -- Delete edge LGE_Id from library graph G
+ -- Delete edge Edge from library graph G
+
+ function Edge_Precedence
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ Compared_To : Library_Graph_Edge_Id) return Precedence_Kind;
+ pragma Inline (Edge_Precedence);
+ -- Determine the precedence of edge Edge of library graph G compared to
+ -- edge Compared_To.
+
+ procedure Find_Cycles_From_Successor
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ End_Vertices : LGV_Sets.Membership_Set;
+ Deleted_Vertices : LGV_Sets.Membership_Set;
+ Most_Significant_Edge : Library_Graph_Edge_Id;
+ Invocation_Edge_Count : Natural;
+ Cycle_Path_Stack : LGE_Lists.Doubly_Linked_List;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List;
+ Cycle_Count : in out Natural;
+ Cycle_Limit : Natural;
+ Elaborate_All_Active : Boolean;
+ Has_Cycle : out Boolean;
+ Indent : Indentation_Level);
+ pragma Inline (Find_Cycles_From_Successor);
+ -- Part of Tarjan's enumeration of the elementary circuits of a directed
+ -- graph algorithm. Find all cycles from the successor indicated by edge
+ -- Edge of library graph G. If at least one cycle exists, set Has_Cycle
+ -- to True. The remaining parameters are as follows:
+ --
+ -- * End vertices is the set of vertices that terminate a potential
+ -- cycle.
+ --
+ -- * Deleted vertices is the set of vertices that have been expanded
+ -- during previous depth-first searches and should not be visited
+ -- for the rest of the algorithm.
+ --
+ -- * Most_Significant_Edge is the current highest-precedence edge on
+ -- the path of the potential cycle.
+ --
+ -- * Invocation_Edge_Count is the number of invocation edges on the
+ -- path of the potential cycle.
+ --
+ -- * Cycle_Path_Stack is the path of the potential cycle.
+ --
+ -- * Visited_Set is the set of vertices that have been visited during
+ -- the current depth-first search.
+ --
+ -- * Visited_Stack maintains the vertices of Visited_Set in a stack
+ -- for later unvisiting.
+ --
+ -- * Cycle_Count is the number of cycles discovered so far.
+ --
+ -- * Cycle_Limit is the upper bound of the number of cycles to be
+ -- discovered.
+ --
+ -- * Elaborate_All_Active should be set when the component currently
+ -- being examined for cycles contains an Elaborate_All edge.
+ --
+ -- * Indent in the desired indentation level for tracing.
+
+ procedure Find_Cycles_From_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ End_Vertices : LGV_Sets.Membership_Set;
+ Deleted_Vertices : LGV_Sets.Membership_Set;
+ Most_Significant_Edge : Library_Graph_Edge_Id;
+ Invocation_Edge_Count : Natural;
+ Cycle_Path_Stack : LGE_Lists.Doubly_Linked_List;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List;
+ Cycle_Count : in out Natural;
+ Cycle_Limit : Natural;
+ Elaborate_All_Active : Boolean;
+ Is_Start_Vertex : Boolean;
+ Has_Cycle : out Boolean;
+ Indent : Indentation_Level);
+ pragma Inline (Find_Cycles_From_Vertex);
+ -- Part of Tarjan's enumeration of the elementary circuits of a directed
+ -- graph algorithm. Find all cycles from vertex Vertex of library graph
+ -- G. If at least one cycle exists, set Has_Cycle to True. The remaining
+ -- parameters are as follows:
+ --
+ -- * End_Vertices is the set of vertices that terminate a potential
+ -- cycle.
+ --
+ -- * Deleted_Vertices is the set of vertices that have been expanded
+ -- during previous depth-first searches and should not be visited
+ -- for the rest of the algorithm.
+ --
+ -- * Most_Significant_Edge is the current highest-precedence edge on
+ -- the path of the potential cycle.
+ --
+ -- * Invocation_Edge_Count is the number of invocation edges on the
+ -- path of the potential cycle.
+ --
+ -- * Cycle_Path_Stack is the path of the potential cycle.
+ --
+ -- * Visited_Set is the set of vertices that have been visited during
+ -- the current depth-first search.
+ --
+ -- * Visited_Stack maintains the vertices of Visited_Set in a stack
+ -- for later unvisiting.
+ --
+ -- * Cycle_Count is the number of cycles discovered so far.
+ --
+ -- * Cycle_Limit is the upper bound of the number of cycles to be
+ -- discovered.
+ --
+ -- * Elaborate_All_Active should be set when the component currently
+ -- being examined for cycles contains an Elaborate_All edge.
+ --
+ -- * Indent in the desired indentation level for tracing.
+
+ procedure Find_Cycles_In_Component
+ (G : Library_Graph;
+ Comp : Component_Id;
+ Cycle_Count : in out Natural;
+ Cycle_Limit : Natural);
+ pragma Inline (Find_Cycles_In_Component);
+ -- Part of Tarjan's enumeration of the elementary circuits of a directed
+ -- graph algorithm. Find all cycles in component Comp of library graph
+ -- G. The remaining parameters are as follows:
+ --
+ -- * Cycle_Count is the number of cycles discovered so far.
+ --
+ -- * Cycle_Limit is the upper bound of the number of cycles to be
+ -- discovered.
+
+ function Find_First_Lower_Precedence_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Id;
+ pragma Inline (Find_First_Lower_Precedence_Cycle);
+ -- Inspect the list of cycles of library graph G and return the first
+ -- cycle whose precedence is lower than that of cycle Cycle. If there
+ -- is no such cycle, return No_Library_Graph_Cycle.
procedure Free is
new Ada.Unchecked_Deallocation
@@ -1005,27 +1295,56 @@ package body Bindo.Graphs is
pragma Inline (Get_Component_Attributes);
-- Obtain the attributes of component Comp of library graph G
+ function Get_LGC_Attributes
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Attributes;
+ pragma Inline (Get_LGC_Attributes);
+ -- Obtain the attributes of cycle Cycle of library graph G
+
function Get_LGE_Attributes
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id)
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id)
return Library_Graph_Edge_Attributes;
pragma Inline (Get_LGE_Attributes);
- -- Obtain the attributes of edge LGE_Id of library graph G
+ -- Obtain the attributes of edge Edge of library graph G
function Get_LGV_Attributes
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id)
return Library_Graph_Vertex_Attributes;
pragma Inline (Get_LGV_Attributes);
- -- Obtain the attributes of vertex LGE_Id of library graph G
+ -- Obtain the attributes of vertex Edge of library graph G
function Has_Elaborate_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Has_Elaborate_Body);
- -- Determine whether vertex LGV_Id of library graph G is subject to
+ -- Determine whether vertex Vertex of library graph G is subject to
-- pragma Elaborate_Body.
+ function Has_Elaborate_All_Edge
+ (G : Library_Graph;
+ Comp : Component_Id) return Boolean;
+ pragma Inline (Has_Elaborate_All_Edge);
+ -- Determine whether component Comp of library graph G contains an
+ -- Elaborate_All edge that links two vertices in the same component.
+
+ function Has_Elaborate_All_Edge
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Has_Elaborate_All_Edge);
+ -- Determine whether vertex Vertex of library graph G contains an
+ -- Elaborate_All edge to a successor where both the vertex and the
+ -- successor reside in the same component.
+
+ function Highest_Precedence_Edge
+ (G : Library_Graph;
+ Left : Library_Graph_Edge_Id;
+ Right : Library_Graph_Edge_Id) return Library_Graph_Edge_Id;
+ pragma Inline (Highest_Precedence_Edge);
+ -- Return the edge with highest precedence among edges Left and Right of
+ -- library graph G.
+
procedure Increment_Library_Graph_Edge_Count
(G : Library_Graph;
Kind : Library_Graph_Edge_Kind);
@@ -1034,37 +1353,154 @@ package body Bindo.Graphs is
procedure Increment_Pending_Predecessors
(G : Library_Graph;
- Comp : Component_Id);
+ Comp : Component_Id;
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Increment_Pending_Predecessors);
- -- Increment the number of pending precedessors component Comp of
- -- library graph G must wait on before it can be elaborated by one.
+ -- Increment the number of pending predecessors component Comp which was
+ -- reached via edge Edge of library graph G must wait on before it can
+ -- be elaborated by one.
procedure Increment_Pending_Predecessors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id);
+ Vertex : Library_Graph_Vertex_Id;
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Increment_Pending_Predecessors);
- -- Increment the number of pending precedessors vertex LGV_Id of library
- -- graph G must wait on before it can be elaborated by one.
+ -- Increment the number of pending predecessors vertex Vertex which was
+ -- reached via edge Edge of library graph G must wait on before it can
+ -- be elaborated by one.
procedure Initialize_Components (G : Library_Graph);
pragma Inline (Initialize_Components);
-- Initialize on the initial call or re-initialize on subsequent calls
-- all components of library graph G.
- function Is_Elaborable_Vertex
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Predecessors : Natural) return Boolean;
- pragma Inline (Is_Elaborable_Vertex);
- -- Determine whether vertex LGV_Id of library graph G can be elaborated
- -- given that it meets number of predecessors Predecessors.
+ function Is_Cycle_Initiating_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cycle_Initiating_Edge);
+ -- Determine whether edge Edge of library graph G starts a cycle
+
+ function Is_Cyclic_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cyclic_Edge);
+ -- Determine whether edge Edge of library graph G participates in a
+ -- cycle.
+
+ function Is_Cyclic_Elaborate_All_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cyclic_Elaborate_All_Edge);
+ -- Determine whether edge Edge of library graph G participates in a
+ -- cycle and has a predecessor that is subject to pragma Elaborate_All.
+
+ function Is_Cyclic_Elaborate_Body_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cyclic_Elaborate_Body_Edge);
+ -- Determine whether edge Edge of library graph G participates in a
+ -- cycle and has a successor that is either a spec subject to pragma
+ -- Elaborate_Body, or a body that completes such a spec.
+
+ function Is_Cyclic_Elaborate_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cyclic_Elaborate_Edge);
+ -- Determine whether edge Edge of library graph G participates in a
+ -- cycle and has a predecessor that is subject to pragma Elaborate.
+
+ function Is_Cyclic_Forced_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cyclic_Forced_Edge);
+ -- Determine whether edge Edge of library graph G participates in a
+ -- cycle and came from the forced-elaboration-order file.
- function Is_Existing_Predecessor_Successor_Relation
+ function Is_Cyclic_Invocation_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cyclic_Invocation_Edge);
+ -- Determine whether edge Edge of library graph G participates in a
+ -- cycle and came from the traversal of the invocation graph.
+
+ function Is_Cyclic_With_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Cyclic_With_Edge);
+ -- Determine whether edge Edge of library graph G participates in a
+ -- cycle and is the result of a with dependency between its successor
+ -- and predecessor.
+
+ function Is_Recorded_Edge
(G : Library_Graph;
Rel : Predecessor_Successor_Relation) return Boolean;
- pragma Inline (Is_Existing_Predecessor_Successor_Relation);
+ pragma Inline (Is_Recorded_Edge);
-- Determine whether a predecessor vertex and a successor vertex
- -- desctibed by relation Rel are already related in library graph G.
+ -- described by relation Rel are already linked in library graph G.
+
+ function Is_Static_Successor_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Static_Successor_Edge);
+ -- Determine whether the successor of invocation edge Edge represents a
+ -- unit that was compiled with the static model.
+
+ function Is_Vertex_With_Elaborate_Body
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Is_Vertex_With_Elaborate_Body);
+ -- Determine whether vertex Vertex of library graph G denotes a spec
+ -- subject to pragma Elaborate_Body or the completing body of such a
+ -- spec.
+
+ function Links_Vertices_In_Same_Component
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Links_Vertices_In_Same_Component);
+ -- Determine whether edge Edge of library graph G links a predecessor
+ -- and successor that reside in the same component.
+
+ function Maximum_Invocation_Edge_Count
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ Count : Natural) return Natural;
+ pragma Inline (Maximum_Invocation_Edge_Count);
+ -- Determine whether edge Edge of library graph G is an invocation edge,
+ -- and if it is return Count + 1, otherwise return Count.
+
+ procedure Normalize_Cycle_Path
+ (Cycle_Path : LGE_Lists.Doubly_Linked_List;
+ Most_Significant_Edge : Library_Graph_Edge_Id);
+ pragma Inline (Normalize_Cycle_Path);
+ -- Normalize cycle path Path by rotating it until its starting edge is
+ -- Sig_Edge.
+
+ procedure Order_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id);
+ pragma Inline (Order_Cycle);
+ -- Insert cycle Cycle in library graph G and sort it based on its
+ -- precedence relative to all recorded cycles.
+
+ function Path
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return LGE_Lists.Doubly_Linked_List;
+ pragma Inline (Path);
+ -- Obtain the path of edges which comprises cycle Cycle of library
+ -- graph G.
+
+ procedure Record_Cycle
+ (G : Library_Graph;
+ Most_Significant_Edge : Library_Graph_Edge_Id;
+ Invocation_Edge_Count : Natural;
+ Cycle_Path : LGE_Lists.Doubly_Linked_List;
+ Indent : Indentation_Level);
+ pragma Inline (Record_Cycle);
+ -- Normalize a cycle described by its path Cycle_Path and add it to
+ -- library graph G. Most_Significant_Edge denotes the edge with the
+ -- highest significance along the cycle path. Invocation_Edge_Count
+ -- is the number of invocation edges along the cycle path. Indent is
+ -- the desired indentation level for tracing.
procedure Set_Component_Attributes
(G : Library_Graph;
@@ -1080,27 +1516,85 @@ package body Bindo.Graphs is
pragma Inline (Set_Corresponding_Vertex);
-- Associate vertex Val of library graph G with unit U_Id
- procedure Set_Is_Existing_Predecessor_Successor_Relation
+ procedure Set_Is_Recorded_Edge
(G : Library_Graph;
Rel : Predecessor_Successor_Relation;
Val : Boolean := True);
- pragma Inline (Set_Is_Existing_Predecessor_Successor_Relation);
- -- Mark a a predecessor vertex and a successor vertex desctibed by
- -- relation Rel as already related depending on value Val.
+ pragma Inline (Set_Is_Recorded_Edge);
+ -- Mark a predecessor vertex and a successor vertex described by
+ -- relation Rel as already linked depending on value Val.
+
+ procedure Set_LGC_Attributes
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Val : Library_Graph_Cycle_Attributes);
+ pragma Inline (Set_LGC_Attributes);
+ -- Set the attributes of cycle Cycle of library graph G to value Val
procedure Set_LGE_Attributes
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id;
- Val : Library_Graph_Edge_Attributes);
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ Val : Library_Graph_Edge_Attributes);
pragma Inline (Set_LGE_Attributes);
- -- Set the attributes of edge LGE_Id of library graph G to value Val
+ -- Set the attributes of edge Edge of library graph G to value Val
procedure Set_LGV_Attributes
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Val : Library_Graph_Vertex_Attributes);
pragma Inline (Set_LGV_Attributes);
- -- Set the attributes of vertex LGV_Id of library graph G to value Val
+ -- Set the attributes of vertex Vertex of library graph G to value Val
+
+ procedure Trace_Component
+ (G : Library_Graph;
+ Comp : Component_Id;
+ Indent : Indentation_Level);
+ pragma Inline (Trace_Component);
+ -- Write the contents of component Comp of library graph G to standard
+ -- output. Indent is the desired indentation level for tracing.
+
+ procedure Trace_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Indent : Indentation_Level);
+ pragma Inline (Trace_Cycle);
+ -- Write the contents of cycle Cycle of library graph G to standard
+ -- output. Indent is the desired indentation level for tracing.
+
+ procedure Trace_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ Indent : Indentation_Level);
+ pragma Inline (Trace_Edge);
+ -- Write the contents of edge Edge of library graph G to standard
+ -- output. Indent is the desired indentation level for tracing.
+
+ procedure Trace_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Indent : Indentation_Level);
+ pragma Inline (Trace_Vertex);
+ -- Write the contents of vertex Vertex of library graph G to standard
+ -- output. Indent is the desired indentation level for tracing.
+
+ procedure Unvisit
+ (Vertex : Library_Graph_Vertex_Id;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List);
+ pragma Inline (Unvisit);
+ -- Part of Tarjan's enumeration of the elementary circuits of a directed
+ -- graph algorithm. Unwind the Visited_Stack by removing the top vertex
+ -- from set Visited_Set until vertex Vertex is reached, inclusive.
+
+ procedure Update_Pending_Predecessors
+ (Strong_Predecessors : in out Natural;
+ Weak_Predecessors : in out Natural;
+ Update_Weak : Boolean;
+ Value : Integer);
+ pragma Inline (Update_Pending_Predecessors);
+ -- Update the number of pending strong or weak predecessors denoted by
+ -- Strong_Predecessors and Weak_Predecessors respectively depending on
+ -- flag Update_Weak by adding value Value.
procedure Update_Pending_Predecessors_Of_Components (G : Library_Graph);
pragma Inline (Update_Pending_Predecessors_Of_Components);
@@ -1108,31 +1602,65 @@ package body Bindo.Graphs is
-- graph G must wait on before they can be elaborated.
procedure Update_Pending_Predecessors_Of_Components
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id);
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Update_Pending_Predecessors_Of_Components);
-- Update the number of pending predecessors the component of edge
-- LGE_Is's successor vertex of library graph G must wait on before
-- it can be elaborated.
+ function Vertex_Precedence
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind;
+ pragma Inline (Vertex_Precedence);
+ -- Determine the precedence of vertex Vertex of library graph G compared
+ -- to vertex Compared_To.
+
+ procedure Visit
+ (Vertex : Library_Graph_Vertex_Id;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List);
+ pragma Inline (Visit);
+ -- Part of Tarjan's enumeration of the elementary circuits of a directed
+ -- graph algorithm. Push vertex Vertex on the Visited_Stack and add it
+ -- to set Visited_Set.
+
+ --------------------
+ -- Activates_Task --
+ --------------------
+
+ function Activates_Task
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Kind (G, Edge) = Invocation_Edge
+ and then Get_LGE_Attributes (G, Edge).Activates_Task;
+ end Activates_Task;
+
-------------------------------
-- Add_Body_Before_Spec_Edge --
-------------------------------
procedure Add_Body_Before_Spec_Edge
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Edges : EL.Doubly_Linked_List)
+ Vertex : Library_Graph_Vertex_Id;
+ Edges : LGE_Lists.Doubly_Linked_List)
is
- LGE_Id : Library_Graph_Edge_Id;
+ Edge : Library_Graph_Edge_Id;
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
- pragma Assert (EL.Present (Edges));
+ pragma Assert (Present (Vertex));
+ pragma Assert (LGE_Lists.Present (Edges));
-- A vertex requires a special Body_Before_Spec edge to its
- -- Corresponging_Item when it either denotes a
+ -- Corresponding_Item when it either denotes a
--
-- * Body that completes a previous spec
--
@@ -1150,31 +1678,33 @@ package body Bindo.Graphs is
-- Assume that that no Body_Before_Spec is necessary
- LGE_Id := No_Library_Graph_Edge;
+ Edge := No_Library_Graph_Edge;
-- A body that completes a previous spec
- if Is_Body_With_Spec (G, LGV_Id) then
- LGE_Id :=
+ if Is_Body_With_Spec (G, Vertex) then
+ Edge :=
Add_Edge_With_Return
- (G => G,
- Pred => LGV_Id, -- body
- Succ => Corresponding_Item (G, LGV_Id), -- spec
- Kind => Body_Before_Spec_Edge);
+ (G => G,
+ Pred => Vertex,
+ Succ => Corresponding_Item (G, Vertex),
+ Kind => Body_Before_Spec_Edge,
+ Activates_Task => False);
-- A spec with a completing body
- elsif Is_Spec_With_Body (G, LGV_Id) then
- LGE_Id :=
+ elsif Is_Spec_With_Body (G, Vertex) then
+ Edge :=
Add_Edge_With_Return
- (G => G,
- Pred => Corresponding_Item (G, LGV_Id), -- body
- Succ => LGV_Id, -- spec
- Kind => Body_Before_Spec_Edge);
+ (G => G,
+ Pred => Corresponding_Item (G, Vertex),
+ Succ => Vertex,
+ Kind => Body_Before_Spec_Edge,
+ Activates_Task => False);
end if;
- if Present (LGE_Id) then
- EL.Append (Edges, LGE_Id);
+ if Present (Edge) then
+ LGE_Lists.Append (Edges, Edge);
end if;
end Add_Body_Before_Spec_Edge;
@@ -1184,24 +1714,23 @@ package body Bindo.Graphs is
procedure Add_Body_Before_Spec_Edges
(G : Library_Graph;
- Edges : EL.Doubly_Linked_List)
+ Edges : LGE_Lists.Doubly_Linked_List)
is
- Iter : Elaborable_Units_Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
- U_Id : Unit_Id;
+ Iter : Elaborable_Units_Iterator;
+ U_Id : Unit_Id;
begin
pragma Assert (Present (G));
- pragma Assert (EL.Present (Edges));
+ pragma Assert (LGE_Lists.Present (Edges));
Iter := Iterate_Elaborable_Units;
while Has_Next (Iter) loop
Next (Iter, U_Id);
- LGV_Id := Corresponding_Vertex (G, U_Id);
- pragma Assert (Present (LGV_Id));
-
- Add_Body_Before_Spec_Edge (G, LGV_Id, Edges);
+ Add_Body_Before_Spec_Edge
+ (G => G,
+ Vertex => Corresponding_Vertex (G, U_Id),
+ Edges => Edges);
end loop;
end Add_Body_Before_Spec_Edges;
@@ -1210,26 +1739,29 @@ package body Bindo.Graphs is
--------------
procedure Add_Edge
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- Succ : Library_Graph_Vertex_Id;
- Kind : Library_Graph_Edge_Kind)
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id;
+ Kind : Library_Graph_Edge_Kind;
+ Activates_Task : Boolean)
is
- LGE_Id : Library_Graph_Edge_Id;
- pragma Unreferenced (LGE_Id);
+ Edge : Library_Graph_Edge_Id;
+ pragma Unreferenced (Edge);
begin
pragma Assert (Present (G));
pragma Assert (Present (Pred));
pragma Assert (Present (Succ));
pragma Assert (Kind /= No_Edge);
+ pragma Assert (not Activates_Task or else Kind = Invocation_Edge);
- LGE_Id :=
+ Edge :=
Add_Edge_With_Return
- (G => G,
- Pred => Pred,
- Succ => Succ,
- Kind => Kind);
+ (G => G,
+ Pred => Pred,
+ Succ => Succ,
+ Kind => Kind,
+ Activates_Task => Activates_Task);
end Add_Edge;
--------------------------
@@ -1237,10 +1769,11 @@ package body Bindo.Graphs is
--------------------------
function Add_Edge_With_Return
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- Succ : Library_Graph_Vertex_Id;
- Kind : Library_Graph_Edge_Kind) return Library_Graph_Edge_Id
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id;
+ Kind : Library_Graph_Edge_Kind;
+ Activates_Task : Boolean) return Library_Graph_Edge_Id
is
pragma Assert (Present (G));
pragma Assert (Present (Pred));
@@ -1251,17 +1784,17 @@ package body Bindo.Graphs is
(Predecessor => Pred,
Successor => Succ);
- LGE_Id : Library_Graph_Edge_Id;
+ Edge : Library_Graph_Edge_Id;
begin
-- Nothing to do when the predecessor and successor are already
-- related by an edge.
- if Is_Existing_Predecessor_Successor_Relation (G, Rel) then
+ if Is_Recorded_Edge (G, Rel) then
return No_Library_Graph_Edge;
end if;
- LGE_Id := Sequence_Next_LGE_Id;
+ Edge := Sequence_Next_Edge;
-- Add the edge to the underlying graph. Note that the predecessor
-- is the source of the edge because it will later need to notify
@@ -1269,33 +1802,38 @@ package body Bindo.Graphs is
DG.Add_Edge
(G => G.Graph,
- E => LGE_Id,
+ E => Edge,
Source => Pred,
Destination => Succ);
-- Construct and save the attributes of the edge
Set_LGE_Attributes
- (G => G,
- LGE_Id => LGE_Id,
- Val => (Kind => Kind));
+ (G => G,
+ Edge => Edge,
+ Val =>
+ (Activates_Task => Activates_Task,
+ Kind => Kind));
-- Mark the predecessor and successor as related by the new edge.
-- This prevents all further attempts to link the same predecessor
-- and successor.
- Set_Is_Existing_Predecessor_Successor_Relation (G, Rel);
+ Set_Is_Recorded_Edge (G, Rel);
-- Update the number of pending predecessors the successor must wait
-- on before it is elaborated.
- Increment_Pending_Predecessors (G, Succ);
+ Increment_Pending_Predecessors
+ (G => G,
+ Vertex => Succ,
+ Edge => Edge);
-- Update the edge statistics
Increment_Library_Graph_Edge_Count (G, Kind);
- return LGE_Id;
+ return Edge;
end Add_Edge_With_Return;
----------------
@@ -1306,7 +1844,7 @@ package body Bindo.Graphs is
(G : Library_Graph;
U_Id : Unit_Id)
is
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
begin
pragma Assert (Present (G));
@@ -1318,55 +1856,217 @@ package body Bindo.Graphs is
return;
end if;
- LGV_Id := Sequence_Next_LGV_Id;
+ Vertex := Sequence_Next_Vertex;
-- Add the vertex to the underlying graph
- DG.Add_Vertex (G.Graph, LGV_Id);
+ DG.Add_Vertex (G.Graph, Vertex);
-- Construct and save the attributes of the vertex
Set_LGV_Attributes
(G => G,
- LGV_Id => LGV_Id,
- Val => (Corresponding_Item => No_Library_Graph_Vertex,
- In_Elaboration_Order => False,
- Pending_Predecessors => 0,
- Unit => U_Id));
+ Vertex => Vertex,
+ Val =>
+ (Corresponding_Item => No_Library_Graph_Vertex,
+ In_Elaboration_Order => False,
+ Pending_Strong_Predecessors => 0,
+ Pending_Weak_Predecessors => 0,
+ Unit => U_Id));
-- Associate the unit with its corresponding vertex
- Set_Corresponding_Vertex (G, U_Id, LGV_Id);
+ Set_Corresponding_Vertex (G, U_Id, Vertex);
end Add_Vertex;
+ ---------------------------------
+ -- At_Least_One_Edge_Satisfies --
+ ---------------------------------
+
+ function At_Least_One_Edge_Satisfies
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Predicate : LGE_Predicate_Ptr) return Boolean
+ is
+ Edge : Library_Graph_Edge_Id;
+ Iter : Edges_Of_Cycle_Iterator;
+ Satisfied : Boolean;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+ pragma Assert (Predicate /= null);
+
+ -- Assume that the predicate cannot be satisfied
+
+ Satisfied := False;
+
+ -- IMPORTANT:
+ --
+ -- * The iteration must run to completion in order to unlock the
+ -- edges of the cycle.
+
+ Iter := Iterate_Edges_Of_Cycle (G, Cycle);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ Satisfied := Satisfied or else Predicate.all (G, Edge);
+ end loop;
+
+ return Satisfied;
+ end At_Least_One_Edge_Satisfies;
+
+ --------------------------
+ -- Complementary_Vertex --
+ --------------------------
+
+ function Complementary_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Force_Complement : Boolean) return Library_Graph_Vertex_Id
+ is
+ Complement : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ -- Assume that there is no complementary vertex
+
+ Complement := No_Library_Graph_Vertex;
+
+ -- The caller requests the complement explicitly
+
+ if Force_Complement then
+ Complement := Corresponding_Item (G, Vertex);
+
+ -- The vertex is a completing body of a spec subject to pragma
+ -- Elaborate_Body. The complementary vertex is the spec.
+
+ elsif Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then
+ Complement := Proper_Spec (G, Vertex);
+
+ -- The vertex is a spec subject to pragma Elaborate_Body. The
+ -- complementary vertex is the body.
+
+ elsif Is_Spec_With_Elaborate_Body (G, Vertex) then
+ Complement := Proper_Body (G, Vertex);
+ end if;
+
+ return Complement;
+ end Complementary_Vertex;
+
---------------
-- Component --
---------------
function Component
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Component_Id
+ Vertex : Library_Graph_Vertex_Id) return Component_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- return DG.Component (G.Graph, LGV_Id);
+ return DG.Component (G.Graph, Vertex);
end Component;
+ ---------------------------------
+ -- Contains_Elaborate_All_Edge --
+ ---------------------------------
+
+ function Contains_Elaborate_All_Edge
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return
+ At_Least_One_Edge_Satisfies
+ (G => G,
+ Cycle => Cycle,
+ Predicate => Is_Elaborate_All_Edge'Access);
+ end Contains_Elaborate_All_Edge;
+
+ ------------------------------------
+ -- Contains_Static_Successor_Edge --
+ ------------------------------------
+
+ function Contains_Static_Successor_Edge
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return
+ At_Least_One_Edge_Satisfies
+ (G => G,
+ Cycle => Cycle,
+ Predicate => Is_Static_Successor_Edge'Access);
+ end Contains_Static_Successor_Edge;
+
+ ------------------------------
+ -- Contains_Task_Activation --
+ ------------------------------
+
+ function Contains_Task_Activation
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return
+ At_Least_One_Edge_Satisfies
+ (G => G,
+ Cycle => Cycle,
+ Predicate => Activates_Task'Access);
+ end Contains_Task_Activation;
+
+ ---------------------
+ -- Copy_Cycle_Path --
+ ---------------------
+
+ function Copy_Cycle_Path
+ (Cycle_Path : LGE_Lists.Doubly_Linked_List)
+ return LGE_Lists.Doubly_Linked_List
+ is
+ Edge : Library_Graph_Edge_Id;
+ Iter : LGE_Lists.Iterator;
+ Path : LGE_Lists.Doubly_Linked_List;
+
+ begin
+ pragma Assert (LGE_Lists.Present (Cycle_Path));
+
+ Path := LGE_Lists.Create;
+ Iter := LGE_Lists.Iterate (Cycle_Path);
+ while LGE_Lists.Has_Next (Iter) loop
+ LGE_Lists.Next (Iter, Edge);
+
+ LGE_Lists.Append (Path, Edge);
+ end loop;
+
+ return Path;
+ end Copy_Cycle_Path;
+
------------------------
-- Corresponding_Item --
------------------------
function Corresponding_Item
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
+ Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- return Get_LGV_Attributes (G, LGV_Id).Corresponding_Item;
+ return Get_LGV_Attributes (G, Vertex).Corresponding_Item;
end Corresponding_Item;
--------------------------
@@ -1381,7 +2081,7 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (U_Id));
- return UV.Get (G.Unit_To_Vertex, U_Id);
+ return Unit_Tables.Get (G.Unit_To_Vertex, U_Id);
end Corresponding_Vertex;
------------
@@ -1395,19 +2095,264 @@ package body Bindo.Graphs is
G : constant Library_Graph := new Library_Graph_Attributes;
begin
- G.Component_Attributes := CA.Create (Initial_Vertices);
- G.Edge_Attributes := EA.Create (Initial_Edges);
+ G.Component_Attributes := Component_Tables.Create (Initial_Vertices);
+ G.Cycle_Attributes := LGC_Tables.Create (Initial_Vertices);
+ G.Cycles := LGC_Lists.Create;
+ G.Edge_Attributes := LGE_Tables.Create (Initial_Edges);
G.Graph :=
DG.Create
(Initial_Vertices => Initial_Vertices,
Initial_Edges => Initial_Edges);
- G.Relations := PS.Create (Initial_Edges);
- G.Unit_To_Vertex := UV.Create (Initial_Vertices);
- G.Vertex_Attributes := VA.Create (Initial_Vertices);
+ G.Recorded_Edges := RE_Sets.Create (Initial_Edges);
+ G.Unit_To_Vertex := Unit_Tables.Create (Initial_Vertices);
+ G.Vertex_Attributes := LGV_Tables.Create (Initial_Vertices);
return G;
end Create;
+ ------------------------
+ -- Cycle_End_Vertices --
+ ------------------------
+
+ function Cycle_End_Vertices
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Elaborate_All_Active : Boolean) return LGV_Sets.Membership_Set
+ is
+ Complement : Library_Graph_Vertex_Id;
+ End_Vertices : LGV_Sets.Membership_Set := LGV_Sets.Nil;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ End_Vertices := LGV_Sets.Create (2);
+
+ -- The input vertex always terminates a cycle path
+
+ LGV_Sets.Insert (End_Vertices, Vertex);
+
+ -- Add the complementary vertex to the set of cycle terminating
+ -- vertices when either Elaborate_All is in effect, or the input
+ -- vertex is part of an Elaborat_Body pair.
+
+ if Elaborate_All_Active
+ or else Is_Vertex_With_Elaborate_Body (G, Vertex)
+ then
+ Complement :=
+ Complementary_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Force_Complement => Elaborate_All_Active);
+
+ if Present (Complement) then
+ LGV_Sets.Insert (End_Vertices, Complement);
+ end if;
+ end if;
+
+ return End_Vertices;
+ end Cycle_End_Vertices;
+
+ -------------------
+ -- Cycle_Kind_Of --
+ -------------------
+
+ function Cycle_Kind_Of
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Cycle_Kind
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ begin
+ if Is_Cyclic_Elaborate_All_Edge (G, Edge) then
+ return Elaborate_All_Cycle;
+
+ elsif Is_Cyclic_Elaborate_Body_Edge (G, Edge) then
+ return Elaborate_Body_Cycle;
+
+ elsif Is_Cyclic_Elaborate_Edge (G, Edge) then
+ return Elaborate_Cycle;
+
+ elsif Is_Cyclic_Forced_Edge (G, Edge) then
+ return Forced_Cycle;
+
+ elsif Is_Cyclic_Invocation_Edge (G, Edge) then
+ return Invocation_Cycle;
+
+ else
+ return No_Cycle_Kind;
+ end if;
+ end Cycle_Kind_Of;
+
+ ---------------------------
+ -- Cycle_Kind_Precedence --
+ ---------------------------
+
+ function Cycle_Kind_Precedence
+ (Kind : Library_Graph_Cycle_Kind;
+ Compared_To : Library_Graph_Cycle_Kind) return Precedence_Kind
+ is
+ Comp_Pos : constant Integer :=
+ Library_Graph_Cycle_Kind'Pos (Compared_To);
+ Kind_Pos : constant Integer := Library_Graph_Cycle_Kind'Pos (Kind);
+
+ begin
+ -- A lower ordinal indicates a higher precedence
+
+ if Kind_Pos < Comp_Pos then
+ return Higher_Precedence;
+
+ elsif Kind_Pos > Comp_Pos then
+ return Lower_Precedence;
+
+ else
+ return Equal_Precedence;
+ end if;
+ end Cycle_Kind_Precedence;
+
+ ---------------------------
+ -- Cycle_Path_Precedence --
+ ---------------------------
+
+ function Cycle_Path_Precedence
+ (G : Library_Graph;
+ Path : LGE_Lists.Doubly_Linked_List;
+ Compared_To : LGE_Lists.Doubly_Linked_List) return Precedence_Kind
+ is
+ procedure Next_Available
+ (Iter : in out LGE_Lists.Iterator;
+ Edge : out Library_Graph_Edge_Id);
+ pragma Inline (Next_Available);
+ -- Obtain the next edge available through iterator Iter, or return
+ -- No_Library_Graph_Edge if the iterator has been exhausted.
+
+ --------------------
+ -- Next_Available --
+ --------------------
+
+ procedure Next_Available
+ (Iter : in out LGE_Lists.Iterator;
+ Edge : out Library_Graph_Edge_Id)
+ is
+ begin
+ -- Assume that the iterator has been exhausted
+
+ Edge := No_Library_Graph_Edge;
+
+ if LGE_Lists.Has_Next (Iter) then
+ LGE_Lists.Next (Iter, Edge);
+ end if;
+ end Next_Available;
+
+ -- Local variables
+
+ Comp_Edge : Library_Graph_Edge_Id;
+ Comp_Iter : LGE_Lists.Iterator;
+ Path_Edge : Library_Graph_Edge_Id;
+ Path_Iter : LGE_Lists.Iterator;
+ Prec : Precedence_Kind;
+
+ -- Start of processing for Cycle_Path_Precedence
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (LGE_Lists.Present (Path));
+ pragma Assert (LGE_Lists.Present (Compared_To));
+
+ -- Assume that the paths have equal precedence
+
+ Prec := Equal_Precedence;
+
+ Comp_Iter := LGE_Lists.Iterate (Compared_To);
+ Path_Iter := LGE_Lists.Iterate (Path);
+
+ Next_Available (Comp_Iter, Comp_Edge);
+ Next_Available (Path_Iter, Path_Edge);
+
+ -- IMPORTANT:
+ --
+ -- * The iteration must run to completion in order to unlock the
+ -- edges of both paths.
+
+ while Present (Comp_Edge) or else Present (Path_Edge) loop
+ if Prec = Equal_Precedence
+ and then Present (Comp_Edge)
+ and then Present (Path_Edge)
+ then
+ Prec :=
+ Edge_Precedence
+ (G => G,
+ Edge => Path_Edge,
+ Compared_To => Comp_Edge);
+ end if;
+
+ Next_Available (Comp_Iter, Comp_Edge);
+ Next_Available (Path_Iter, Path_Edge);
+ end loop;
+
+ return Prec;
+ end Cycle_Path_Precedence;
+
+ ----------------------
+ -- Cycle_Precedence --
+ ----------------------
+
+ function Cycle_Precedence
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Compared_To : Library_Graph_Cycle_Id) return Precedence_Kind
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+ pragma Assert (Present (Compared_To));
+
+ Comp_Invs : constant Natural :=
+ Invocation_Edge_Count (G, Compared_To);
+ Comp_Len : constant Natural := Length (G, Compared_To);
+ Cycle_Invs : constant Natural := Invocation_Edge_Count (G, Cycle);
+ Cycle_Len : constant Natural := Length (G, Cycle);
+ Kind_Prec : constant Precedence_Kind :=
+ Cycle_Kind_Precedence
+ (Kind => Kind (G, Cycle),
+ Compared_To => Kind (G, Compared_To));
+
+ begin
+ -- Prefer a cycle with higher precedence based on its kind
+
+ if Kind_Prec = Higher_Precedence
+ or else
+ Kind_Prec = Lower_Precedence
+ then
+ return Kind_Prec;
+
+ -- Prefer a shorter cycle
+
+ elsif Cycle_Len < Comp_Len then
+ return Higher_Precedence;
+
+ elsif Cycle_Len > Comp_Len then
+ return Lower_Precedence;
+
+ -- Prefer a cycle wih fewer invocation edges
+
+ elsif Cycle_Invs < Comp_Invs then
+ return Higher_Precedence;
+
+ elsif Cycle_Invs > Comp_Invs then
+ return Lower_Precedence;
+
+ -- Prefer a cycle with a higher path precedence
+
+ else
+ return
+ Cycle_Path_Precedence
+ (G => G,
+ Path => Path (G, Cycle),
+ Compared_To => Path (G, Compared_To));
+ end if;
+ end Cycle_Precedence;
+
----------------------------------------
-- Decrement_Library_Graph_Edge_Count --
----------------------------------------
@@ -1430,7 +2375,8 @@ package body Bindo.Graphs is
procedure Decrement_Pending_Predecessors
(G : Library_Graph;
- Comp : Component_Id)
+ Comp : Component_Id;
+ Edge : Library_Graph_Edge_Id)
is
Attrs : Component_Attributes;
@@ -1439,7 +2385,13 @@ package body Bindo.Graphs is
pragma Assert (Present (Comp));
Attrs := Get_Component_Attributes (G, Comp);
- Attrs.Pending_Predecessors := Attrs.Pending_Predecessors - 1;
+
+ Update_Pending_Predecessors
+ (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
+ Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
+ Update_Weak => Is_Invocation_Edge (G, Edge),
+ Value => -1);
+
Set_Component_Attributes (G, Comp, Attrs);
end Decrement_Pending_Predecessors;
@@ -1449,17 +2401,24 @@ package body Bindo.Graphs is
procedure Decrement_Pending_Predecessors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id;
+ Edge : Library_Graph_Edge_Id)
is
Attrs : Library_Graph_Vertex_Attributes;
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
+
+ Attrs := Get_LGV_Attributes (G, Vertex);
- Attrs := Get_LGV_Attributes (G, LGV_Id);
- Attrs.Pending_Predecessors := Attrs.Pending_Predecessors - 1;
- Set_LGV_Attributes (G, LGV_Id, Attrs);
+ Update_Pending_Predecessors
+ (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
+ Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
+ Update_Weak => Is_Invocation_Edge (G, Edge),
+ Value => -1);
+
+ Set_LGV_Attributes (G, Vertex, Attrs);
end Decrement_Pending_Predecessors;
-----------------------------------
@@ -1468,22 +2427,21 @@ package body Bindo.Graphs is
procedure Delete_Body_Before_Spec_Edges
(G : Library_Graph;
- Edges : EL.Doubly_Linked_List)
+ Edges : LGE_Lists.Doubly_Linked_List)
is
- Iter : EL.Iterator;
- LGE_Id : Library_Graph_Edge_Id;
+ Edge : Library_Graph_Edge_Id;
+ Iter : LGE_Lists.Iterator;
begin
pragma Assert (Present (G));
- pragma Assert (EL.Present (Edges));
+ pragma Assert (LGE_Lists.Present (Edges));
- Iter := EL.Iterate (Edges);
- while EL.Has_Next (Iter) loop
- EL.Next (Iter, LGE_Id);
- pragma Assert (Present (LGE_Id));
- pragma Assert (Kind (G, LGE_Id) = Body_Before_Spec_Edge);
+ Iter := LGE_Lists.Iterate (Edges);
+ while LGE_Lists.Has_Next (Iter) loop
+ LGE_Lists.Next (Iter, Edge);
+ pragma Assert (Kind (G, Edge) = Body_Before_Spec_Edge);
- Delete_Edge (G, LGE_Id);
+ Delete_Edge (G, Edge);
end loop;
end Delete_Body_Before_Spec_Edges;
@@ -1492,44 +2450,43 @@ package body Bindo.Graphs is
-----------------
procedure Delete_Edge
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id)
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id)
is
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
-
- Pred : constant Library_Graph_Vertex_Id := Predecessor (G, LGE_Id);
- Succ : constant Library_Graph_Vertex_Id := Successor (G, LGE_Id);
-
- pragma Assert (Present (Pred));
- pragma Assert (Present (Succ));
+ pragma Assert (Present (Edge));
- Rel : constant Predecessor_Successor_Relation :=
- (Predecessor => Pred,
- Successor => Succ);
+ Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
+ Rel : constant Predecessor_Successor_Relation :=
+ (Predecessor => Pred,
+ Successor => Succ);
begin
-- Update the edge statistics
- Decrement_Library_Graph_Edge_Count (G, Kind (G, LGE_Id));
+ Decrement_Library_Graph_Edge_Count (G, Kind (G, Edge));
-- Update the number of pending predecessors the successor must wait
-- on before it is elaborated.
- Decrement_Pending_Predecessors (G, Succ);
+ Decrement_Pending_Predecessors
+ (G => G,
+ Vertex => Succ,
+ Edge => Edge);
-- Delete the link between the predecessor and successor. This allows
-- for further attempts to link the same predecessor and successor.
- PS.Delete (G.Relations, Rel);
+ RE_Sets.Delete (G.Recorded_Edges, Rel);
-- Delete the attributes of the edge
- EA.Delete (G.Edge_Attributes, LGE_Id);
+ LGE_Tables.Delete (G.Edge_Attributes, Edge);
-- Delete the edge from the underlying graph
- DG.Delete_Edge (G.Graph, LGE_Id);
+ DG.Delete_Edge (G.Graph, Edge);
end Delete_Edge;
-------------
@@ -1540,12 +2497,14 @@ package body Bindo.Graphs is
begin
pragma Assert (Present (G));
- CA.Destroy (G.Component_Attributes);
- EA.Destroy (G.Edge_Attributes);
- DG.Destroy (G.Graph);
- PS.Destroy (G.Relations);
- UV.Destroy (G.Unit_To_Vertex);
- VA.Destroy (G.Vertex_Attributes);
+ Component_Tables.Destroy (G.Component_Attributes);
+ LGC_Tables.Destroy (G.Cycle_Attributes);
+ LGC_Lists.Destroy (G.Cycles);
+ LGE_Tables.Destroy (G.Edge_Attributes);
+ DG.Destroy (G.Graph);
+ RE_Sets.Destroy (G.Recorded_Edges);
+ Unit_Tables.Destroy (G.Unit_To_Vertex);
+ LGV_Tables.Destroy (G.Vertex_Attributes);
Free (G);
end Destroy;
@@ -1562,17 +2521,16 @@ package body Bindo.Graphs is
null;
end Destroy_Component_Attributes;
- --------------------------------
- -- Destroy_Library_Graph_Edge --
- --------------------------------
+ --------------------------------------------
+ -- Destroy_Library_Graph_Cycle_Attributes --
+ --------------------------------------------
- procedure Destroy_Library_Graph_Edge
- (LGE_Id : in out Library_Graph_Edge_Id)
+ procedure Destroy_Library_Graph_Cycle_Attributes
+ (Attrs : in out Library_Graph_Cycle_Attributes)
is
- pragma Unreferenced (LGE_Id);
begin
- null;
- end Destroy_Library_Graph_Edge;
+ LGE_Lists.Destroy (Attrs.Path);
+ end Destroy_Library_Graph_Cycle_Attributes;
-------------------------------------------
-- Destroy_Library_Graph_Edge_Attributes --
@@ -1586,18 +2544,6 @@ package body Bindo.Graphs is
null;
end Destroy_Library_Graph_Edge_Attributes;
- ----------------------------------
- -- Destroy_Library_Graph_Vertex --
- ----------------------------------
-
- procedure Destroy_Library_Graph_Vertex
- (LGV_Id : in out Library_Graph_Vertex_Id)
- is
- pragma Unreferenced (LGV_Id);
- begin
- null;
- end Destroy_Library_Graph_Vertex;
-
---------------------------------------------
-- Destroy_Library_Graph_Vertex_Attributes --
---------------------------------------------
@@ -1611,15 +2557,88 @@ package body Bindo.Graphs is
end Destroy_Library_Graph_Vertex_Attributes;
---------------------
+ -- Edge_Precedence --
+ ---------------------
+
+ function Edge_Precedence
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ Compared_To : Library_Graph_Edge_Id) return Precedence_Kind
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+ pragma Assert (Present (Compared_To));
+
+ Comp_Succ : constant Library_Graph_Vertex_Id :=
+ Successor (G, Compared_To);
+ Edge_Succ : constant Library_Graph_Vertex_Id :=
+ Successor (G, Edge);
+ Kind_Prec : constant Precedence_Kind :=
+ Cycle_Kind_Precedence
+ (Kind => Cycle_Kind_Of (G, Edge),
+ Compared_To => Cycle_Kind_Of (G, Compared_To));
+ Succ_Prec : constant Precedence_Kind :=
+ Vertex_Precedence
+ (G => G,
+ Vertex => Edge_Succ,
+ Compared_To => Comp_Succ);
+
+ begin
+ -- Prefer an edge with a higher cycle kind precedence
+
+ if Kind_Prec = Higher_Precedence
+ or else
+ Kind_Prec = Lower_Precedence
+ then
+ return Kind_Prec;
+
+ -- Prefer an edge whose successor has a higher precedence
+
+ elsif Comp_Succ /= Edge_Succ
+ and then (Succ_Prec = Higher_Precedence
+ or else
+ Succ_Prec = Lower_Precedence)
+ then
+ return Succ_Prec;
+
+ -- Prefer an edge whose predecessor has a higher precedence
+
+ else
+ return
+ Vertex_Precedence
+ (G => G,
+ Vertex => Predecessor (G, Edge),
+ Compared_To => Predecessor (G, Compared_To));
+ end if;
+ end Edge_Precedence;
+
+ ---------------
+ -- File_Name --
+ ---------------
+
+ function File_Name
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return File_Name_Type
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return File_Name (Unit (G, Vertex));
+ end File_Name;
+
+ ---------------------
-- Find_Components --
---------------------
procedure Find_Components (G : Library_Graph) is
- Edges : EL.Doubly_Linked_List;
+ Edges : LGE_Lists.Doubly_Linked_List;
begin
pragma Assert (Present (G));
+ Start_Phase (Component_Discovery);
+
-- Initialize or reinitialize the components of the graph
Initialize_Components (G);
@@ -1629,7 +2648,7 @@ package body Bindo.Graphs is
-- edges eliminates the need to create yet another graph, where both
-- spec and body are collapsed into a single vertex.
- Edges := EL.Create;
+ Edges := LGE_Lists.Create;
Add_Body_Before_Spec_Edges (G, Edges);
DG.Find_Components (G.Graph);
@@ -1638,14 +2657,535 @@ package body Bindo.Graphs is
-- successor spec because they cause unresolvable circularities.
Delete_Body_Before_Spec_Edges (G, Edges);
- EL.Destroy (Edges);
+ LGE_Lists.Destroy (Edges);
-- Update the number of predecessors various components must wait on
-- before they can be elaborated.
Update_Pending_Predecessors_Of_Components (G);
+ End_Phase (Component_Discovery);
end Find_Components;
+ -----------------
+ -- Find_Cycles --
+ -----------------
+
+ procedure Find_Cycles (G : Library_Graph) is
+ All_Cycle_Limit : constant Natural := 64;
+ -- The performance of Tarjan's algorithm may degrate to exponential
+ -- when pragma Elaborate_All is in effect, or some vertex is part of
+ -- an Elaborate_Body pair. In this case the algorithm discovers all
+ -- combinations of edges that close a circuit starting and ending on
+ -- some start vertex while going through different vertices. Use a
+ -- limit on the total number of cycles within a component to guard
+ -- against such degradation.
+
+ Comp : Component_Id;
+ Cycle_Count : Natural;
+ Iter : Component_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+
+ Start_Phase (Cycle_Discovery);
+
+ -- The cycles of graph G are discovered using Tarjan's enumeration
+ -- of the elementary circuits of a directed-graph algorithm. Do not
+ -- modify this code unless you intimately understand the algorithm.
+ --
+ -- The logic of the algorithm is split among the following routines:
+ --
+ -- Cycle_End_Vertices
+ -- Find_Cycles_From_Successor
+ -- Find_Cycles_From_Vertex
+ -- Find_Cycles_In_Component
+ -- Unvisit
+ -- Visit
+ --
+ -- The original algorithm has been significantly modified in order to
+ --
+ -- * Accommodate the semantics of Elaborate_All and Elaborate_Body.
+ --
+ -- * Capture cycle paths as edges rather than vertices.
+ --
+ -- * Take advantage of graph components.
+
+ -- Assume that the graph does not contain a cycle
+
+ Cycle_Count := 0;
+
+ -- Run the modified version of the algorithm on each component of the
+ -- graph.
+
+ Iter := Iterate_Components (G);
+ while Has_Next (Iter) loop
+ Next (Iter, Comp);
+
+ Find_Cycles_In_Component
+ (G => G,
+ Comp => Comp,
+ Cycle_Count => Cycle_Count,
+ Cycle_Limit => All_Cycle_Limit);
+ end loop;
+
+ End_Phase (Cycle_Discovery);
+ end Find_Cycles;
+
+ --------------------------------
+ -- Find_Cycles_From_Successor --
+ --------------------------------
+
+ procedure Find_Cycles_From_Successor
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ End_Vertices : LGV_Sets.Membership_Set;
+ Deleted_Vertices : LGV_Sets.Membership_Set;
+ Most_Significant_Edge : Library_Graph_Edge_Id;
+ Invocation_Edge_Count : Natural;
+ Cycle_Path_Stack : LGE_Lists.Doubly_Linked_List;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List;
+ Cycle_Count : in out Natural;
+ Cycle_Limit : Natural;
+ Elaborate_All_Active : Boolean;
+ Has_Cycle : out Boolean;
+ Indent : Indentation_Level)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+ pragma Assert (LGV_Sets.Present (End_Vertices));
+ pragma Assert (LGV_Sets.Present (Deleted_Vertices));
+ pragma Assert (LGE_Lists.Present (Cycle_Path_Stack));
+ pragma Assert (LGV_Sets.Present (Visited_Set));
+ pragma Assert (LGV_Lists.Present (Visited_Stack));
+
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
+ Succ_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
+
+ begin
+ -- Assume that the successor reached via the edge does not result in
+ -- a cycle.
+
+ Has_Cycle := False;
+
+ -- Nothing to do when the edge connects two vertices residing in two
+ -- different components.
+
+ if not Is_Cyclic_Edge (G, Edge) then
+ return;
+ end if;
+
+ Trace_Edge (G, Edge, Indent);
+
+ -- The modified version does not place vertices on the "point stack",
+ -- but instead collects the edges comprising the cycle. Prepare the
+ -- edge for backtracking.
+
+ LGE_Lists.Prepend (Cycle_Path_Stack, Edge);
+
+ Find_Cycles_From_Vertex
+ (G => G,
+ Vertex => Succ,
+ End_Vertices => End_Vertices,
+ Deleted_Vertices => Deleted_Vertices,
+ Most_Significant_Edge => Most_Significant_Edge,
+ Invocation_Edge_Count => Invocation_Edge_Count,
+ Cycle_Path_Stack => Cycle_Path_Stack,
+ Visited_Set => Visited_Set,
+ Visited_Stack => Visited_Stack,
+ Cycle_Count => Cycle_Count,
+ Cycle_Limit => Cycle_Limit,
+ Elaborate_All_Active => Elaborate_All_Active,
+ Is_Start_Vertex => False,
+ Has_Cycle => Has_Cycle,
+ Indent => Succ_Indent);
+
+ -- The modified version does not place vertices on the "point stack",
+ -- but instead collects the edges comprising the cycle. Backtrack the
+ -- edge.
+
+ LGE_Lists.Delete_First (Cycle_Path_Stack);
+ end Find_Cycles_From_Successor;
+
+ -----------------------------
+ -- Find_Cycles_From_Vertex --
+ -----------------------------
+
+ procedure Find_Cycles_From_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ End_Vertices : LGV_Sets.Membership_Set;
+ Deleted_Vertices : LGV_Sets.Membership_Set;
+ Most_Significant_Edge : Library_Graph_Edge_Id;
+ Invocation_Edge_Count : Natural;
+ Cycle_Path_Stack : LGE_Lists.Doubly_Linked_List;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List;
+ Cycle_Count : in out Natural;
+ Cycle_Limit : Natural;
+ Elaborate_All_Active : Boolean;
+ Is_Start_Vertex : Boolean;
+ Has_Cycle : out Boolean;
+ Indent : Indentation_Level)
+ is
+ Edge_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
+
+ Complement : Library_Graph_Vertex_Id;
+ Edge : Library_Graph_Edge_Id;
+ Iter : Edges_To_Successors_Iterator;
+
+ Complement_Has_Cycle : Boolean;
+ -- This flag is set when either Elaborate_All is in effect or the
+ -- current vertex is part of an Elaborate_Body pair, and visiting
+ -- the "complementary" vertex resulted in a cycle.
+
+ Successor_Has_Cycle : Boolean;
+ -- This flag is set when visiting at least one successor of the
+ -- current vertex resulted in a cycle.
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+ pragma Assert (LGV_Sets.Present (End_Vertices));
+ pragma Assert (LGV_Sets.Present (Deleted_Vertices));
+ pragma Assert (LGE_Lists.Present (Cycle_Path_Stack));
+ pragma Assert (LGV_Sets.Present (Visited_Set));
+ pragma Assert (LGV_Lists.Present (Visited_Stack));
+
+ -- Assume that the vertex does not close a circuit
+
+ Has_Cycle := False;
+
+ -- Nothing to do when the limit on the number of saved cycles has
+ -- been reached. This protects against a combinatorial explosion
+ -- in components with Elaborate_All cycles.
+
+ if Cycle_Count >= Cycle_Limit then
+ return;
+
+ -- The vertex closes the circuit, thus resulting in a cycle. Save
+ -- the cycle for later diagnostics. The initial invocation of the
+ -- routine always ignores the starting vertex, to prevent a spurious
+ -- self-cycle.
+
+ elsif not Is_Start_Vertex
+ and then LGV_Sets.Contains (End_Vertices, Vertex)
+ then
+ Trace_Vertex (G, Vertex, Indent);
+
+ Record_Cycle
+ (G => G,
+ Most_Significant_Edge => Most_Significant_Edge,
+ Invocation_Edge_Count => Invocation_Edge_Count,
+ Cycle_Path => Cycle_Path_Stack,
+ Indent => Indent);
+
+ Has_Cycle := True;
+ Cycle_Count := Cycle_Count + 1;
+ return;
+
+ -- Nothing to do when the vertex has already been deleted. This
+ -- indicates that all available cycles involving the vertex have
+ -- been discovered, and the vertex cannot contribute further to
+ -- the depth-first search.
+
+ elsif LGV_Sets.Contains (Deleted_Vertices, Vertex) then
+ return;
+
+ -- Nothing to do when the vertex has already been visited. This
+ -- indicates that the depth-first search initiated from some start
+ -- vertex already encountered this vertex, and the visited stack has
+ -- not been unrolled yet.
+
+ elsif LGV_Sets.Contains (Visited_Set, Vertex) then
+ return;
+ end if;
+
+ Trace_Vertex (G, Vertex, Indent);
+
+ -- Mark the vertex as visited
+
+ Visit
+ (Vertex => Vertex,
+ Visited_Set => Visited_Set,
+ Visited_Stack => Visited_Stack);
+
+ -- Extend the depth-first search via all the edges to successors
+
+ Iter := Iterate_Edges_To_Successors (G, Vertex);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ Find_Cycles_From_Successor
+ (G => G,
+ Edge => Edge,
+ End_Vertices => End_Vertices,
+ Deleted_Vertices => Deleted_Vertices,
+
+ -- The edge may be more important than the most important edge
+ -- up to this point, thus "upgrading" the nature of the cycle,
+ -- and shifting its point of normalization.
+
+ Most_Significant_Edge =>
+ Highest_Precedence_Edge
+ (G => G,
+ Left => Edge,
+ Right => Most_Significant_Edge),
+
+ -- The edge may be an invocation edge, in which case the count
+ -- of invocation edges increases by one.
+
+ Invocation_Edge_Count =>
+ Maximum_Invocation_Edge_Count
+ (G => G,
+ Edge => Edge,
+ Count => Invocation_Edge_Count),
+
+ Cycle_Path_Stack => Cycle_Path_Stack,
+ Visited_Set => Visited_Set,
+ Visited_Stack => Visited_Stack,
+ Cycle_Count => Cycle_Count,
+ Cycle_Limit => Cycle_Limit,
+ Elaborate_All_Active => Elaborate_All_Active,
+ Has_Cycle => Successor_Has_Cycle,
+ Indent => Edge_Indent);
+
+ Has_Cycle := Has_Cycle or Successor_Has_Cycle;
+ end loop;
+
+ -- Visit the complementary vertex of the current vertex when pragma
+ -- Elaborate_All is in effect, or the current vertex is part of an
+ -- Elaborate_Body pair.
+
+ if Elaborate_All_Active
+ or else Is_Vertex_With_Elaborate_Body (G, Vertex)
+ then
+ Complement :=
+ Complementary_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Force_Complement => Elaborate_All_Active);
+
+ if Present (Complement) then
+ Find_Cycles_From_Vertex
+ (G => G,
+ Vertex => Complement,
+ End_Vertices => End_Vertices,
+ Deleted_Vertices => Deleted_Vertices,
+ Most_Significant_Edge => Most_Significant_Edge,
+ Invocation_Edge_Count => Invocation_Edge_Count,
+ Cycle_Path_Stack => Cycle_Path_Stack,
+ Visited_Set => Visited_Set,
+ Visited_Stack => Visited_Stack,
+ Cycle_Count => Cycle_Count,
+ Cycle_Limit => Cycle_Limit,
+ Elaborate_All_Active => Elaborate_All_Active,
+ Is_Start_Vertex => Is_Start_Vertex,
+ Has_Cycle => Complement_Has_Cycle,
+ Indent => Indent);
+
+ Has_Cycle := Has_Cycle or Complement_Has_Cycle;
+ end if;
+ end if;
+
+ -- The original algorithm clears the "marked stack" in two places:
+ --
+ -- * When the depth-first search starting from the current vertex
+ -- discovers at least one cycle, and
+ --
+ -- * When the depth-first search initiated from a start vertex
+ -- completes.
+ --
+ -- The modified version handles both cases in one place.
+
+ if Has_Cycle or else Is_Start_Vertex then
+ Unvisit
+ (Vertex => Vertex,
+ Visited_Set => Visited_Set,
+ Visited_Stack => Visited_Stack);
+ end if;
+
+ -- Delete a start vertex from the graph once its depth-first search
+ -- completes. This action preserves the invariant where a cycle is
+ -- not rediscovered "later" in some permuted form.
+
+ if Is_Start_Vertex then
+ LGV_Sets.Insert (Deleted_Vertices, Vertex);
+ end if;
+ end Find_Cycles_From_Vertex;
+
+ ------------------------------
+ -- Find_Cycles_In_Component --
+ ------------------------------
+
+ procedure Find_Cycles_In_Component
+ (G : Library_Graph;
+ Comp : Component_Id;
+ Cycle_Count : in out Natural;
+ Cycle_Limit : Natural)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Comp));
+
+ Num_Of_Vertices : constant Natural :=
+ Number_Of_Component_Vertices (G, Comp);
+
+ Elaborate_All_Active : constant Boolean :=
+ Has_Elaborate_All_Edge (G, Comp);
+ -- The presence of an Elaborate_All edge within a component causes
+ -- all spec-body pairs to be treated as one vertex.
+
+ Has_Cycle : Boolean;
+ Iter : Component_Vertex_Iterator;
+ Vertex : Library_Graph_Vertex_Id;
+
+ Cycle_Path_Stack : LGE_Lists.Doubly_Linked_List := LGE_Lists.Nil;
+ -- The "point stack" of Tarjan's algorithm. The original maintains
+ -- a stack of vertices, however for diagnostic purposes using edges
+ -- is preferable.
+
+ Deleted_Vertices : LGV_Sets.Membership_Set := LGV_Sets.Nil;
+ -- The original algorithm alters the graph by deleting vertices with
+ -- lower ordinals compared to some starting vertex. Since the graph
+ -- must remain intact for diagnostic purposes, vertices are instead
+ -- inserted in this set and treated as "deleted".
+
+ End_Vertices : LGV_Sets.Membership_Set := LGV_Sets.Nil;
+ -- The original algorithm uses a single vertex to indicate the start
+ -- and end vertex of a cycle. The semantics of pragmas Elaborate_All
+ -- and Elaborate_Body increase this number by one. The end vertices
+ -- are added to this set and treated as "cycle-terminating".
+
+ Visited_Set : LGV_Sets.Membership_Set := LGV_Sets.Nil;
+ -- The "mark" array of Tarjan's algorithm. Since the original visits
+ -- all vertices in increasing ordinal number 1 .. N, the array offers
+ -- a one-to-one mapping between a vertex and its "marked" state. The
+ -- modified version however visits vertices within components, where
+ -- their ordinals are not contiguous. Vertices are added to this set
+ -- and treated as "marked".
+
+ Visited_Stack : LGV_Lists.Doubly_Linked_List := LGV_Lists.Nil;
+ -- The "marked stack" of Tarjan's algorithm
+
+ begin
+ Trace_Component (G, Comp, No_Indentation);
+
+ -- Initialize all component-level data structures
+
+ Cycle_Path_Stack := LGE_Lists.Create;
+ Deleted_Vertices := LGV_Sets.Create (Num_Of_Vertices);
+ Visited_Set := LGV_Sets.Create (Num_Of_Vertices);
+ Visited_Stack := LGV_Lists.Create;
+
+ -- The modified version does not use ordinals to visit vertices in
+ -- 1 .. N fashion. To preserve the invariant of the original, this
+ -- version deletes a vertex after its depth-first search completes.
+ -- The timing of the deletion is sound because all cycles through
+ -- that vertex have already been discovered, thus the vertex cannot
+ -- contribute to any cycles discovered "later" in the algorithm.
+
+ Iter := Iterate_Component_Vertices (G, Comp);
+ while Has_Next (Iter) loop
+ Next (Iter, Vertex);
+
+ -- Construct the set of vertices (at most 2) that terminates a
+ -- potential cycle that starts from the current vertex.
+
+ End_Vertices :=
+ Cycle_End_Vertices
+ (G => G,
+ Vertex => Vertex,
+ Elaborate_All_Active => Elaborate_All_Active);
+
+ -- The modified version maintains two additional attributes while
+ -- performing the depth-first search:
+ --
+ -- * The most significant edge of the current potential cycle.
+ --
+ -- * The number of invocation edges encountered along the path
+ -- of the current potential cycle.
+ --
+ -- Both attributes are used in the heuristic that determines the
+ -- importance of cycles.
+
+ Find_Cycles_From_Vertex
+ (G => G,
+ Vertex => Vertex,
+ End_Vertices => End_Vertices,
+ Deleted_Vertices => Deleted_Vertices,
+ Most_Significant_Edge => No_Library_Graph_Edge,
+ Invocation_Edge_Count => 0,
+ Cycle_Path_Stack => Cycle_Path_Stack,
+ Visited_Set => Visited_Set,
+ Visited_Stack => Visited_Stack,
+ Cycle_Count => Cycle_Count,
+ Cycle_Limit => Cycle_Limit,
+ Elaborate_All_Active => Elaborate_All_Active,
+ Is_Start_Vertex => True,
+ Has_Cycle => Has_Cycle,
+ Indent => Nested_Indentation);
+
+ -- Destroy the cycle-terminating vertices because a new set must
+ -- be constructed for the next vertex.
+
+ LGV_Sets.Destroy (End_Vertices);
+ end loop;
+
+ -- Destroy all component-level data structures
+
+ LGE_Lists.Destroy (Cycle_Path_Stack);
+ LGV_Sets.Destroy (Deleted_Vertices);
+ LGV_Sets.Destroy (Visited_Set);
+ LGV_Lists.Destroy (Visited_Stack);
+ end Find_Cycles_In_Component;
+
+ ---------------------------------------
+ -- Find_First_Lower_Precedence_Cycle --
+ ---------------------------------------
+
+ function Find_First_Lower_Precedence_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Id
+ is
+ Current_Cycle : Library_Graph_Cycle_Id;
+ Iter : All_Cycle_Iterator;
+ Lesser_Cycle : Library_Graph_Cycle_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ -- Assume that there is no lesser cycle
+
+ Lesser_Cycle := No_Library_Graph_Cycle;
+
+ -- Find a cycle with a slightly lower precedence than the input
+ -- cycle.
+ --
+ -- IMPORTANT:
+ --
+ -- * The iterator must run to completion in order to unlock the
+ -- list of all cycles.
+
+ Iter := Iterate_All_Cycles (G);
+ while Has_Next (Iter) loop
+ Next (Iter, Current_Cycle);
+
+ if not Present (Lesser_Cycle)
+ and then Cycle_Precedence
+ (G => G,
+ Cycle => Cycle,
+ Compared_To => Current_Cycle) = Higher_Precedence
+ then
+ Lesser_Cycle := Current_Cycle;
+ end if;
+ end loop;
+
+ return Lesser_Cycle;
+ end Find_First_Lower_Precedence_Cycle;
+
------------------------------
-- Get_Component_Attributes --
------------------------------
@@ -1658,23 +3198,37 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (Comp));
- return CA.Get (G.Component_Attributes, Comp);
+ return Component_Tables.Get (G.Component_Attributes, Comp);
end Get_Component_Attributes;
------------------------
+ -- Get_LGC_Attributes --
+ ------------------------
+
+ function Get_LGC_Attributes
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Attributes
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return LGC_Tables.Get (G.Cycle_Attributes, Cycle);
+ end Get_LGC_Attributes;
+
+ ------------------------
-- Get_LGE_Attributes --
------------------------
function Get_LGE_Attributes
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id)
- return Library_Graph_Edge_Attributes
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Edge_Attributes
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Edge));
- return EA.Get (G.Edge_Attributes, LGE_Id);
+ return LGE_Tables.Get (G.Edge_Attributes, Edge);
end Get_LGE_Attributes;
------------------------
@@ -1683,41 +3237,154 @@ package body Bindo.Graphs is
function Get_LGV_Attributes
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id)
return Library_Graph_Vertex_Attributes
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- return VA.Get (G.Vertex_Attributes, LGV_Id);
+ return LGV_Tables.Get (G.Vertex_Attributes, Vertex);
end Get_LGV_Attributes;
+ -----------------------------
+ -- Has_Elaborate_All_Cycle --
+ -----------------------------
+
+ function Has_Elaborate_All_Cycle (G : Library_Graph) return Boolean is
+ Edge : Library_Graph_Edge_Id;
+ Iter : All_Edge_Iterator;
+ Seen : Boolean;
+
+ begin
+ pragma Assert (Present (G));
+
+ -- Assume that no cyclic Elaborate_All edge has been seen
+
+ Seen := False;
+
+ -- IMPORTANT:
+ --
+ -- * The iteration must run to completion in order to unlock the
+ -- graph.
+
+ Iter := Iterate_All_Edges (G);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ if not Seen and then Is_Cyclic_Elaborate_All_Edge (G, Edge) then
+ Seen := True;
+ end if;
+ end loop;
+
+ return Seen;
+ end Has_Elaborate_All_Cycle;
+
+ ----------------------------
+ -- Has_Elaborate_All_Edge --
+ ----------------------------
+
+ function Has_Elaborate_All_Edge
+ (G : Library_Graph;
+ Comp : Component_Id) return Boolean
+ is
+ Has_Edge : Boolean;
+ Iter : Component_Vertex_Iterator;
+ Vertex : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Comp));
+
+ -- Assume that there is no Elaborate_All edge
+
+ Has_Edge := False;
+
+ -- IMPORTANT:
+ --
+ -- * The iteration must run to completion in order to unlock the
+ -- component vertices.
+
+ Iter := Iterate_Component_Vertices (G, Comp);
+ while Has_Next (Iter) loop
+ Next (Iter, Vertex);
+
+ Has_Edge := Has_Edge or else Has_Elaborate_All_Edge (G, Vertex);
+ end loop;
+
+ return Has_Edge;
+ end Has_Elaborate_All_Edge;
+
+ ----------------------------
+ -- Has_Elaborate_All_Edge --
+ ----------------------------
+
+ function Has_Elaborate_All_Edge
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ Edge : Library_Graph_Edge_Id;
+ Has_Edge : Boolean;
+ Iter : Edges_To_Successors_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ -- Assume that there is no Elaborate_All edge
+
+ Has_Edge := False;
+
+ -- IMPORTANT:
+ --
+ -- * The iteration must run to completion in order to unlock the
+ -- edges to successors.
+
+ Iter := Iterate_Edges_To_Successors (G, Vertex);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ Has_Edge :=
+ Has_Edge or else Is_Cyclic_Elaborate_All_Edge (G, Edge);
+ end loop;
+
+ return Has_Edge;
+ end Has_Elaborate_All_Edge;
+
------------------------
-- Has_Elaborate_Body --
------------------------
function Has_Elaborate_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
+ pragma Assert (Present (Vertex));
+ U_Id : constant Unit_Id := Unit (G, Vertex);
U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
begin
- return U_Rec.Elaborate_Body;
+ -- Treat the spec and body as decoupled when switch -d_b (ignore the
+ -- effects of pragma Elaborate_Body) is in effect.
+
+ return U_Rec.Elaborate_Body and not Debug_Flag_Underscore_B;
end Has_Elaborate_Body;
--------------
-- Has_Next --
--------------
+ function Has_Next (Iter : All_Cycle_Iterator) return Boolean is
+ begin
+ return LGC_Lists.Has_Next (LGC_Lists.Iterator (Iter));
+ end Has_Next;
+
+ --------------
+ -- Has_Next --
+ --------------
+
function Has_Next (Iter : All_Edge_Iterator) return Boolean is
begin
return DG.Has_Next (DG.All_Edge_Iterator (Iter));
@@ -1754,11 +3421,64 @@ package body Bindo.Graphs is
-- Has_Next --
--------------
+ function Has_Next (Iter : Edges_Of_Cycle_Iterator) return Boolean is
+ begin
+ return LGE_Lists.Has_Next (LGE_Lists.Iterator (Iter));
+ end Has_Next;
+
+ --------------
+ -- Has_Next --
+ --------------
+
function Has_Next (Iter : Edges_To_Successors_Iterator) return Boolean is
begin
return DG.Has_Next (DG.Outgoing_Edge_Iterator (Iter));
end Has_Next;
+ -----------------------------
+ -- Has_No_Elaboration_Code --
+ -----------------------------
+
+ function Has_No_Elaboration_Code
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return Has_No_Elaboration_Code (Unit (G, Vertex));
+ end Has_No_Elaboration_Code;
+
+ -----------------------------------------
+ -- Hash_Library_Graph_Cycle_Attributes --
+ -----------------------------------------
+
+ function Hash_Library_Graph_Cycle_Attributes
+ (Attrs : Library_Graph_Cycle_Attributes) return Bucket_Range_Type
+ is
+ Edge : Library_Graph_Edge_Id;
+ Hash : Bucket_Range_Type;
+ Iter : LGE_Lists.Iterator;
+
+ begin
+ pragma Assert (LGE_Lists.Present (Attrs.Path));
+
+ -- The hash is obtained in the following manner:
+ --
+ -- (((edge1 * 31) + edge2) * 31) + edgeN
+
+ Hash := 0;
+ Iter := LGE_Lists.Iterate (Attrs.Path);
+ while LGE_Lists.Has_Next (Iter) loop
+ LGE_Lists.Next (Iter, Edge);
+
+ Hash := (Hash * 31) + Bucket_Range_Type (Edge);
+ end loop;
+
+ return Hash;
+ end Hash_Library_Graph_Cycle_Attributes;
+
-----------------------------------------
-- Hash_Predecessor_Successor_Relation --
-----------------------------------------
@@ -1776,21 +3496,106 @@ package body Bindo.Graphs is
Bucket_Range_Type (Rel.Successor));
end Hash_Predecessor_Successor_Relation;
+ ------------------------------
+ -- Highest_Precedence_Cycle --
+ ------------------------------
+
+ function Highest_Precedence_Cycle
+ (G : Library_Graph) return Library_Graph_Cycle_Id
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (LGC_Lists.Present (G.Cycles));
+
+ if LGC_Lists.Is_Empty (G.Cycles) then
+ return No_Library_Graph_Cycle;
+
+ -- The highest precedence cycle is always the first in the list of
+ -- all cycles.
+
+ else
+ return LGC_Lists.First (G.Cycles);
+ end if;
+ end Highest_Precedence_Cycle;
+
+ -----------------------------
+ -- Highest_Precedence_Edge --
+ -----------------------------
+
+ function Highest_Precedence_Edge
+ (G : Library_Graph;
+ Left : Library_Graph_Edge_Id;
+ Right : Library_Graph_Edge_Id) return Library_Graph_Edge_Id
+ is
+ Edge_Prec : Precedence_Kind;
+
+ begin
+ pragma Assert (Present (G));
+
+ -- Both edges are available, pick the one with highest precedence
+
+ if Present (Left) and then Present (Right) then
+ Edge_Prec :=
+ Edge_Precedence
+ (G => G,
+ Edge => Left,
+ Compared_To => Right);
+
+ if Edge_Prec = Higher_Precedence then
+ return Left;
+
+ -- The precedence rules for edges are such that no two edges can
+ -- ever have the same precedence.
+
+ else
+ pragma Assert (Edge_Prec = Lower_Precedence);
+ return Right;
+ end if;
+
+ -- Otherwise at least one edge must be present
+
+ elsif Present (Left) then
+ return Left;
+
+ else
+ pragma Assert (Present (Right));
+
+ return Right;
+ end if;
+ end Highest_Precedence_Edge;
+
--------------------------
-- In_Elaboration_Order --
--------------------------
function In_Elaboration_Order
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- return Get_LGV_Attributes (G, LGV_Id).In_Elaboration_Order;
+ return Get_LGV_Attributes (G, Vertex).In_Elaboration_Order;
end In_Elaboration_Order;
+ -----------------------
+ -- In_Same_Component --
+ -----------------------
+
+ function In_Same_Component
+ (G : Library_Graph;
+ Left : Library_Graph_Vertex_Id;
+ Right : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Left));
+ pragma Assert (Present (Right));
+
+ return Component (G, Left) = Component (G, Right);
+ end In_Same_Component;
+
----------------------------------------
-- Increment_Library_Graph_Edge_Count --
----------------------------------------
@@ -1813,7 +3618,8 @@ package body Bindo.Graphs is
procedure Increment_Pending_Predecessors
(G : Library_Graph;
- Comp : Component_Id)
+ Comp : Component_Id;
+ Edge : Library_Graph_Edge_Id)
is
Attrs : Component_Attributes;
@@ -1822,7 +3628,13 @@ package body Bindo.Graphs is
pragma Assert (Present (Comp));
Attrs := Get_Component_Attributes (G, Comp);
- Attrs.Pending_Predecessors := Attrs.Pending_Predecessors + 1;
+
+ Update_Pending_Predecessors
+ (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
+ Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
+ Update_Weak => Is_Invocation_Edge (G, Edge),
+ Value => 1);
+
Set_Component_Attributes (G, Comp, Attrs);
end Increment_Pending_Predecessors;
@@ -1832,17 +3644,24 @@ package body Bindo.Graphs is
procedure Increment_Pending_Predecessors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id;
+ Edge : Library_Graph_Edge_Id)
is
Attrs : Library_Graph_Vertex_Attributes;
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- Attrs := Get_LGV_Attributes (G, LGV_Id);
- Attrs.Pending_Predecessors := Attrs.Pending_Predecessors + 1;
- Set_LGV_Attributes (G, LGV_Id, Attrs);
+ Attrs := Get_LGV_Attributes (G, Vertex);
+
+ Update_Pending_Predecessors
+ (Strong_Predecessors => Attrs.Pending_Strong_Predecessors,
+ Weak_Predecessors => Attrs.Pending_Weak_Predecessors,
+ Update_Weak => Is_Invocation_Edge (G, Edge),
+ Value => 1);
+
+ Set_LGV_Attributes (G, Vertex, Attrs);
end Increment_Pending_Predecessors;
---------------------------
@@ -1854,30 +3673,60 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
-- The graph already contains a set of components. Reinitialize
- -- them in order to accomodate the new set of components about to
+ -- them in order to accommodate the new set of components about to
-- be computed.
if Number_Of_Components (G) > 0 then
- CA.Destroy (G.Component_Attributes);
- G.Component_Attributes := CA.Create (Number_Of_Vertices (G));
+ Component_Tables.Destroy (G.Component_Attributes);
+
+ G.Component_Attributes :=
+ Component_Tables.Create (Number_Of_Vertices (G));
end if;
end Initialize_Components;
+ ---------------------------
+ -- Invocation_Edge_Count --
+ ---------------------------
+
+ function Invocation_Edge_Count
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Natural
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return Get_LGC_Attributes (G, Cycle).Invocation_Edge_Count;
+ end Invocation_Edge_Count;
+
+ -------------------------------
+ -- Invocation_Graph_Encoding --
+ -------------------------------
+
+ function Invocation_Graph_Encoding
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id)
+ return Invocation_Graph_Encoding_Kind
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return Invocation_Graph_Encoding (Unit (G, Vertex));
+ end Invocation_Graph_Encoding;
+
-------------
-- Is_Body --
-------------
function Is_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
+ pragma Assert (Present (Vertex));
+ U_Id : constant Unit_Id := Unit (G, Vertex);
U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
begin
@@ -1890,19 +3739,17 @@ package body Bindo.Graphs is
function Is_Body_Of_Spec_With_Elaborate_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
- Spec_LGV_Id : Library_Graph_Vertex_Id;
-
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- if Is_Body_With_Spec (G, LGV_Id) then
- Spec_LGV_Id := Proper_Spec (G, LGV_Id);
- pragma Assert (Present (Spec_LGV_Id));
-
- return Is_Spec_With_Elaborate_Body (G, Spec_LGV_Id);
+ if Is_Body_With_Spec (G, Vertex) then
+ return
+ Is_Spec_With_Elaborate_Body
+ (G => G,
+ Vertex => Proper_Spec (G, Vertex));
end if;
return False;
@@ -1914,21 +3761,176 @@ package body Bindo.Graphs is
function Is_Body_With_Spec
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
+ pragma Assert (Present (Vertex));
+ U_Id : constant Unit_Id := Unit (G, Vertex);
U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
begin
return U_Rec.Utype = Is_Body;
end Is_Body_With_Spec;
+ ------------------------------
+ -- Is_Cycle_Initiating_Edge --
+ ------------------------------
+
+ function Is_Cycle_Initiating_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Cyclic_Elaborate_All_Edge (G, Edge)
+ or else Is_Cyclic_Elaborate_Body_Edge (G, Edge)
+ or else Is_Cyclic_Elaborate_Edge (G, Edge)
+ or else Is_Cyclic_Forced_Edge (G, Edge)
+ or else Is_Cyclic_Invocation_Edge (G, Edge);
+ end Is_Cycle_Initiating_Edge;
+
+ --------------------
+ -- Is_Cyclic_Edge --
+ --------------------
+
+ function Is_Cyclic_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Cycle_Initiating_Edge (G, Edge)
+ or else Is_Cyclic_With_Edge (G, Edge);
+ end Is_Cyclic_Edge;
+
+ ----------------------------------
+ -- Is_Cyclic_Elaborate_All_Edge --
+ ----------------------------------
+
+ function Is_Cyclic_Elaborate_All_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Elaborate_All_Edge (G, Edge)
+ and then Links_Vertices_In_Same_Component (G, Edge);
+ end Is_Cyclic_Elaborate_All_Edge;
+
+ -----------------------------------
+ -- Is_Cyclic_Elaborate_Body_Edge --
+ -----------------------------------
+
+ function Is_Cyclic_Elaborate_Body_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Elaborate_Body_Edge (G, Edge)
+ and then Links_Vertices_In_Same_Component (G, Edge);
+ end Is_Cyclic_Elaborate_Body_Edge;
+
+ ------------------------------
+ -- Is_Cyclic_Elaborate_Edge --
+ ------------------------------
+
+ function Is_Cyclic_Elaborate_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Elaborate_Edge (G, Edge)
+ and then Links_Vertices_In_Same_Component (G, Edge);
+ end Is_Cyclic_Elaborate_Edge;
+
+ ---------------------------
+ -- Is_Cyclic_Forced_Edge --
+ ---------------------------
+
+ function Is_Cyclic_Forced_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Forced_Edge (G, Edge)
+ and then Links_Vertices_In_Same_Component (G, Edge);
+ end Is_Cyclic_Forced_Edge;
+
+ -------------------------------
+ -- Is_Cyclic_Invocation_Edge --
+ -------------------------------
+
+ function Is_Cyclic_Invocation_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Invocation_Edge (G, Edge)
+ and then Links_Vertices_In_Same_Component (G, Edge);
+ end Is_Cyclic_Invocation_Edge;
+
+ -------------------------
+ -- Is_Cyclic_With_Edge --
+ -------------------------
+
+ function Is_Cyclic_With_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ -- Ignore Elaborate_Body edges because they also appear as with
+ -- edges, but have special successors.
+
+ return
+ Is_With_Edge (G, Edge)
+ and then Links_Vertices_In_Same_Component (G, Edge)
+ and then not Is_Elaborate_Body_Edge (G, Edge);
+ end Is_Cyclic_With_Edge;
+
+ -------------------------------
+ -- Is_Dynamically_Elaborated --
+ -------------------------------
+
+ function Is_Dynamically_Elaborated
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return Is_Dynamically_Elaborated (Unit (G, Vertex));
+ end Is_Dynamically_Elaborated;
+
-----------------------------
-- Is_Elaborable_Component --
-----------------------------
@@ -1941,12 +3943,14 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (Comp));
- -- A component can be elaborated when
+ -- A component is elaborable when:
--
- -- * The component is no longer wanting on any of its predecessors
- -- to be elaborated.
+ -- * It is not waiting on strong predecessors, and
+ -- * It is not waiting on weak predecessors
- return Pending_Predecessors (G, Comp) = 0;
+ return
+ Pending_Strong_Predecessors (G, Comp) = 0
+ and then Pending_Weak_Predecessors (G, Comp) = 0;
end Is_Elaborable_Component;
--------------------------
@@ -1955,104 +3959,132 @@ package body Bindo.Graphs is
function Is_Elaborable_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
- Check_LGV_Id : Library_Graph_Vertex_Id;
-
- begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- Check_LGV_Id := LGV_Id;
+ Complement : constant Library_Graph_Vertex_Id :=
+ Complementary_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Force_Complement => False);
- -- A spec-body pair where the spec carries pragma Elaborate_Body must
- -- be treated as one vertex for elaboration purposes. Use the spec as
- -- the point of reference for the composite vertex.
+ Strong_Preds : Natural;
+ Weak_Preds : Natural;
- if Is_Body_Of_Spec_With_Elaborate_Body (G, Check_LGV_Id) then
- Check_LGV_Id := Proper_Spec (G, Check_LGV_Id);
- pragma Assert (Present (Check_LGV_Id));
+ begin
+ -- A vertex is elaborable when:
+ --
+ -- * It has not been elaborated yet, and
+ -- * The complement vertex of an Elaborate_Body pair has not been
+ -- elaborated yet, and
+ -- * It resides within an elaborable component, and
+ -- * It is not waiting on strong predecessors, and
+ -- * It is not waiting on weak predecessors
+
+ if In_Elaboration_Order (G, Vertex) then
+ return False;
+
+ elsif Present (Complement)
+ and then In_Elaboration_Order (G, Complement)
+ then
+ return False;
+
+ elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then
+ return False;
end if;
- return
- Is_Elaborable_Vertex
- (G => G,
- LGV_Id => Check_LGV_Id,
- Predecessors => 0);
+ Pending_Predecessors_For_Elaboration
+ (G => G,
+ Vertex => Vertex,
+ Strong_Preds => Strong_Preds,
+ Weak_Preds => Weak_Preds);
+
+ return Strong_Preds = 0 and then Weak_Preds = 0;
end Is_Elaborable_Vertex;
- --------------------------
- -- Is_Elaborable_Vertex --
- --------------------------
+ ---------------------------
+ -- Is_Elaborate_All_Edge --
+ ---------------------------
- function Is_Elaborable_Vertex
- (G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
- Predecessors : Natural) return Boolean
+ function Is_Elaborate_All_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- Comp : constant Component_Id := Component (G, LGV_Id);
+ pragma Assert (Present (Edge));
- pragma Assert (Present (Comp));
+ return Kind (G, Edge) = Elaborate_All_Edge;
+ end Is_Elaborate_All_Edge;
- Body_LGV_Id : Library_Graph_Vertex_Id;
+ ----------------------------
+ -- Is_Elaborate_Body_Edge --
+ ----------------------------
+ function Is_Elaborate_Body_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
begin
- -- The vertex must not be re-elaborated once it has been elaborated
-
- if In_Elaboration_Order (G, LGV_Id) then
- return False;
-
- -- The vertex must not be waiting on more precedessors than requested
- -- to be elaborated.
-
- elsif Pending_Predecessors (G, LGV_Id) /= Predecessors then
- return False;
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
- -- The component where the vertex resides must not be waiting on any
- -- of its precedessors to be elaborated.
+ return
+ Kind (G, Edge) = With_Edge
+ and then Is_Vertex_With_Elaborate_Body (G, Successor (G, Edge));
+ end Is_Elaborate_Body_Edge;
- elsif not Is_Elaborable_Component (G, Comp) then
- return False;
+ -----------------------
+ -- Is_Elaborate_Edge --
+ -----------------------
- -- The vertex denotes a spec with a completing body, and is subject
- -- to pragma Elaborate_Body. The body must be elaborable for the
- -- vertex to be elaborated. Account for the sole predecessor of the
- -- body which is the vertex itself.
+ function Is_Elaborate_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
- elsif Is_Spec_With_Elaborate_Body (G, LGV_Id) then
- Body_LGV_Id := Proper_Body (G, LGV_Id);
- pragma Assert (Present (Body_LGV_Id));
+ return Kind (G, Edge) = Elaborate_Edge;
+ end Is_Elaborate_Edge;
- return
- Is_Elaborable_Vertex
- (G => G,
- LGV_Id => Body_LGV_Id,
- Predecessors => 1);
- end if;
+ ----------------------------
+ -- Is_Elaborate_Body_Pair --
+ ----------------------------
- -- At this point it is known that the vertex can be elaborated
+ function Is_Elaborate_Body_Pair
+ (G : Library_Graph;
+ Spec_Vertex : Library_Graph_Vertex_Id;
+ Body_Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Spec_Vertex));
+ pragma Assert (Present (Body_Vertex));
- return True;
- end Is_Elaborable_Vertex;
+ return
+ Is_Spec_With_Elaborate_Body (G, Spec_Vertex)
+ and then Is_Body_Of_Spec_With_Elaborate_Body (G, Body_Vertex)
+ and then Proper_Body (G, Spec_Vertex) = Body_Vertex;
+ end Is_Elaborate_Body_Pair;
- ------------------------------------------------
- -- Is_Existing_Predecessor_Successor_Relation --
- ------------------------------------------------
+ --------------------
+ -- Is_Forced_Edge --
+ --------------------
- function Is_Existing_Predecessor_Successor_Relation
- (G : Library_Graph;
- Rel : Predecessor_Successor_Relation) return Boolean
+ function Is_Forced_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (Rel.Predecessor));
- pragma Assert (Present (Rel.Successor));
+ pragma Assert (Present (Edge));
- return PS.Contains (G.Relations, Rel);
- end Is_Existing_Predecessor_Successor_Relation;
+ return Kind (G, Edge) = Forced_Edge;
+ end Is_Forced_Edge;
----------------------
-- Is_Internal_Unit --
@@ -2060,18 +4092,29 @@ package body Bindo.Graphs is
function Is_Internal_Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
+ return Is_Internal_Unit (Unit (G, Vertex));
+ end Is_Internal_Unit;
- pragma Assert (Present (U_Id));
+ ------------------------
+ -- Is_Invocation_Edge --
+ ------------------------
+ function Is_Invocation_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
begin
- return Is_Internal_Unit (U_Id);
- end Is_Internal_Unit;
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return Kind (G, Edge) = Invocation_Edge;
+ end Is_Invocation_Edge;
------------------------
-- Is_Predefined_Unit --
@@ -2079,17 +4122,13 @@ package body Bindo.Graphs is
function Is_Predefined_Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
+ pragma Assert (Present (Vertex));
- pragma Assert (Present (U_Id));
-
- begin
- return Is_Predefined_Unit (U_Id);
+ return Is_Predefined_Unit (Unit (G, Vertex));
end Is_Predefined_Unit;
---------------------------
@@ -2098,57 +4137,79 @@ package body Bindo.Graphs is
function Is_Preelaborated_Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
+ pragma Assert (Present (Vertex));
+ U_Id : constant Unit_Id := Unit (G, Vertex);
U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
begin
return U_Rec.Preelab or else U_Rec.Pure;
end Is_Preelaborated_Unit;
+ ----------------------
+ -- Is_Recorded_Edge --
+ ----------------------
+
+ function Is_Recorded_Edge
+ (G : Library_Graph;
+ Rel : Predecessor_Successor_Relation) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Rel.Predecessor));
+ pragma Assert (Present (Rel.Successor));
+
+ return RE_Sets.Contains (G.Recorded_Edges, Rel);
+ end Is_Recorded_Edge;
+
-------------
-- Is_Spec --
-------------
function Is_Spec
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
+ pragma Assert (Present (Vertex));
+ U_Id : constant Unit_Id := Unit (G, Vertex);
U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
begin
return U_Rec.Utype = Is_Spec or else U_Rec.Utype = Is_Spec_Only;
end Is_Spec;
+ ------------------------------
+ -- Is_Spec_Before_Body_Edge --
+ ------------------------------
+
+ function Is_Spec_Before_Body_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return Kind (G, Edge) = Spec_Before_Body_Edge;
+ end Is_Spec_Before_Body_Edge;
+
-----------------------
-- Is_Spec_With_Body --
-----------------------
function Is_Spec_With_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
-
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
+ pragma Assert (Present (Vertex));
+ U_Id : constant Unit_Id := Unit (G, Vertex);
U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
begin
@@ -2161,17 +4222,131 @@ package body Bindo.Graphs is
function Is_Spec_With_Elaborate_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
return
- Is_Spec_With_Body (G, LGV_Id)
- and then Has_Elaborate_Body (G, LGV_Id);
+ Is_Spec_With_Body (G, Vertex)
+ and then Has_Elaborate_Body (G, Vertex);
end Is_Spec_With_Elaborate_Body;
+ ------------------------------
+ -- Is_Static_Successor_Edge --
+ ------------------------------
+
+ function Is_Static_Successor_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return
+ Is_Invocation_Edge (G, Edge)
+ and then not Is_Dynamically_Elaborated (G, Successor (G, Edge));
+ end Is_Static_Successor_Edge;
+
+ -----------------------------------
+ -- Is_Vertex_With_Elaborate_Body --
+ -----------------------------------
+
+ function Is_Vertex_With_Elaborate_Body
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return
+ Is_Spec_With_Elaborate_Body (G, Vertex)
+ or else
+ Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex);
+ end Is_Vertex_With_Elaborate_Body;
+
+ ---------------------------------
+ -- Is_Weakly_Elaborable_Vertex --
+ ----------------------------------
+
+ function Is_Weakly_Elaborable_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ Complement : constant Library_Graph_Vertex_Id :=
+ Complementary_Vertex
+ (G => G,
+ Vertex => Vertex,
+ Force_Complement => False);
+
+ Strong_Preds : Natural;
+ Weak_Preds : Natural;
+
+ begin
+ -- A vertex is weakly elaborable when:
+ --
+ -- * It has not been elaborated yet, and
+ -- * The complement vertex of an Elaborate_Body pair has not been
+ -- elaborated yet, and
+ -- * It resides within an elaborable component, and
+ -- * It is not waiting on strong predecessors, and
+ -- * It is waiting on at least one weak predecessor
+
+ if In_Elaboration_Order (G, Vertex) then
+ return False;
+
+ elsif Present (Complement)
+ and then In_Elaboration_Order (G, Complement)
+ then
+ return False;
+
+ elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then
+ return False;
+ end if;
+
+ Pending_Predecessors_For_Elaboration
+ (G => G,
+ Vertex => Vertex,
+ Strong_Preds => Strong_Preds,
+ Weak_Preds => Weak_Preds);
+
+ return Strong_Preds = 0 and then Weak_Preds >= 1;
+ end Is_Weakly_Elaborable_Vertex;
+
+ ------------------
+ -- Is_With_Edge --
+ ------------------
+
+ function Is_With_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return Kind (G, Edge) = With_Edge;
+ end Is_With_Edge;
+
+ ------------------------
+ -- Iterate_All_Cycles --
+ ------------------------
+
+ function Iterate_All_Cycles
+ (G : Library_Graph) return All_Cycle_Iterator
+ is
+ begin
+ pragma Assert (Present (G));
+
+ return All_Cycle_Iterator (LGC_Lists.Iterate (G.Cycles));
+ end Iterate_All_Cycles;
+
-----------------------
-- Iterate_All_Edges --
-----------------------
@@ -2228,22 +4403,36 @@ package body Bindo.Graphs is
(DG.Iterate_Component_Vertices (G.Graph, Comp));
end Iterate_Component_Vertices;
+ ----------------------------
+ -- Iterate_Edges_Of_Cycle --
+ ----------------------------
+
+ function Iterate_Edges_Of_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Edges_Of_Cycle_Iterator
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return Edges_Of_Cycle_Iterator (LGE_Lists.Iterate (Path (G, Cycle)));
+ end Iterate_Edges_Of_Cycle;
+
---------------------------------
-- Iterate_Edges_To_Successors --
---------------------------------
function Iterate_Edges_To_Successors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
- return Edges_To_Successors_Iterator
+ Vertex : Library_Graph_Vertex_Id) return Edges_To_Successors_Iterator
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
return
Edges_To_Successors_Iterator
- (DG.Iterate_Outgoing_Edges (G.Graph, LGV_Id));
+ (DG.Iterate_Outgoing_Edges (G.Graph, Vertex));
end Iterate_Edges_To_Successors;
----------
@@ -2252,15 +4441,45 @@ package body Bindo.Graphs is
function Kind
(G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Library_Graph_Edge_Kind
+ Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Kind
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Cycle));
- return Get_LGE_Attributes (G, LGE_Id).Kind;
+ return Get_LGC_Attributes (G, Cycle).Kind;
end Kind;
+ ----------
+ -- Kind --
+ ----------
+
+ function Kind
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Edge_Kind
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ return Get_LGE_Attributes (G, Edge).Kind;
+ end Kind;
+
+ ------------
+ -- Length --
+ ------------
+
+ function Length
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Natural
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return LGE_Lists.Size (Path (G, Cycle));
+ end Length;
+
------------------------------
-- Library_Graph_Edge_Count --
------------------------------
@@ -2280,27 +4499,45 @@ package body Bindo.Graphs is
--------------------------------------
function Links_Vertices_In_Same_Component
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Boolean
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Edge));
- Pred : constant Library_Graph_Vertex_Id := Predecessor (G, LGE_Id);
- Succ : constant Library_Graph_Vertex_Id := Successor (G, LGE_Id);
+ -- An edge is part of a cycle when both the successor and predecessor
+ -- reside in the same component.
- pragma Assert (Present (Pred));
- pragma Assert (Present (Succ));
+ return
+ In_Same_Component
+ (G => G,
+ Left => Predecessor (G, Edge),
+ Right => Successor (G, Edge));
+ end Links_Vertices_In_Same_Component;
- Pred_Comp : constant Component_Id := Component (G, Pred);
- Succ_Comp : constant Component_Id := Component (G, Succ);
+ -----------------------------------
+ -- Maximum_Invocation_Edge_Count --
+ -----------------------------------
- pragma Assert (Present (Pred_Comp));
- pragma Assert (Present (Succ_Comp));
+ function Maximum_Invocation_Edge_Count
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ Count : Natural) return Natural
+ is
+ New_Count : Natural;
begin
- return Pred_Comp = Succ_Comp;
- end Links_Vertices_In_Same_Component;
+ pragma Assert (Present (G));
+
+ New_Count := Count;
+
+ if Present (Edge) and then Is_Invocation_Edge (G, Edge) then
+ New_Count := New_Count + 1;
+ end if;
+
+ return New_Count;
+ end Maximum_Invocation_Edge_Count;
----------
-- Name --
@@ -2308,17 +4545,13 @@ package body Bindo.Graphs is
function Name
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Unit_Name_Type
+ Vertex : Library_Graph_Vertex_Id) return Unit_Name_Type
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
-
- begin
- return Name (U_Id);
+ return Name (Unit (G, Vertex));
end Name;
-----------------------
@@ -2327,29 +4560,37 @@ package body Bindo.Graphs is
function Needs_Elaboration
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean
+ Vertex : Library_Graph_Vertex_Id) return Boolean
is
+ begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
+ return Needs_Elaboration (Unit (G, Vertex));
+ end Needs_Elaboration;
- pragma Assert (Present (U_Id));
+ ----------
+ -- Next --
+ ----------
+ procedure Next
+ (Iter : in out All_Cycle_Iterator;
+ Cycle : out Library_Graph_Cycle_Id)
+ is
begin
- return Needs_Elaboration (U_Id);
- end Needs_Elaboration;
+ LGC_Lists.Next (LGC_Lists.Iterator (Iter), Cycle);
+ end Next;
----------
-- Next --
----------
procedure Next
- (Iter : in out All_Edge_Iterator;
- LGE_Id : out Library_Graph_Edge_Id)
+ (Iter : in out All_Edge_Iterator;
+ Edge : out Library_Graph_Edge_Id)
is
begin
- DG.Next (DG.All_Edge_Iterator (Iter), LGE_Id);
+ DG.Next (DG.All_Edge_Iterator (Iter), Edge);
end Next;
----------
@@ -2358,10 +4599,22 @@ package body Bindo.Graphs is
procedure Next
(Iter : in out All_Vertex_Iterator;
- LGV_Id : out Library_Graph_Vertex_Id)
+ Vertex : out Library_Graph_Vertex_Id)
is
begin
- DG.Next (DG.All_Vertex_Iterator (Iter), LGV_Id);
+ DG.Next (DG.All_Vertex_Iterator (Iter), Vertex);
+ end Next;
+
+ ----------
+ -- Next --
+ ----------
+
+ procedure Next
+ (Iter : in out Edges_Of_Cycle_Iterator;
+ Edge : out Library_Graph_Edge_Id)
+ is
+ begin
+ LGE_Lists.Next (LGE_Lists.Iterator (Iter), Edge);
end Next;
----------
@@ -2381,11 +4634,11 @@ package body Bindo.Graphs is
----------
procedure Next
- (Iter : in out Edges_To_Successors_Iterator;
- LGE_Id : out Library_Graph_Edge_Id)
+ (Iter : in out Edges_To_Successors_Iterator;
+ Edge : out Library_Graph_Edge_Id)
is
begin
- DG.Next (DG.Outgoing_Edge_Iterator (Iter), LGE_Id);
+ DG.Next (DG.Outgoing_Edge_Iterator (Iter), Edge);
end Next;
----------
@@ -2394,12 +4647,51 @@ package body Bindo.Graphs is
procedure Next
(Iter : in out Component_Vertex_Iterator;
- LGV_Id : out Library_Graph_Vertex_Id)
+ Vertex : out Library_Graph_Vertex_Id)
is
begin
- DG.Next (DG.Component_Vertex_Iterator (Iter), LGV_Id);
+ DG.Next (DG.Component_Vertex_Iterator (Iter), Vertex);
end Next;
+ --------------------------
+ -- Normalize_Cycle_Path --
+ --------------------------
+
+ procedure Normalize_Cycle_Path
+ (Cycle_Path : LGE_Lists.Doubly_Linked_List;
+ Most_Significant_Edge : Library_Graph_Edge_Id)
+ is
+ Edge : Library_Graph_Edge_Id;
+
+ begin
+ pragma Assert (LGE_Lists.Present (Cycle_Path));
+ pragma Assert (Present (Most_Significant_Edge));
+
+ -- Perform at most |Cycle_Path| rotations in case the cycle is
+ -- malformed and the significant edge does not appear within.
+
+ for Rotation in 1 .. LGE_Lists.Size (Cycle_Path) loop
+ Edge := LGE_Lists.First (Cycle_Path);
+
+ -- The cycle is already rotated such that the most significant
+ -- edge is first.
+
+ if Edge = Most_Significant_Edge then
+ return;
+
+ -- Otherwise rotate the cycle by relocating the current edge from
+ -- the start to the end of the path. This preserves the order of
+ -- the path.
+
+ else
+ LGE_Lists.Delete_First (Cycle_Path);
+ LGE_Lists.Append (Cycle_Path, Edge);
+ end if;
+ end loop;
+
+ pragma Assert (False);
+ end Normalize_Cycle_Path;
+
----------------------------------
-- Number_Of_Component_Vertices --
----------------------------------
@@ -2426,6 +4718,17 @@ package body Bindo.Graphs is
return DG.Number_Of_Components (G.Graph);
end Number_Of_Components;
+ ----------------------
+ -- Number_Of_Cycles --
+ ----------------------
+
+ function Number_Of_Cycles (G : Library_Graph) return Natural is
+ begin
+ pragma Assert (Present (G));
+
+ return LGC_Lists.Size (G.Cycles);
+ end Number_Of_Cycles;
+
---------------------
-- Number_Of_Edges --
---------------------
@@ -2443,12 +4746,12 @@ package body Bindo.Graphs is
function Number_Of_Edges_To_Successors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Natural
+ Vertex : Library_Graph_Vertex_Id) return Natural
is
begin
pragma Assert (Present (G));
- return DG.Number_Of_Outgoing_Edges (G.Graph, LGV_Id);
+ return DG.Number_Of_Outgoing_Edges (G.Graph, Vertex);
end Number_Of_Edges_To_Successors;
------------------------
@@ -2462,11 +4765,131 @@ package body Bindo.Graphs is
return DG.Number_Of_Vertices (G.Graph);
end Number_Of_Vertices;
- --------------------------
- -- Pending_Predecessors --
- --------------------------
+ -----------------
+ -- Order_Cycle --
+ -----------------
+
+ procedure Order_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id)
+ is
+ Lesser_Cycle : Library_Graph_Cycle_Id;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+ pragma Assert (LGC_Lists.Present (G.Cycles));
+
+ -- The input cycle is the first to be inserted
+
+ if LGC_Lists.Is_Empty (G.Cycles) then
+ LGC_Lists.Prepend (G.Cycles, Cycle);
+
+ -- Otherwise the list of all cycles contains at least one cycle.
+ -- Insert the input cycle based on its precedence.
+
+ else
+ Lesser_Cycle := Find_First_Lower_Precedence_Cycle (G, Cycle);
+
+ -- The list contains at least one cycle, and the input cycle has a
+ -- higher precedence compared to some cycle in the list.
+
+ if Present (Lesser_Cycle) then
+ LGC_Lists.Insert_Before
+ (L => G.Cycles,
+ Before => Lesser_Cycle,
+ Elem => Cycle);
+
+ -- Otherwise the input cycle has the lowest precedence among all
+ -- cycles.
+
+ else
+ LGC_Lists.Append (G.Cycles, Cycle);
+ end if;
+ end if;
+ end Order_Cycle;
+
+ ----------
+ -- Path --
+ ----------
+
+ function Path
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return LGE_Lists.Doubly_Linked_List
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ return Get_LGC_Attributes (G, Cycle).Path;
+ end Path;
+
+ ------------------------------------------
+ -- Pending_Predecessors_For_Elaboration --
+ ------------------------------------------
+
+ procedure Pending_Predecessors_For_Elaboration
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Strong_Preds : out Natural;
+ Weak_Preds : out Natural)
+ is
+ Complement : Library_Graph_Vertex_Id;
+ Spec_Vertex : Library_Graph_Vertex_Id;
+ Total_Strong_Preds : Natural;
+ Total_Weak_Preds : Natural;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
- function Pending_Predecessors
+ Total_Strong_Preds := Pending_Strong_Predecessors (G, Vertex);
+ Total_Weak_Preds := Pending_Weak_Predecessors (G, Vertex);
+
+ -- Assume that there is no complementary vertex that needs to be
+ -- examined.
+
+ Complement := No_Library_Graph_Vertex;
+ Spec_Vertex := No_Library_Graph_Vertex;
+
+ if Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then
+ Complement := Proper_Spec (G, Vertex);
+ Spec_Vertex := Complement;
+
+ elsif Is_Spec_With_Elaborate_Body (G, Vertex) then
+ Complement := Proper_Body (G, Vertex);
+ Spec_Vertex := Vertex;
+ end if;
+
+ -- The vertex is part of an Elaborate_Body pair. Take into account
+ -- the strong and weak predecessors of the complementary vertex.
+
+ if Present (Complement) then
+ Total_Strong_Preds :=
+ Pending_Strong_Predecessors (G, Complement) + Total_Strong_Preds;
+ Total_Weak_Preds :=
+ Pending_Weak_Predecessors (G, Complement) + Total_Weak_Preds;
+
+ -- The body of an Elaborate_Body pair is the successor of a strong
+ -- edge where the predecessor is the spec. This edge must not be
+ -- considered for elaboration purposes because the pair is treated
+ -- as one vertex. Account for the edge only when the spec has not
+ -- been elaborated yet.
+
+ if not In_Elaboration_Order (G, Spec_Vertex) then
+ Total_Strong_Preds := Total_Strong_Preds - 1;
+ end if;
+ end if;
+
+ Strong_Preds := Total_Strong_Preds;
+ Weak_Preds := Total_Weak_Preds;
+ end Pending_Predecessors_For_Elaboration;
+
+ ---------------------------------
+ -- Pending_Strong_Predecessors --
+ ---------------------------------
+
+ function Pending_Strong_Predecessors
(G : Library_Graph;
Comp : Component_Id) return Natural
is
@@ -2474,37 +4897,67 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (Comp));
- return Get_Component_Attributes (G, Comp).Pending_Predecessors;
- end Pending_Predecessors;
+ return Get_Component_Attributes (G, Comp).Pending_Strong_Predecessors;
+ end Pending_Strong_Predecessors;
- --------------------------
- -- Pending_Predecessors --
- --------------------------
+ ---------------------------------
+ -- Pending_Strong_Predecessors --
+ ---------------------------------
+
+ function Pending_Strong_Predecessors
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Natural
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ return Get_LGV_Attributes (G, Vertex).Pending_Strong_Predecessors;
+ end Pending_Strong_Predecessors;
+
+ -------------------------------
+ -- Pending_Weak_Predecessors --
+ -------------------------------
+
+ function Pending_Weak_Predecessors
+ (G : Library_Graph;
+ Comp : Component_Id) return Natural
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Comp));
+
+ return Get_Component_Attributes (G, Comp).Pending_Weak_Predecessors;
+ end Pending_Weak_Predecessors;
+
+ -------------------------------
+ -- Pending_Weak_Predecessors --
+ -------------------------------
- function Pending_Predecessors
+ function Pending_Weak_Predecessors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Natural
+ Vertex : Library_Graph_Vertex_Id) return Natural
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- return Get_LGV_Attributes (G, LGV_Id).Pending_Predecessors;
- end Pending_Predecessors;
+ return Get_LGV_Attributes (G, Vertex).Pending_Weak_Predecessors;
+ end Pending_Weak_Predecessors;
-----------------
-- Predecessor --
-----------------
function Predecessor
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Edge));
- return DG.Source_Vertex (G.Graph, LGE_Id);
+ return DG.Source_Vertex (G.Graph, Edge);
end Predecessor;
-------------
@@ -2522,23 +4975,23 @@ package body Bindo.Graphs is
function Proper_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
+ Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
-- When the vertex denotes a spec with a completing body, return the
-- body.
- if Is_Spec_With_Body (G, LGV_Id) then
- return Corresponding_Item (G, LGV_Id);
+ if Is_Spec_With_Body (G, Vertex) then
+ return Corresponding_Item (G, Vertex);
-- Otherwise the vertex must be a body
else
- pragma Assert (Is_Body (G, LGV_Id));
- return LGV_Id;
+ pragma Assert (Is_Body (G, Vertex));
+ return Vertex;
end if;
end Proper_Body;
@@ -2548,26 +5001,102 @@ package body Bindo.Graphs is
function Proper_Spec
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
+ Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
-- When the vertex denotes a body that completes a spec, return the
-- spec.
- if Is_Body_With_Spec (G, LGV_Id) then
- return Corresponding_Item (G, LGV_Id);
+ if Is_Body_With_Spec (G, Vertex) then
+ return Corresponding_Item (G, Vertex);
-- Otherwise the vertex must denote a spec
else
- pragma Assert (Is_Spec (G, LGV_Id));
- return LGV_Id;
+ pragma Assert (Is_Spec (G, Vertex));
+ return Vertex;
end if;
end Proper_Spec;
+ ------------------
+ -- Record_Cycle --
+ ------------------
+
+ procedure Record_Cycle
+ (G : Library_Graph;
+ Most_Significant_Edge : Library_Graph_Edge_Id;
+ Invocation_Edge_Count : Natural;
+ Cycle_Path : LGE_Lists.Doubly_Linked_List;
+ Indent : Indentation_Level)
+ is
+ Cycle : Library_Graph_Cycle_Id;
+ Path : LGE_Lists.Doubly_Linked_List;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Most_Significant_Edge));
+ pragma Assert (LGE_Lists.Present (Cycle_Path));
+
+ -- Replicate the path of the cycle in order to avoid sharing lists
+
+ Path := Copy_Cycle_Path (Cycle_Path);
+
+ -- Normalize the path of the cycle such that its most significant
+ -- edge is the first in the list of edges.
+
+ Normalize_Cycle_Path
+ (Cycle_Path => Path,
+ Most_Significant_Edge => Most_Significant_Edge);
+
+ -- Save the cycle for diagnostic purposes. Its kind is determined by
+ -- its most significant edge.
+
+ Cycle := Sequence_Next_Cycle;
+
+ Set_LGC_Attributes
+ (G => G,
+ Cycle => Cycle,
+ Val =>
+ (Invocation_Edge_Count => Invocation_Edge_Count,
+ Kind =>
+ Cycle_Kind_Of
+ (G => G,
+ Edge => Most_Significant_Edge),
+ Path => Path));
+
+ Trace_Cycle (G, Cycle, Indent);
+
+ -- Order the cycle based on its precedence relative to previously
+ -- discovered cycles.
+
+ Order_Cycle (G, Cycle);
+ end Record_Cycle;
+
+ -----------------------------------------
+ -- Same_Library_Graph_Cycle_Attributes --
+ -----------------------------------------
+
+ function Same_Library_Graph_Cycle_Attributes
+ (Left : Library_Graph_Cycle_Attributes;
+ Right : Library_Graph_Cycle_Attributes) return Boolean
+ is
+ begin
+ -- Two cycles are the same when
+ --
+ -- * They are of the same kind
+ -- * They have the same number of invocation edges in their paths
+ -- * Their paths are the same length
+ -- * The edges comprising their paths are the same
+
+ return
+ Left.Invocation_Edge_Count = Right.Invocation_Edge_Count
+ and then Left.Kind = Right.Kind
+ and then LGE_Lists.Equal (Left.Path, Right.Path);
+ end Same_Library_Graph_Cycle_Attributes;
+
------------------------------
-- Set_Component_Attributes --
------------------------------
@@ -2581,7 +5110,7 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (Comp));
- CA.Put (G.Component_Attributes, Comp, Val);
+ Component_Tables.Put (G.Component_Attributes, Comp, Val);
end Set_Component_Attributes;
----------------------------
@@ -2590,18 +5119,18 @@ package body Bindo.Graphs is
procedure Set_Corresponding_Item
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Val : Library_Graph_Vertex_Id)
is
Attrs : Library_Graph_Vertex_Attributes;
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- Attrs := Get_LGV_Attributes (G, LGV_Id);
+ Attrs := Get_LGV_Attributes (G, Vertex);
Attrs.Corresponding_Item := Val;
- Set_LGV_Attributes (G, LGV_Id, Attrs);
+ Set_LGV_Attributes (G, Vertex, Attrs);
end Set_Corresponding_Item;
------------------------------
@@ -2617,7 +5146,7 @@ package body Bindo.Graphs is
pragma Assert (Present (G));
pragma Assert (Present (U_Id));
- UV.Put (G.Unit_To_Vertex, U_Id, Val);
+ Unit_Tables.Put (G.Unit_To_Vertex, U_Id, Val);
end Set_Corresponding_Vertex;
------------------------------
@@ -2626,25 +5155,25 @@ package body Bindo.Graphs is
procedure Set_In_Elaboration_Order
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Val : Boolean := True)
is
Attrs : Library_Graph_Vertex_Attributes;
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- Attrs := Get_LGV_Attributes (G, LGV_Id);
+ Attrs := Get_LGV_Attributes (G, Vertex);
Attrs.In_Elaboration_Order := Val;
- Set_LGV_Attributes (G, LGV_Id, Attrs);
+ Set_LGV_Attributes (G, Vertex, Attrs);
end Set_In_Elaboration_Order;
- ----------------------------------------------------
- -- Set_Is_Existing_Predecessor_Successor_Relation --
- ----------------------------------------------------
+ --------------------------
+ -- Set_Is_Recorded_Edge --
+ --------------------------
- procedure Set_Is_Existing_Predecessor_Successor_Relation
+ procedure Set_Is_Recorded_Edge
(G : Library_Graph;
Rel : Predecessor_Successor_Relation;
Val : Boolean := True)
@@ -2655,11 +5184,27 @@ package body Bindo.Graphs is
pragma Assert (Present (Rel.Successor));
if Val then
- PS.Insert (G.Relations, Rel);
+ RE_Sets.Insert (G.Recorded_Edges, Rel);
else
- PS.Delete (G.Relations, Rel);
+ RE_Sets.Delete (G.Recorded_Edges, Rel);
end if;
- end Set_Is_Existing_Predecessor_Successor_Relation;
+ end Set_Is_Recorded_Edge;
+
+ ------------------------
+ -- Set_LGC_Attributes --
+ ------------------------
+
+ procedure Set_LGC_Attributes
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Val : Library_Graph_Cycle_Attributes)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ LGC_Tables.Put (G.Cycle_Attributes, Cycle, Val);
+ end Set_LGC_Attributes;
------------------------
-- Set_LGE_Attributes --
@@ -2667,14 +5212,14 @@ package body Bindo.Graphs is
procedure Set_LGE_Attributes
(G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id;
+ Edge : Library_Graph_Edge_Id;
Val : Library_Graph_Edge_Attributes)
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Edge));
- EA.Put (G.Edge_Attributes, LGE_Id, Val);
+ LGE_Tables.Put (G.Edge_Attributes, Edge, Val);
end Set_LGE_Attributes;
------------------------
@@ -2683,14 +5228,14 @@ package body Bindo.Graphs is
procedure Set_LGV_Attributes
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Val : Library_Graph_Vertex_Attributes)
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- VA.Put (G.Vertex_Attributes, LGV_Id, Val);
+ LGV_Tables.Put (G.Vertex_Attributes, Vertex, Val);
end Set_LGV_Attributes;
---------------
@@ -2698,31 +5243,253 @@ package body Bindo.Graphs is
---------------
function Successor
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Edge));
- return DG.Destination_Vertex (G.Graph, LGE_Id);
+ return DG.Destination_Vertex (G.Graph, Edge);
end Successor;
+ ---------------------
+ -- Trace_Component --
+ ---------------------
+
+ procedure Trace_Component
+ (G : Library_Graph;
+ Comp : Component_Id;
+ Indent : Indentation_Level)
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Comp));
+
+ -- Nothing to do when switch -d_t (output cycle-detection trace
+ -- information) is not in effect.
+
+ if not Debug_Flag_Underscore_T then
+ return;
+ end if;
+
+ Write_Eol;
+ Indent_By (Indent);
+ Write_Str ("component (Comp_");
+ Write_Int (Int (Comp));
+ Write_Str (")");
+ Write_Eol;
+ end Trace_Component;
+
+ -----------------
+ -- Trace_Cycle --
+ -----------------
+
+ procedure Trace_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id;
+ Indent : Indentation_Level)
+ is
+ Attr_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
+ Edge_Indent : constant Indentation_Level :=
+ Attr_Indent + Nested_Indentation;
+
+ Edge : Library_Graph_Edge_Id;
+ Iter : Edges_Of_Cycle_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ -- Nothing to do when switch -d_t (output cycle-detection trace
+ -- information) is not in effect.
+
+ if not Debug_Flag_Underscore_T then
+ return;
+ end if;
+
+ Indent_By (Indent);
+ Write_Str ("cycle (LGC_Id_");
+ Write_Int (Int (Cycle));
+ Write_Str (")");
+ Write_Eol;
+
+ Indent_By (Attr_Indent);
+ Write_Str ("kind = ");
+ Write_Str (Kind (G, Cycle)'Img);
+ Write_Eol;
+
+ Indent_By (Attr_Indent);
+ Write_Str ("invocation edges = ");
+ Write_Int (Int (Invocation_Edge_Count (G, Cycle)));
+ Write_Eol;
+
+ Indent_By (Attr_Indent);
+ Write_Str ("length: ");
+ Write_Int (Int (Length (G, Cycle)));
+ Write_Eol;
+
+ Iter := Iterate_Edges_Of_Cycle (G, Cycle);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ Indent_By (Edge_Indent);
+ Write_Str ("library graph edge (LGE_Id_");
+ Write_Int (Int (Edge));
+ Write_Str (")");
+ Write_Eol;
+ end loop;
+ end Trace_Cycle;
+
+ ----------------
+ -- Trace_Edge --
+ ----------------
+
+ procedure Trace_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id;
+ Indent : Indentation_Level)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ Attr_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
+
+ Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
+
+ begin
+ -- Nothing to do when switch -d_t (output cycle-detection trace
+ -- information) is not in effect.
+
+ if not Debug_Flag_Underscore_T then
+ return;
+ end if;
+
+ Indent_By (Indent);
+ Write_Str ("library graph edge (LGE_Id_");
+ Write_Int (Int (Edge));
+ Write_Str (")");
+ Write_Eol;
+
+ Indent_By (Attr_Indent);
+ Write_Str ("kind = ");
+ Write_Str (Kind (G, Edge)'Img);
+ Write_Eol;
+
+ Indent_By (Attr_Indent);
+ Write_Str ("Predecessor (LGV_Id_");
+ Write_Int (Int (Pred));
+ Write_Str (") name = ");
+ Write_Name (Name (G, Pred));
+ Write_Eol;
+
+ Indent_By (Attr_Indent);
+ Write_Str ("Successor (LGV_Id_");
+ Write_Int (Int (Succ));
+ Write_Str (") name = ");
+ Write_Name (Name (G, Succ));
+ Write_Eol;
+ end Trace_Edge;
+
+ ------------------
+ -- Trace_Vertex --
+ ------------------
+
+ procedure Trace_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Indent : Indentation_Level)
+ is
+ Attr_Indent : constant Indentation_Level :=
+ Indent + Nested_Indentation;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ -- Nothing to do when switch -d_t (output cycle-detection trace
+ -- information) is not in effect.
+
+ if not Debug_Flag_Underscore_T then
+ return;
+ end if;
+
+ Indent_By (Indent);
+ Write_Str ("library graph vertex (LGV_Id_");
+ Write_Int (Int (Vertex));
+ Write_Str (")");
+ Write_Eol;
+
+ Indent_By (Attr_Indent);
+ Write_Str ("Unit (U_Id_");
+ Write_Int (Int (Unit (G, Vertex)));
+ Write_Str (") name = ");
+ Write_Name (Name (G, Vertex));
+ Write_Eol;
+ end Trace_Vertex;
+
----------
-- Unit --
----------
function Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Unit_Id
+ Vertex : Library_Graph_Vertex_Id) return Unit_Id
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
- return Get_LGV_Attributes (G, LGV_Id).Unit;
+ return Get_LGV_Attributes (G, Vertex).Unit;
end Unit;
+ -------------
+ -- Unvisit --
+ -------------
+
+ procedure Unvisit
+ (Vertex : Library_Graph_Vertex_Id;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List)
+ is
+ Current_Vertex : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (Vertex));
+ pragma Assert (LGV_Sets.Present (Visited_Set));
+ pragma Assert (LGV_Lists.Present (Visited_Stack));
+
+ while not LGV_Lists.Is_Empty (Visited_Stack) loop
+ Current_Vertex := LGV_Lists.First (Visited_Stack);
+
+ LGV_Lists.Delete_First (Visited_Stack);
+ LGV_Sets.Delete (Visited_Set, Current_Vertex);
+
+ exit when Current_Vertex = Vertex;
+ end loop;
+ end Unvisit;
+
+ ---------------------------------
+ -- Update_Pending_Predecessors --
+ ---------------------------------
+
+ procedure Update_Pending_Predecessors
+ (Strong_Predecessors : in out Natural;
+ Weak_Predecessors : in out Natural;
+ Update_Weak : Boolean;
+ Value : Integer)
+ is
+ begin
+ if Update_Weak then
+ Weak_Predecessors := Weak_Predecessors + Value;
+ else
+ Strong_Predecessors := Strong_Predecessors + Value;
+ end if;
+ end Update_Pending_Predecessors;
+
-----------------------------------------------
-- Update_Pending_Predecessors_Of_Components --
-----------------------------------------------
@@ -2730,18 +5497,17 @@ package body Bindo.Graphs is
procedure Update_Pending_Predecessors_Of_Components
(G : Library_Graph)
is
- Iter : All_Edge_Iterator;
- LGE_Id : Library_Graph_Edge_Id;
+ Edge : Library_Graph_Edge_Id;
+ Iter : All_Edge_Iterator;
begin
pragma Assert (Present (G));
Iter := Iterate_All_Edges (G);
while Has_Next (Iter) loop
- Next (Iter, LGE_Id);
- pragma Assert (Present (LGE_Id));
+ Next (Iter, Edge);
- Update_Pending_Predecessors_Of_Components (G, LGE_Id);
+ Update_Pending_Predecessors_Of_Components (G, Edge);
end loop;
end Update_Pending_Predecessors_Of_Components;
@@ -2750,20 +5516,16 @@ package body Bindo.Graphs is
-----------------------------------------------
procedure Update_Pending_Predecessors_Of_Components
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id)
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id)
is
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
+ pragma Assert (Present (Edge));
- Pred : constant Library_Graph_Vertex_Id := Predecessor (G, LGE_Id);
- Succ : constant Library_Graph_Vertex_Id := Successor (G, LGE_Id);
-
- pragma Assert (Present (Pred));
- pragma Assert (Present (Succ));
-
- Pred_Comp : constant Component_Id := Component (G, Pred);
- Succ_Comp : constant Component_Id := Component (G, Succ);
+ Pred_Comp : constant Component_Id :=
+ Component (G, Predecessor (G, Edge));
+ Succ_Comp : constant Component_Id :=
+ Component (G, Successor (G, Edge));
pragma Assert (Present (Pred_Comp));
pragma Assert (Present (Succ_Comp));
@@ -2774,113 +5536,179 @@ package body Bindo.Graphs is
-- must wait on another predecessor until it can be elaborated.
if Pred_Comp /= Succ_Comp then
- Increment_Pending_Predecessors (G, Succ_Comp);
+ Increment_Pending_Predecessors
+ (G => G,
+ Comp => Succ_Comp,
+ Edge => Edge);
end if;
end Update_Pending_Predecessors_Of_Components;
+
+ -----------------------
+ -- Vertex_Precedence --
+ -----------------------
+
+ function Vertex_Precedence
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind
+ is
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+ pragma Assert (Present (Compared_To));
+
+ -- Use lexicographical order to determine precedence and ensure
+ -- deterministic behavior.
+
+ if Uname_Less (Name (G, Vertex), Name (G, Compared_To)) then
+ return Higher_Precedence;
+ else
+ return Lower_Precedence;
+ end if;
+ end Vertex_Precedence;
+
+ -----------
+ -- Visit --
+ -----------
+
+ procedure Visit
+ (Vertex : Library_Graph_Vertex_Id;
+ Visited_Set : LGV_Sets.Membership_Set;
+ Visited_Stack : LGV_Lists.Doubly_Linked_List)
+ is
+ begin
+ pragma Assert (Present (Vertex));
+ pragma Assert (LGV_Sets.Present (Visited_Set));
+ pragma Assert (LGV_Lists.Present (Visited_Stack));
+
+ LGV_Sets.Insert (Visited_Set, Vertex);
+ LGV_Lists.Prepend (Visited_Stack, Vertex);
+ end Visit;
end Library_Graphs;
-------------
-- Present --
-------------
- function Present (IGE_Id : Invocation_Graph_Edge_Id) return Boolean is
+ function Present (Edge : Invocation_Graph_Edge_Id) return Boolean is
begin
- return IGE_Id /= No_Invocation_Graph_Edge;
+ return Edge /= No_Invocation_Graph_Edge;
end Present;
-------------
-- Present --
-------------
- function Present (IGV_Id : Invocation_Graph_Vertex_Id) return Boolean is
+ function Present (Vertex : Invocation_Graph_Vertex_Id) return Boolean is
begin
- return IGV_Id /= No_Invocation_Graph_Vertex;
+ return Vertex /= No_Invocation_Graph_Vertex;
end Present;
-------------
-- Present --
-------------
- function Present (LGE_Id : Library_Graph_Edge_Id) return Boolean is
+ function Present (Cycle : Library_Graph_Cycle_Id) return Boolean is
begin
- return LGE_Id /= No_Library_Graph_Edge;
+ return Cycle /= No_Library_Graph_Cycle;
end Present;
-------------
-- Present --
-------------
- function Present (LGV_Id : Library_Graph_Vertex_Id) return Boolean is
+ function Present (Edge : Library_Graph_Edge_Id) return Boolean is
begin
- return LGV_Id /= No_Library_Graph_Vertex;
+ return Edge /= No_Library_Graph_Edge;
+ end Present;
+
+ -------------
+ -- Present --
+ -------------
+
+ function Present (Vertex : Library_Graph_Vertex_Id) return Boolean is
+ begin
+ return Vertex /= No_Library_Graph_Vertex;
end Present;
--------------------------
- -- Sequence_Next_IGE_Id --
+ -- Sequence_Next_Edge --
--------------------------
IGE_Sequencer : Invocation_Graph_Edge_Id := First_Invocation_Graph_Edge;
-- The counter for invocation graph edges. Do not directly manipulate its
-- value.
- function Sequence_Next_IGE_Id return Invocation_Graph_Edge_Id is
- IGE_Id : constant Invocation_Graph_Edge_Id := IGE_Sequencer;
+ function Sequence_Next_Edge return Invocation_Graph_Edge_Id is
+ Edge : constant Invocation_Graph_Edge_Id := IGE_Sequencer;
begin
IGE_Sequencer := IGE_Sequencer + 1;
- return IGE_Id;
- end Sequence_Next_IGE_Id;
+ return Edge;
+ end Sequence_Next_Edge;
--------------------------
- -- Sequence_Next_IGV_Id --
+ -- Sequence_Next_Vertex --
--------------------------
IGV_Sequencer : Invocation_Graph_Vertex_Id := First_Invocation_Graph_Vertex;
-- The counter for invocation graph vertices. Do not directly manipulate
-- its value.
+ function Sequence_Next_Vertex return Invocation_Graph_Vertex_Id is
+ Vertex : constant Invocation_Graph_Vertex_Id := IGV_Sequencer;
+
+ begin
+ IGV_Sequencer := IGV_Sequencer + 1;
+ return Vertex;
+ end Sequence_Next_Vertex;
+
--------------------------
- -- Sequence_Next_IGV_Id --
+ -- Sequence_Next_Cycle --
--------------------------
- function Sequence_Next_IGV_Id return Invocation_Graph_Vertex_Id is
- IGV_Id : constant Invocation_Graph_Vertex_Id := IGV_Sequencer;
+ LGC_Sequencer : Library_Graph_Cycle_Id := First_Library_Graph_Cycle;
+ -- The counter for library graph cycles. Do not directly manipulate its
+ -- value.
+
+ function Sequence_Next_Cycle return Library_Graph_Cycle_Id is
+ Cycle : constant Library_Graph_Cycle_Id := LGC_Sequencer;
begin
- IGV_Sequencer := IGV_Sequencer + 1;
- return IGV_Id;
- end Sequence_Next_IGV_Id;
+ LGC_Sequencer := LGC_Sequencer + 1;
+ return Cycle;
+ end Sequence_Next_Cycle;
--------------------------
- -- Sequence_Next_LGE_Id --
+ -- Sequence_Next_Edge --
--------------------------
LGE_Sequencer : Library_Graph_Edge_Id := First_Library_Graph_Edge;
-- The counter for library graph edges. Do not directly manipulate its
-- value.
- function Sequence_Next_LGE_Id return Library_Graph_Edge_Id is
- LGE_Id : constant Library_Graph_Edge_Id := LGE_Sequencer;
+ function Sequence_Next_Edge return Library_Graph_Edge_Id is
+ Edge : constant Library_Graph_Edge_Id := LGE_Sequencer;
begin
LGE_Sequencer := LGE_Sequencer + 1;
- return LGE_Id;
- end Sequence_Next_LGE_Id;
+ return Edge;
+ end Sequence_Next_Edge;
--------------------------
- -- Sequence_Next_LGV_Id --
+ -- Sequence_Next_Vertex --
--------------------------
LGV_Sequencer : Library_Graph_Vertex_Id := First_Library_Graph_Vertex;
-- The counter for library graph vertices. Do not directly manipulate its
-- value.
- function Sequence_Next_LGV_Id return Library_Graph_Vertex_Id is
- LGV_Id : constant Library_Graph_Vertex_Id := LGV_Sequencer;
+ function Sequence_Next_Vertex return Library_Graph_Vertex_Id is
+ Vertex : constant Library_Graph_Vertex_Id := LGV_Sequencer;
begin
LGV_Sequencer := LGV_Sequencer + 1;
- return LGV_Id;
- end Sequence_Next_LGV_Id;
+ return Vertex;
+ end Sequence_Next_Vertex;
end Bindo.Graphs;
diff --git a/gcc/ada/bindo-graphs.ads b/gcc/ada/bindo-graphs.ads
index a5dc6ea..f376801 100644
--- a/gcc/ada/bindo-graphs.ads
+++ b/gcc/ada/bindo-graphs.ads
@@ -28,11 +28,14 @@
-- The following unit defines the various graphs used in determining the
-- elaboration order of units.
+with Types; use Types;
+
with Bindo.Units; use Bindo.Units;
with GNAT; use GNAT;
with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
with GNAT.Graphs; use GNAT.Graphs;
+with GNAT.Lists; use GNAT.Lists;
with GNAT.Sets; use GNAT.Sets;
package Bindo.Graphs is
@@ -49,14 +52,24 @@ package Bindo.Graphs is
First_Invocation_Graph_Edge : constant Invocation_Graph_Edge_Id :=
No_Invocation_Graph_Edge + 1;
+ procedure Destroy_Invocation_Graph_Edge
+ (Edge : in out Invocation_Graph_Edge_Id);
+ pragma Inline (Destroy_Invocation_Graph_Edge);
+ -- Destroy invocation graph edge Edge
+
function Hash_Invocation_Graph_Edge
- (IGE_Id : Invocation_Graph_Edge_Id) return Bucket_Range_Type;
+ (Edge : Invocation_Graph_Edge_Id) return Bucket_Range_Type;
pragma Inline (Hash_Invocation_Graph_Edge);
- -- Obtain the hash value of key IGE_Id
+ -- Obtain the hash value of key Edge
- function Present (IGE_Id : Invocation_Graph_Edge_Id) return Boolean;
+ function Present (Edge : Invocation_Graph_Edge_Id) return Boolean;
pragma Inline (Present);
- -- Determine whether invocation graph edge IGE_Id exists
+ -- Determine whether invocation graph edge Edge exists
+
+ package IGE_Lists is new Doubly_Linked_Lists
+ (Element_Type => Invocation_Graph_Edge_Id,
+ "=" => "=",
+ Destroy_Element => Destroy_Invocation_Graph_Edge);
------------------------------
-- Invocation graph vertex --
@@ -71,13 +84,47 @@ package Bindo.Graphs is
No_Invocation_Graph_Vertex + 1;
function Hash_Invocation_Graph_Vertex
- (IGV_Id : Invocation_Graph_Vertex_Id) return Bucket_Range_Type;
+ (Vertex : Invocation_Graph_Vertex_Id) return Bucket_Range_Type;
pragma Inline (Hash_Invocation_Graph_Vertex);
- -- Obtain the hash value of key IGV_Id
+ -- Obtain the hash value of key Vertex
- function Present (IGV_Id : Invocation_Graph_Vertex_Id) return Boolean;
+ function Present (Vertex : Invocation_Graph_Vertex_Id) return Boolean;
pragma Inline (Present);
- -- Determine whether invocation graph vertex IGV_Id exists
+ -- Determine whether invocation graph vertex Vertex exists
+
+ package IGV_Sets is new Membership_Sets
+ (Element_Type => Invocation_Graph_Vertex_Id,
+ "=" => "=",
+ Hash => Hash_Invocation_Graph_Vertex);
+
+ -------------------------
+ -- Library graph cycle --
+ -------------------------
+
+ type Library_Graph_Cycle_Id is new Natural;
+ No_Library_Graph_Cycle : constant Library_Graph_Cycle_Id :=
+ Library_Graph_Cycle_Id'First;
+ First_Library_Graph_Cycle : constant Library_Graph_Cycle_Id :=
+ No_Library_Graph_Cycle + 1;
+
+ procedure Destroy_Library_Graph_Cycle
+ (Cycle : in out Library_Graph_Cycle_Id);
+ pragma Inline (Destroy_Library_Graph_Cycle);
+ -- Destroy library graph cycle Cycle
+
+ function Hash_Library_Graph_Cycle
+ (Cycle : Library_Graph_Cycle_Id) return Bucket_Range_Type;
+ pragma Inline (Hash_Library_Graph_Cycle);
+ -- Obtain the hash value of key Cycle
+
+ function Present (Cycle : Library_Graph_Cycle_Id) return Boolean;
+ pragma Inline (Present);
+ -- Determine whether library graph cycle Cycle exists
+
+ package LGC_Lists is new Doubly_Linked_Lists
+ (Element_Type => Library_Graph_Cycle_Id,
+ "=" => "=",
+ Destroy_Element => Destroy_Library_Graph_Cycle);
------------------------
-- Library graph edge --
@@ -91,14 +138,29 @@ package Bindo.Graphs is
First_Library_Graph_Edge : constant Library_Graph_Edge_Id :=
No_Library_Graph_Edge + 1;
+ procedure Destroy_Library_Graph_Edge
+ (Edge : in out Library_Graph_Edge_Id);
+ pragma Inline (Destroy_Library_Graph_Edge);
+ -- Destroy library graph edge Edge
+
function Hash_Library_Graph_Edge
- (LGE_Id : Library_Graph_Edge_Id) return Bucket_Range_Type;
+ (Edge : Library_Graph_Edge_Id) return Bucket_Range_Type;
pragma Inline (Hash_Library_Graph_Edge);
- -- Obtain the hash value of key LGE_Id
+ -- Obtain the hash value of key Edge
- function Present (LGE_Id : Library_Graph_Edge_Id) return Boolean;
+ function Present (Edge : Library_Graph_Edge_Id) return Boolean;
pragma Inline (Present);
- -- Determine whether library graph edge LGE_Id exists
+ -- Determine whether library graph edge Edge exists
+
+ package LGE_Lists is new Doubly_Linked_Lists
+ (Element_Type => Library_Graph_Edge_Id,
+ "=" => "=",
+ Destroy_Element => Destroy_Library_Graph_Edge);
+
+ package LGE_Sets is new Membership_Sets
+ (Element_Type => Library_Graph_Edge_Id,
+ "=" => "=",
+ Hash => Hash_Library_Graph_Edge);
--------------------------
-- Library graph vertex --
@@ -112,14 +174,29 @@ package Bindo.Graphs is
First_Library_Graph_Vertex : constant Library_Graph_Vertex_Id :=
No_Library_Graph_Vertex + 1;
+ procedure Destroy_Library_Graph_Vertex
+ (Vertex : in out Library_Graph_Vertex_Id);
+ pragma Inline (Destroy_Library_Graph_Vertex);
+ -- Destroy library graph vertex Vertex
+
function Hash_Library_Graph_Vertex
- (LGV_Id : Library_Graph_Vertex_Id) return Bucket_Range_Type;
+ (Vertex : Library_Graph_Vertex_Id) return Bucket_Range_Type;
pragma Inline (Hash_Library_Graph_Vertex);
- -- Obtain the hash value of key LGV_Id
+ -- Obtain the hash value of key Vertex
- function Present (LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ function Present (Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Present);
- -- Determine whether library graph vertex LGV_Id exists
+ -- Determine whether library graph vertex Vertex exists
+
+ package LGV_Lists is new Doubly_Linked_Lists
+ (Element_Type => Library_Graph_Vertex_Id,
+ "=" => "=",
+ Destroy_Element => Destroy_Library_Graph_Vertex);
+
+ package LGV_Sets is new Membership_Sets
+ (Element_Type => Library_Graph_Vertex_Id,
+ "=" => "=",
+ Hash => Hash_Library_Graph_Vertex);
-----------------------
-- Invocation_Graphs --
@@ -152,13 +229,16 @@ package Bindo.Graphs is
-- describes.
procedure Add_Vertex
- (G : Invocation_Graph;
- IC_Id : Invocation_Construct_Id;
- LGV_Id : Library_Graph_Vertex_Id);
+ (G : Invocation_Graph;
+ IC_Id : Invocation_Construct_Id;
+ Body_Vertex : Library_Graph_Vertex_Id;
+ Spec_Vertex : Library_Graph_Vertex_Id);
pragma Inline (Add_Vertex);
-- Create a new vertex in invocation graph G. IC_Id is the invocation
- -- construct the vertex describes. LGV_Id is the library graph vertex
- -- where the invocation construct appears.
+ -- construct the vertex describes. Body_Vertex denotes the library graph
+ -- vertex where the invocation construct's body is declared. Spec_Vertex
+ -- is the library graph vertex where the invocation construct's spec is
+ -- declared.
function Create
(Initial_Vertices : Positive;
@@ -179,11 +259,26 @@ package Bindo.Graphs is
-- Vertex attributes --
-----------------------
+ function Body_Vertex
+ (G : Invocation_Graph;
+ Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
+ pragma Inline (Body_Vertex);
+ -- Obtain the library graph vertex where the body of the invocation
+ -- construct represented by vertex Vertex of invocation graph G is
+ -- declared.
+
+ function Column
+ (G : Invocation_Graph;
+ Vertex : Invocation_Graph_Vertex_Id) return Nat;
+ pragma Inline (Column);
+ -- Obtain the column number where the invocation construct vertex Vertex
+ -- of invocation graph G describes.
+
function Construct
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Invocation_Construct_Id;
+ Vertex : Invocation_Graph_Vertex_Id) return Invocation_Construct_Id;
pragma Inline (Construct);
- -- Obtain the invocation construct vertex IGV_Id of invocation graph G
+ -- Obtain the invocation construct vertex Vertex of invocation graph G
-- describes.
function Corresponding_Vertex
@@ -193,41 +288,56 @@ package Bindo.Graphs is
-- Obtain the vertex of invocation graph G that corresponds to signature
-- IS_Id.
- function Lib_Vertex
+ function Line
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
- pragma Inline (Lib_Vertex);
- -- Obtain the library graph vertex where vertex IGV_Id of invocation
- -- graph appears.
+ Vertex : Invocation_Graph_Vertex_Id) return Nat;
+ pragma Inline (Line);
+ -- Obtain the line number where the invocation construct vertex Vertex
+ -- of invocation graph G describes.
function Name
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Name_Id;
+ Vertex : Invocation_Graph_Vertex_Id) return Name_Id;
pragma Inline (Name);
- -- Obtain the name of the construct vertex IGV_Id of invocation graph G
+ -- Obtain the name of the construct vertex Vertex of invocation graph G
-- describes.
+ function Spec_Vertex
+ (G : Invocation_Graph;
+ Vertex : Invocation_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
+ pragma Inline (Spec_Vertex);
+ -- Obtain the library graph vertex where the spec of the invocation
+ -- construct represented by vertex Vertex of invocation graph G is
+ -- declared.
+
---------------------
-- Edge attributes --
---------------------
+ function Extra
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) return Name_Id;
+ pragma Inline (Extra);
+ -- Obtain the extra name used in error diagnostics of edge Edge of
+ -- invocation graph G.
+
function Kind
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id) return Invocation_Kind;
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) return Invocation_Kind;
pragma Inline (Kind);
- -- Obtain the nature of edge IGE_Id of invocation graph G
+ -- Obtain the nature of edge Edge of invocation graph G
function Relation
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id) return Invocation_Relation_Id;
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) return Invocation_Relation_Id;
pragma Inline (Relation);
- -- Obtain the relation edge IGE_Id of invocation graph G describes
+ -- Obtain the relation edge Edge of invocation graph G describes
function Target
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id) return Invocation_Graph_Vertex_Id;
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) return Invocation_Graph_Vertex_Id;
pragma Inline (Target);
- -- Obtain the target vertex edge IGE_Id of invocation graph G designates
+ -- Obtain the target vertex edge Edge of invocation graph G designates
----------------
-- Statistics --
@@ -245,9 +355,9 @@ package Bindo.Graphs is
function Number_Of_Edges_To_Targets
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Natural;
+ Vertex : Invocation_Graph_Vertex_Id) return Natural;
pragma Inline (Number_Of_Edges_To_Targets);
- -- Obtain the total number of edges to targets vertex IGV_Id of
+ -- Obtain the total number of edges to targets vertex Vertex of
-- invocation graph G has.
function Number_Of_Elaboration_Roots
@@ -278,8 +388,8 @@ package Bindo.Graphs is
-- Obtain an iterator over all edges of invocation graph G
procedure Next
- (Iter : in out All_Edge_Iterator;
- IGE_Id : out Invocation_Graph_Edge_Id);
+ (Iter : in out All_Edge_Iterator;
+ Edge : out Invocation_Graph_Edge_Id);
pragma Inline (Next);
-- Return the current edge referenced by iterator Iter and advance to
-- the next available edge.
@@ -300,7 +410,7 @@ package Bindo.Graphs is
procedure Next
(Iter : in out All_Vertex_Iterator;
- IGV_Id : out Invocation_Graph_Vertex_Id);
+ Vertex : out Invocation_Graph_Vertex_Id);
pragma Inline (Next);
-- Return the current vertex referenced by iterator Iter and advance
-- to the next available vertex.
@@ -316,14 +426,14 @@ package Bindo.Graphs is
function Iterate_Edges_To_Targets
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id) return Edges_To_Targets_Iterator;
+ Vertex : Invocation_Graph_Vertex_Id) return Edges_To_Targets_Iterator;
pragma Inline (Iterate_Edges_To_Targets);
-- Obtain an iterator over all edges to targets with source vertex
- -- IGV_Id of invocation graph G.
+ -- Vertex of invocation graph G.
procedure Next
- (Iter : in out Edges_To_Targets_Iterator;
- IGE_Id : out Invocation_Graph_Edge_Id);
+ (Iter : in out Edges_To_Targets_Iterator;
+ Edge : out Invocation_Graph_Edge_Id);
pragma Inline (Next);
-- Return the current edge referenced by iterator Iter and advance to
-- the next available edge.
@@ -357,32 +467,38 @@ package Bindo.Graphs is
--------------
procedure Destroy_Invocation_Graph_Vertex
- (IGV_Id : in out Invocation_Graph_Vertex_Id);
+ (Vertex : in out Invocation_Graph_Vertex_Id);
pragma Inline (Destroy_Invocation_Graph_Vertex);
- -- Destroy invocation graph vertex IGV_Id
+ -- Destroy invocation graph vertex Vertex
-- The following type represents the attributes of an invocation graph
-- vertex.
type Invocation_Graph_Vertex_Attributes is record
+ Body_Vertex : Library_Graph_Vertex_Id := No_Library_Graph_Vertex;
+ -- Reference to the library graph vertex where the body of this
+ -- vertex resides.
+
Construct : Invocation_Construct_Id := No_Invocation_Construct;
-- Reference to the invocation construct this vertex represents
- Lib_Vertex : Library_Graph_Vertex_Id := No_Library_Graph_Vertex;
- -- Reference to the library graph vertex where this vertex resides
+ Spec_Vertex : Library_Graph_Vertex_Id := No_Library_Graph_Vertex;
+ -- Reference to the library graph vertex where the spec of this
+ -- vertex resides.
end record;
No_Invocation_Graph_Vertex_Attributes :
constant Invocation_Graph_Vertex_Attributes :=
- (Construct => No_Invocation_Construct,
- Lib_Vertex => No_Library_Graph_Vertex);
+ (Body_Vertex => No_Library_Graph_Vertex,
+ Construct => No_Invocation_Construct,
+ Spec_Vertex => No_Library_Graph_Vertex);
procedure Destroy_Invocation_Graph_Vertex_Attributes
(Attrs : in out Invocation_Graph_Vertex_Attributes);
pragma Inline (Destroy_Invocation_Graph_Vertex_Attributes);
-- Destroy the contents of attributes Attrs
- package VA is new Dynamic_Hash_Tables
+ package IGV_Tables is new Dynamic_Hash_Tables
(Key_Type => Invocation_Graph_Vertex_Id,
Value_Type => Invocation_Graph_Vertex_Attributes,
No_Value => No_Invocation_Graph_Vertex_Attributes,
@@ -399,9 +515,9 @@ package Bindo.Graphs is
-----------
procedure Destroy_Invocation_Graph_Edge
- (IGE_Id : in out Invocation_Graph_Edge_Id);
+ (Edge : in out Invocation_Graph_Edge_Id);
pragma Inline (Destroy_Invocation_Graph_Edge);
- -- Destroy invocation graph edge IGE_Id
+ -- Destroy invocation graph edge Edge
-- The following type represents the attributes of an invocation graph
-- edge.
@@ -420,7 +536,7 @@ package Bindo.Graphs is
pragma Inline (Destroy_Invocation_Graph_Edge_Attributes);
-- Destroy the contents of attributes Attrs
- package EA is new Dynamic_Hash_Tables
+ package IGE_Tables is new Dynamic_Hash_Tables
(Key_Type => Invocation_Graph_Edge_Id,
Value_Type => Invocation_Graph_Edge_Attributes,
No_Value => No_Invocation_Graph_Edge_Attributes,
@@ -457,7 +573,7 @@ package Bindo.Graphs is
pragma Inline (Hash_Source_Target_Relation);
-- Obtain the hash value of key Rel
- package ST is new Membership_Sets
+ package Relation_Sets is new Membership_Sets
(Element_Type => Source_Target_Relation,
"=" => "=",
Hash => Hash_Source_Target_Relation);
@@ -477,7 +593,7 @@ package Bindo.Graphs is
pragma Inline (Hash_Invocation_Signature);
-- Obtain the hash value of key IS_Id
- package SV is new Dynamic_Hash_Tables
+ package Signature_Tables is new Dynamic_Hash_Tables
(Key_Type => Invocation_Signature_Id,
Value_Type => Invocation_Graph_Vertex_Id,
No_Value => No_Invocation_Graph_Vertex,
@@ -493,7 +609,7 @@ package Bindo.Graphs is
-- Elaboration roots --
-----------------------
- package ER is new Membership_Sets
+ package IGV_Sets is new Membership_Sets
(Element_Type => Invocation_Graph_Vertex_Id,
"=" => "=",
Hash => Hash_Invocation_Graph_Vertex);
@@ -518,24 +634,25 @@ package Bindo.Graphs is
Counts : Invocation_Graph_Edge_Counts := (others => 0);
-- Edge statistics
- Edge_Attributes : EA.Dynamic_Hash_Table := EA.Nil;
+ Edge_Attributes : IGE_Tables.Dynamic_Hash_Table := IGE_Tables.Nil;
-- The map of edge -> edge attributes for all edges in the graph
Graph : DG.Directed_Graph := DG.Nil;
-- The underlying graph describing the relations between edges and
-- vertices.
- Relations : ST.Membership_Set := ST.Nil;
+ Relations : Relation_Sets.Membership_Set := Relation_Sets.Nil;
-- The set of relations between source and targets, used to prevent
-- duplicate edges in the graph.
- Roots : ER.Membership_Set := ER.Nil;
+ Roots : IGV_Sets.Membership_Set := IGV_Sets.Nil;
-- The set of elaboration root vertices
- Signature_To_Vertex : SV.Dynamic_Hash_Table := SV.Nil;
+ Signature_To_Vertex : Signature_Tables.Dynamic_Hash_Table :=
+ Signature_Tables.Nil;
-- The map of signature -> vertex
- Vertex_Attributes : VA.Dynamic_Hash_Table := VA.Nil;
+ Vertex_Attributes : IGV_Tables.Dynamic_Hash_Table := IGV_Tables.Nil;
-- The map of vertex -> vertex attributes for all vertices in the
-- graph.
end record;
@@ -550,7 +667,7 @@ package Bindo.Graphs is
type All_Edge_Iterator is new DG.All_Edge_Iterator;
type All_Vertex_Iterator is new DG.All_Vertex_Iterator;
type Edges_To_Targets_Iterator is new DG.Outgoing_Edge_Iterator;
- type Elaboration_Root_Iterator is new ER.Iterator;
+ type Elaboration_Root_Iterator is new IGV_Sets.Iterator;
end Invocation_Graphs;
--------------------
@@ -559,6 +676,32 @@ package Bindo.Graphs is
package Library_Graphs is
+ -- The following type represents the various kinds of library graph
+ -- cycles. The ordering of kinds is significant, where a literal with
+ -- lower ordinal has a higher precedence than one with higher ordinal.
+
+ type Library_Graph_Cycle_Kind is
+ (Elaborate_Body_Cycle,
+ -- A cycle that involves at least one spec-body pair, where the
+ -- spec is subject to pragma Elaborate_Body. This is the highest
+ -- precedence cycle.
+
+ Elaborate_Cycle,
+ -- A cycle that involves at least one Elaborate edge
+
+ Elaborate_All_Cycle,
+ -- A cycle that involves at least one Elaborate_All edge
+
+ Forced_Cycle,
+ -- A cycle that involves at least one edge which is a byproduct of
+ -- the forced-elaboration-order file.
+
+ Invocation_Cycle,
+ -- A cycle that involves at least one invocation edge. This is the
+ -- lowest precedence cycle.
+
+ No_Cycle_Kind);
+
-- The following type represents the various kinds of library edges
type Library_Graph_Edge_Kind is
@@ -599,18 +742,33 @@ package Bindo.Graphs is
type Library_Graph is private;
Nil : constant Library_Graph;
+ type LGE_Predicate_Ptr is access function
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+
+ type LGV_Comparator_Ptr is access function
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind;
+
+ type LGV_Predicate_Ptr is access function
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+
----------------------
-- Graph operations --
----------------------
procedure Add_Edge
- (G : Library_Graph;
- Pred : Library_Graph_Vertex_Id;
- Succ : Library_Graph_Vertex_Id;
- Kind : Library_Graph_Edge_Kind);
+ (G : Library_Graph;
+ Pred : Library_Graph_Vertex_Id;
+ Succ : Library_Graph_Vertex_Id;
+ Kind : Library_Graph_Edge_Kind;
+ Activates_Task : Boolean);
pragma Inline (Add_Edge);
-- Create a new edge in library graph G with source vertex Pred and
- -- destination vertex Succ. Kind denotes the nature of the edge.
+ -- destination vertex Succ. Kind denotes the nature of the edge. Flag
+ -- Activates_Task should be set when the edge involves task activation.
procedure Add_Vertex
(G : Library_Graph;
@@ -634,6 +792,16 @@ package Bindo.Graphs is
pragma Inline (Find_Components);
-- Find all components in library graph G
+ procedure Find_Cycles (G : Library_Graph);
+ pragma Inline (Find_Cycles);
+ -- Find all cycles in library graph G
+
+ function Highest_Precedence_Cycle
+ (G : Library_Graph) return Library_Graph_Cycle_Id;
+ pragma Inline (Highest_Precedence_Cycle);
+ -- Obtain the cycle with highest precedence among all other cycles of
+ -- library graph G.
+
function Present (G : Library_Graph) return Boolean;
pragma Inline (Present);
-- Determine whether library graph G exists
@@ -644,16 +812,16 @@ package Bindo.Graphs is
function Component
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Component_Id;
+ Vertex : Library_Graph_Vertex_Id) return Component_Id;
pragma Inline (Component);
- -- Obtain the component where vertex LGV_Id of library graph G resides
+ -- Obtain the component where vertex Vertex of library graph G resides
function Corresponding_Item
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
pragma Inline (Corresponding_Item);
-- Obtain the complementary vertex which represents the corresponding
- -- spec or body of vertex LGV_Id of library graph G.
+ -- spec or body of vertex Vertex of library graph G.
function Corresponding_Vertex
(G : Library_Graph;
@@ -664,75 +832,117 @@ package Bindo.Graphs is
procedure Decrement_Pending_Predecessors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id);
+ Vertex : Library_Graph_Vertex_Id;
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Decrement_Pending_Predecessors);
- -- Decrease the number of pending predecessors vertex LGV_Id of library
- -- graph G must wait on until it can be elaborated.
+ -- Decrease the number of pending predecessors vertex Vertex which was
+ -- reached via edge Edge of library graph G must wait until it can be
+ -- elaborated.
+
+ function File_Name
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return File_Name_Type;
+ pragma Inline (File_Name);
+ -- Obtain the name of the file where vertex Vertex of library graph G
+ -- resides.
function In_Elaboration_Order
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (In_Elaboration_Order);
- -- Determine whether vertex LGV_Id of library graph G is already in some
+ -- Determine whether vertex Vertex of library graph G is already in some
-- elaboration order.
+ function Invocation_Graph_Encoding
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id)
+ return Invocation_Graph_Encoding_Kind;
+ pragma Inline (Invocation_Graph_Encoding);
+ -- Obtain the encoding format used to capture information related to
+ -- invocation vertices and edges that reside within vertex Vertex of
+ -- library graph G.
+
function Name
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Unit_Name_Type;
+ Vertex : Library_Graph_Vertex_Id) return Unit_Name_Type;
pragma Inline (Name);
- -- Obtain the name of the unit which vertex LGV_Id of library graph G
+ -- Obtain the name of the unit which vertex Vertex of library graph G
-- represents.
- function Pending_Predecessors
+ procedure Pending_Predecessors_For_Elaboration
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Strong_Preds : out Natural;
+ Weak_Preds : out Natural);
+ pragma Inline (Pending_Predecessors_For_Elaboration);
+ -- Obtain the number of pending strong and weak predecessors of vertex
+ -- Vertex of library graph G, taking into account Elaborate_Body pairs.
+ -- Strong predecessors are returned in Strong_Preds. Weak predecessors
+ -- are returned in Weak_Preds.
+
+ function Pending_Strong_Predecessors
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Natural;
+ pragma Inline (Pending_Strong_Predecessors);
+ -- Obtain the number of pending strong predecessors vertex Vertex of
+ -- library graph G must wait on until it can be elaborated.
+
+ function Pending_Weak_Predecessors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Natural;
- pragma Inline (Pending_Predecessors);
- -- Obtain the number of pending predecessors vertex LGV_Id of library
- -- graph G must wait on until it can be elaborated.
+ Vertex : Library_Graph_Vertex_Id) return Natural;
+ pragma Inline (Pending_Weak_Predecessors);
+ -- Obtain the number of pending weak predecessors vertex Vertex of
+ -- library graph G must wait on until it can be elaborated.
procedure Set_Corresponding_Item
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Val : Library_Graph_Vertex_Id);
pragma Inline (Set_Corresponding_Item);
-- Set the complementary vertex which represents the corresponding
- -- spec or body of vertex LGV_Id of library graph G to value Val.
+ -- spec or body of vertex Vertex of library graph G to value Val.
procedure Set_In_Elaboration_Order
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
Val : Boolean := True);
pragma Inline (Set_In_Elaboration_Order);
- -- Mark vertex LGV_Id of library graph G as included in some elaboration
+ -- Mark vertex Vertex of library graph G as included in some elaboration
-- order depending on value Val.
function Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Unit_Id;
+ Vertex : Library_Graph_Vertex_Id) return Unit_Id;
pragma Inline (Unit);
- -- Obtain the unit vertex LGV_Id of library graph G represents
+ -- Obtain the unit vertex Vertex of library graph G represents
---------------------
-- Edge attributes --
---------------------
+ function Activates_Task
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Activates_Task);
+ -- Determine whether edge Edge of library graph G activates a task
+
function Kind
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Library_Graph_Edge_Kind;
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Edge_Kind;
pragma Inline (Kind);
- -- Obtain the nature of edge LGE_Id of library graph G
+ -- Obtain the nature of edge Edge of library graph G
function Predecessor
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id;
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id;
pragma Inline (Predecessor);
- -- Obtain the predecessor vertex of edge LGE_Id of library graph G
+ -- Obtain the predecessor vertex of edge Edge of library graph G
function Successor
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id;
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Library_Graph_Vertex_Id;
pragma Inline (Successor);
- -- Obtain the successor vertex of edge LGE_Id of library graph G
+ -- Obtain the successor vertex of edge Edge of library graph G
--------------------------
-- Component attributes --
@@ -740,120 +950,276 @@ package Bindo.Graphs is
procedure Decrement_Pending_Predecessors
(G : Library_Graph;
- Comp : Component_Id);
+ Comp : Component_Id;
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Decrement_Pending_Predecessors);
- -- Decrease the number of pending predecessors component Comp of library
- -- graph G must wait on until it can be elaborated.
+ -- Decrease the number of pending predecessors component Comp which was
+ -- reached via edge Edge of library graph G must wait on until it can be
+ -- elaborated.
- function Pending_Predecessors
+ function Pending_Strong_Predecessors
(G : Library_Graph;
Comp : Component_Id) return Natural;
- pragma Inline (Pending_Predecessors);
- -- Obtain the number of pending predecessors component Comp of library
- -- graph G must wait on until it can be elaborated.
+ pragma Inline (Pending_Strong_Predecessors);
+ -- Obtain the number of pending strong predecessors component Comp of
+ -- library graph G must wait on until it can be elaborated.
+
+ function Pending_Weak_Predecessors
+ (G : Library_Graph;
+ Comp : Component_Id) return Natural;
+ pragma Inline (Pending_Weak_Predecessors);
+ -- Obtain the number of pending weak predecessors component Comp of
+ -- library graph G must wait on until it can be elaborated.
+
+ ----------------------
+ -- Cycle attributes --
+ ----------------------
+
+ function Invocation_Edge_Count
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Natural;
+ pragma Inline (Invocation_Edge_Count);
+ -- Obtain the number of invocation edges in cycle Cycle of library
+ -- graph G.
+
+ function Kind
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Library_Graph_Cycle_Kind;
+ pragma Inline (Kind);
+ -- Obtain the nature of cycle Cycle of library graph G
+
+ function Length
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Natural;
+ pragma Inline (Length);
+ -- Obtain the length of cycle Cycle of library graph G
---------------
-- Semantics --
---------------
+ function Complementary_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id;
+ Force_Complement : Boolean) return Library_Graph_Vertex_Id;
+ pragma Inline (Complementary_Vertex);
+ -- Obtain the complementary vertex of vertex Vertex of library graph G
+ -- as follows:
+ --
+ -- * If Vertex is the spec of an Elaborate_Body pair, return the body
+ -- * If Vertex is the body of an Elaborate_Body pair, return the spec
+ --
+ -- This behavior can be forced by setting flag Force_Complement to True.
+
+ function Contains_Elaborate_All_Edge
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Boolean;
+ pragma Inline (Contains_Elaborate_All_Edge);
+ -- Determine whether cycle Cycle of library graph G contains an
+ -- Elaborate_All edge.
+
+ function Contains_Static_Successor_Edge
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Boolean;
+ pragma Inline (Contains_Static_Successor_Edge);
+ -- Determine whether cycle Cycle of library graph G contains an edge
+ -- where the successor was compiled using the static model.
+
+ function Contains_Task_Activation
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Boolean;
+ pragma Inline (Contains_Task_Activation);
+ -- Determine whether cycle Cycle of library graph G contains an
+ -- invocation edge where the path it represents involves a task
+ -- activation.
+
+ function Has_Elaborate_All_Cycle (G : Library_Graph) return Boolean;
+ pragma Inline (Has_Elaborate_All_Cycle);
+ -- Determine whether library graph G contains a cycle involving pragma
+ -- Elaborate_All.
+
+ function Has_No_Elaboration_Code
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Has_No_Elaboration_Code);
+ -- Determine whether vertex Vertex of library graph G represents a unit
+ -- that lacks elaboration code.
+
+ function In_Same_Component
+ (G : Library_Graph;
+ Left : Library_Graph_Vertex_Id;
+ Right : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (In_Same_Component);
+ -- Determine whether vertices Left and Right of library graph G reside
+ -- in the same component.
+
function Is_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Body);
- -- Determine whether vertex LGV_Id of library graph G denotes a body
+ -- Determine whether vertex Vertex of library graph G denotes a body
function Is_Body_Of_Spec_With_Elaborate_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Body_Of_Spec_With_Elaborate_Body);
- -- Determine whether vertex LGV_Id of library graph G denotes a body
+ -- Determine whether vertex Vertex of library graph G denotes a body
-- with a corresponding spec, and the spec has pragma Elaborate_Body.
function Is_Body_With_Spec
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Body_With_Spec);
- -- Determine whether vertex LGV_Id of library graph G denotes a body
+ -- Determine whether vertex Vertex of library graph G denotes a body
-- with a corresponding spec.
+ function Is_Dynamically_Elaborated
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Is_Dynamically_Elaborated);
+ -- Determine whether vertex Vertex of library graph G was compiled
+ -- using the dynamic model.
+
function Is_Elaborable_Component
(G : Library_Graph;
Comp : Component_Id) return Boolean;
pragma Inline (Is_Elaborable_Component);
- -- Determine whether component Comp of library graph G can be elaborated
+ -- Determine whether component Comp of library graph G is not waiting on
+ -- any predecessors, and can thus be elaborated.
function Is_Elaborable_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Elaborable_Vertex);
- -- Determine whether vertex LGV_Id of library graph G can be elaborated
+ -- Determine whether vertex Vertex of library graph G is not waiting on
+ -- any predecessors, and can thus be elaborated.
+
+ function Is_Elaborate_All_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Elaborate_All_Edge);
+ -- Determine whether edge Edge of library graph G is an edge whose
+ -- predecessor is subject to pragma Elaborate_All.
+
+ function Is_Elaborate_Body_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Elaborate_Body_Edge);
+ -- Determine whether edge Edge of library graph G has a successor
+ -- that is either a spec subject to pragma Elaborate_Body, or a body
+ -- that completes such a spec.
+
+ function Is_Elaborate_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Elaborate_Edge);
+ -- Determine whether edge Edge of library graph G is an edge whose
+ -- predecessor is subject to pragma Elaborate.
+
+ function Is_Elaborate_Body_Pair
+ (G : Library_Graph;
+ Spec_Vertex : Library_Graph_Vertex_Id;
+ Body_Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Is_Elaborate_Body_Pair);
+ -- Determine whether vertices Spec_Vertex and Body_Vertex of library
+ -- graph G denote a spec subject to Elaborate_Body and its completing
+ -- body.
+
+ function Is_Forced_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Forced_Edge);
+ -- Determine whether edge Edge of library graph G is a byproduct of the
+ -- forced-elaboration-order file.
function Is_Internal_Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Internal_Unit);
- -- Determine whether vertex LGV_Id of library graph G denotes an
+ -- Determine whether vertex Vertex of library graph G denotes an
-- internal unit.
+ function Is_Invocation_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Invocation_Edge);
+ -- Determine whether edge Edge of library graph G came from the
+ -- traversal of the invocation graph.
+
function Is_Predefined_Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Predefined_Unit);
- -- Determine whether vertex LGV_Id of library graph G denotes a
+ -- Determine whether vertex Vertex of library graph G denotes a
-- predefined unit.
function Is_Preelaborated_Unit
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Preelaborated_Unit);
- -- Determine whether vertex LGV_Id of library graph G denotes a unit
- -- subjec to pragma Pure or Preelaborable.
+ -- Determine whether vertex Vertex of library graph G denotes a unit
+ -- subject to pragma Pure or Preelaborable.
function Is_Spec
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Spec);
- -- Determine whether vertex LGV_Id of library graph G denotes a spec
+ -- Determine whether vertex Vertex of library graph G denotes a spec
+
+ function Is_Spec_Before_Body_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_Spec_Before_Body_Edge);
+ -- Determine whether edge Edge of library graph G links a predecessor
+ -- spec and a successor body belonging to the same unit.
function Is_Spec_With_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Spec_With_Body);
- -- Determine whether vertex LGV_Id of library graph G denotes a spec
+ -- Determine whether vertex Vertex of library graph G denotes a spec
-- with a corresponding body.
function Is_Spec_With_Elaborate_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Is_Spec_With_Elaborate_Body);
- -- Determine whether vertex LGV_Id of library graph G denotes a spec
+ -- Determine whether vertex Vertex of library graph G denotes a spec
-- with a corresponding body, and is subject to pragma Elaborate_Body.
- function Links_Vertices_In_Same_Component
+ function Is_Weakly_Elaborable_Vertex
(G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) return Boolean;
- pragma Inline (Links_Vertices_In_Same_Component);
- -- Determine whether edge LGE_Id of library graph G links a predecessor
- -- and a successor that reside within the same component.
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
+ pragma Inline (Is_Weakly_Elaborable_Vertex);
+ -- Determine whether vertex Vertex of library graph G is waiting on
+ -- weak predecessors only, in which case it can be elaborated assuming
+ -- that the weak edges will not be exercised at elaboration time.
+
+ function Is_With_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) return Boolean;
+ pragma Inline (Is_With_Edge);
+ -- Determine whether edge Edge of library graph G is the result of a
+ -- with dependency between its successor and predecessor.
function Needs_Elaboration
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Boolean;
+ Vertex : Library_Graph_Vertex_Id) return Boolean;
pragma Inline (Needs_Elaboration);
- -- Determine whether vertex LGV_Id of library graph G represents a unit
+ -- Determine whether vertex Vertex of library graph G represents a unit
-- that needs to be elaborated.
function Proper_Body
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
pragma Inline (Proper_Body);
- -- Obtain the body of vertex LGV_Id of library graph G
+ -- Obtain the body of vertex Vertex of library graph G
function Proper_Spec
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id) return Library_Graph_Vertex_Id;
pragma Inline (Proper_Spec);
- -- Obtain the spec of vertex LGV_Id of library graph G
+ -- Obtain the spec of vertex Vertex of library graph G
----------------
-- Statistics --
@@ -876,15 +1242,19 @@ package Bindo.Graphs is
pragma Inline (Number_Of_Components);
-- Obtain the total number of components in library graph G
+ function Number_Of_Cycles (G : Library_Graph) return Natural;
+ pragma Inline (Number_Of_Cycles);
+ -- Obtain the total number of cycles in library graph G
+
function Number_Of_Edges (G : Library_Graph) return Natural;
pragma Inline (Number_Of_Edges);
-- Obtain the total number of edges in library graph G
function Number_Of_Edges_To_Successors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Natural;
+ Vertex : Library_Graph_Vertex_Id) return Natural;
pragma Inline (Number_Of_Edges_To_Successors);
- -- Obtain the total number of edges to successors vertex LGV_Id of
+ -- Obtain the total number of edges to successors vertex Vertex of
-- library graph G has.
function Number_Of_Vertices (G : Library_Graph) return Natural;
@@ -895,6 +1265,27 @@ package Bindo.Graphs is
-- Iterators --
---------------
+ -- The following type represents an iterator over all cycles of a
+ -- library graph.
+
+ type All_Cycle_Iterator is private;
+
+ function Has_Next (Iter : All_Cycle_Iterator) return Boolean;
+ pragma Inline (Has_Next);
+ -- Determine whether iterator Iter has more cycles to examine
+
+ function Iterate_All_Cycles
+ (G : Library_Graph) return All_Cycle_Iterator;
+ pragma Inline (Iterate_All_Cycles);
+ -- Obtain an iterator over all cycles of library graph G
+
+ procedure Next
+ (Iter : in out All_Cycle_Iterator;
+ Cycle : out Library_Graph_Cycle_Id);
+ pragma Inline (Next);
+ -- Return the current cycle referenced by iterator Iter and advance to
+ -- the next available cycle.
+
-- The following type represents an iterator over all edges of a library
-- graph.
@@ -909,8 +1300,8 @@ package Bindo.Graphs is
-- Obtain an iterator over all edges of library graph G
procedure Next
- (Iter : in out All_Edge_Iterator;
- LGE_Id : out Library_Graph_Edge_Id);
+ (Iter : in out All_Edge_Iterator;
+ Edge : out Library_Graph_Edge_Id);
pragma Inline (Next);
-- Return the current edge referenced by iterator Iter and advance to
-- the next available edge.
@@ -931,7 +1322,7 @@ package Bindo.Graphs is
procedure Next
(Iter : in out All_Vertex_Iterator;
- LGV_Id : out Library_Graph_Vertex_Id);
+ Vertex : out Library_Graph_Vertex_Id);
pragma Inline (Next);
-- Return the current vertex referenced by iterator Iter and advance
-- to the next available vertex.
@@ -975,11 +1366,34 @@ package Bindo.Graphs is
procedure Next
(Iter : in out Component_Vertex_Iterator;
- LGV_Id : out Library_Graph_Vertex_Id);
+ Vertex : out Library_Graph_Vertex_Id);
pragma Inline (Next);
-- Return the current vertex referenced by iterator Iter and advance
-- to the next available vertex.
+ -- The following type represents an iterator over all edges that form a
+ -- cycle.
+
+ type Edges_Of_Cycle_Iterator is private;
+
+ function Has_Next (Iter : Edges_Of_Cycle_Iterator) return Boolean;
+ pragma Inline (Has_Next);
+ -- Determine whether iterator Iter has more edges to examine
+
+ function Iterate_Edges_Of_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) return Edges_Of_Cycle_Iterator;
+ pragma Inline (Iterate_Edges_Of_Cycle);
+ -- Obtain an iterator over all edges that form cycle Cycle of library
+ -- graph G.
+
+ procedure Next
+ (Iter : in out Edges_Of_Cycle_Iterator;
+ Edge : out Library_Graph_Edge_Id);
+ pragma Inline (Next);
+ -- Return the current edge referenced by iterator Iter and advance to
+ -- the next available edge.
+
-- The following type represents an iterator over all edges that reach
-- successors starting from a particular predecessor vertex.
@@ -991,14 +1405,14 @@ package Bindo.Graphs is
function Iterate_Edges_To_Successors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) return Edges_To_Successors_Iterator;
+ Vertex : Library_Graph_Vertex_Id) return Edges_To_Successors_Iterator;
pragma Inline (Iterate_Components);
-- Obtain an iterator over all edges to successors with predecessor
- -- vertex LGV_Id of library graph G.
+ -- vertex Vertex of library graph G.
procedure Next
- (Iter : in out Edges_To_Successors_Iterator;
- LGE_Id : out Library_Graph_Edge_Id);
+ (Iter : in out Edges_To_Successors_Iterator;
+ Edge : out Library_Graph_Edge_Id);
pragma Inline (Next);
-- Return the current edge referenced by iterator Iter and advance to
-- the next available edge.
@@ -1009,11 +1423,6 @@ package Bindo.Graphs is
-- Vertices --
--------------
- procedure Destroy_Library_Graph_Vertex
- (LGV_Id : in out Library_Graph_Vertex_Id);
- pragma Inline (Destroy_Library_Graph_Vertex);
- -- Destroy library graph vertex LGV_Id
-
-- The following type represents the attributes of a library graph
-- vertex.
@@ -1034,9 +1443,13 @@ package Bindo.Graphs is
In_Elaboration_Order : Boolean := False;
-- Set when this vertex is elaborated
- Pending_Predecessors : Natural := 0;
- -- The number of pending predecessor vertices this vertex must wait
- -- on before it can be elaborated.
+ Pending_Strong_Predecessors : Natural := 0;
+ -- The number of pending strong predecessor vertices this vertex must
+ -- wait on before it can be elaborated.
+
+ Pending_Weak_Predecessors : Natural := 0;
+ -- The number of weak predecessor vertices this vertex must wait on
+ -- before it can be elaborated.
Unit : Unit_Id := No_Unit_Id;
-- The reference to unit this vertex represents
@@ -1044,17 +1457,18 @@ package Bindo.Graphs is
No_Library_Graph_Vertex_Attributes :
constant Library_Graph_Vertex_Attributes :=
- (Corresponding_Item => No_Library_Graph_Vertex,
- In_Elaboration_Order => False,
- Pending_Predecessors => 0,
- Unit => No_Unit_Id);
+ (Corresponding_Item => No_Library_Graph_Vertex,
+ In_Elaboration_Order => False,
+ Pending_Strong_Predecessors => 0,
+ Pending_Weak_Predecessors => 0,
+ Unit => No_Unit_Id);
procedure Destroy_Library_Graph_Vertex_Attributes
(Attrs : in out Library_Graph_Vertex_Attributes);
pragma Inline (Destroy_Library_Graph_Vertex_Attributes);
-- Destroy the contents of attributes Attrs
- package VA is new Dynamic_Hash_Tables
+ package LGV_Tables is new Dynamic_Hash_Tables
(Key_Type => Library_Graph_Vertex_Id,
Value_Type => Library_Graph_Vertex_Attributes,
No_Value => No_Library_Graph_Vertex_Attributes,
@@ -1070,28 +1484,28 @@ package Bindo.Graphs is
-- Edges --
-----------
- procedure Destroy_Library_Graph_Edge
- (LGE_Id : in out Library_Graph_Edge_Id);
- pragma Inline (Destroy_Library_Graph_Edge);
- -- Destroy library graph edge LGE_Id
-
-- The following type represents the attributes of a library graph edge
type Library_Graph_Edge_Attributes is record
+ Activates_Task : Boolean := False;
+ -- Set for an invocation edge, where at least one of the paths the
+ -- edge represents activates a task.
+
Kind : Library_Graph_Edge_Kind := No_Edge;
-- The nature of the library graph edge
end record;
No_Library_Graph_Edge_Attributes :
constant Library_Graph_Edge_Attributes :=
- (Kind => No_Edge);
+ (Activates_Task => False,
+ Kind => No_Edge);
procedure Destroy_Library_Graph_Edge_Attributes
(Attrs : in out Library_Graph_Edge_Attributes);
pragma Inline (Destroy_Library_Graph_Edge_Attributes);
-- Destroy the contents of attributes Attrs
- package EA is new Dynamic_Hash_Tables
+ package LGE_Tables is new Dynamic_Hash_Tables
(Key_Type => Library_Graph_Edge_Id,
Value_Type => Library_Graph_Edge_Attributes,
No_Value => No_Library_Graph_Edge_Attributes,
@@ -1110,20 +1524,25 @@ package Bindo.Graphs is
-- The following type represents the attributes of a component
type Component_Attributes is record
- Pending_Predecessors : Natural := 0;
- -- The number of pending predecessor components this component must
- -- wait on before it can be elaborated.
+ Pending_Strong_Predecessors : Natural := 0;
+ -- The number of pending strong predecessor components this component
+ -- must wait on before it can be elaborated.
+
+ Pending_Weak_Predecessors : Natural := 0;
+ -- The number of pending weak predecessor components this component
+ -- must wait on before it can be elaborated.
end record;
No_Component_Attributes : constant Component_Attributes :=
- (Pending_Predecessors => 0);
+ (Pending_Strong_Predecessors => 0,
+ Pending_Weak_Predecessors => 0);
procedure Destroy_Component_Attributes
(Attrs : in out Component_Attributes);
pragma Inline (Destroy_Component_Attributes);
-- Destroy the contents of attributes Attrs
- package CA is new Dynamic_Hash_Tables
+ package Component_Tables is new Dynamic_Hash_Tables
(Key_Type => Component_Id,
Value_Type => Component_Attributes,
No_Value => No_Component_Attributes,
@@ -1135,9 +1554,60 @@ package Bindo.Graphs is
Destroy_Value => Destroy_Component_Attributes,
Hash => Hash_Component);
- ---------------
- -- Relations --
- ---------------
+ ------------
+ -- Cycles --
+ ------------
+
+ -- The following type represents the attributes of a cycle
+
+ type Library_Graph_Cycle_Attributes is record
+ Invocation_Edge_Count : Natural := 0;
+ -- The number of invocation edges within the cycle
+
+ Kind : Library_Graph_Cycle_Kind := No_Cycle_Kind;
+ -- The nature of the cycle
+
+ Path : LGE_Lists.Doubly_Linked_List := LGE_Lists.Nil;
+ -- The path of edges that form the cycle
+ end record;
+
+ No_Library_Graph_Cycle_Attributes :
+ constant Library_Graph_Cycle_Attributes :=
+ (Invocation_Edge_Count => 0,
+ Kind => No_Cycle_Kind,
+ Path => LGE_Lists.Nil);
+
+ procedure Destroy_Library_Graph_Cycle_Attributes
+ (Attrs : in out Library_Graph_Cycle_Attributes);
+ pragma Inline (Destroy_Library_Graph_Cycle_Attributes);
+ -- Destroy the contents of attributes Attrs
+
+ function Hash_Library_Graph_Cycle_Attributes
+ (Attrs : Library_Graph_Cycle_Attributes) return Bucket_Range_Type;
+ pragma Inline (Hash_Library_Graph_Cycle_Attributes);
+ -- Obtain the hash of key Attrs
+
+ function Same_Library_Graph_Cycle_Attributes
+ (Left : Library_Graph_Cycle_Attributes;
+ Right : Library_Graph_Cycle_Attributes) return Boolean;
+ pragma Inline (Same_Library_Graph_Cycle_Attributes);
+ -- Determine whether cycle attributes Left and Right are the same
+
+ package LGC_Tables is new Dynamic_Hash_Tables
+ (Key_Type => Library_Graph_Cycle_Id,
+ Value_Type => Library_Graph_Cycle_Attributes,
+ No_Value => No_Library_Graph_Cycle_Attributes,
+ Expansion_Threshold => 1.5,
+ Expansion_Factor => 2,
+ Compression_Threshold => 0.3,
+ Compression_Factor => 2,
+ "=" => "=",
+ Destroy_Value => Destroy_Library_Graph_Cycle_Attributes,
+ Hash => Hash_Library_Graph_Cycle);
+
+ --------------------
+ -- Recorded edges --
+ --------------------
-- The following type represents a relation between a predecessor and
-- successor vertices.
@@ -1160,7 +1630,7 @@ package Bindo.Graphs is
pragma Inline (Hash_Predecessor_Successor_Relation);
-- Obtain the hash value of key Rel
- package PS is new Membership_Sets
+ package RE_Sets is new Membership_Sets
(Element_Type => Predecessor_Successor_Relation,
"=" => "=",
Hash => Hash_Predecessor_Successor_Relation);
@@ -1176,7 +1646,7 @@ package Bindo.Graphs is
-- Units --
-----------
- package UV is new Dynamic_Hash_Tables
+ package Unit_Tables is new Dynamic_Hash_Tables
(Key_Type => Unit_Id,
Value_Type => Library_Graph_Vertex_Id,
No_Value => No_Library_Graph_Vertex,
@@ -1205,28 +1675,35 @@ package Bindo.Graphs is
-- The following type represents the attributes of a library graph
type Library_Graph_Attributes is record
- Component_Attributes : CA.Dynamic_Hash_Table := CA.Nil;
+ Component_Attributes : Component_Tables.Dynamic_Hash_Table :=
+ Component_Tables.Nil;
-- The map of component -> component attributes for all components in
-- the graph.
Counts : Library_Graph_Edge_Counts := (others => 0);
-- Edge statistics
- Edge_Attributes : EA.Dynamic_Hash_Table := EA.Nil;
+ Cycle_Attributes : LGC_Tables.Dynamic_Hash_Table := LGC_Tables.Nil;
+ -- The map of cycle -> cycle attributes for all cycles in the graph
+
+ Cycles : LGC_Lists.Doubly_Linked_List := LGC_Lists.Nil;
+ -- The list of all cycles in the graph, sorted based on precedence
+
+ Edge_Attributes : LGE_Tables.Dynamic_Hash_Table := LGE_Tables.Nil;
-- The map of edge -> edge attributes for all edges in the graph
Graph : DG.Directed_Graph := DG.Nil;
-- The underlying graph describing the relations between edges and
-- vertices.
- Relations : PS.Membership_Set := PS.Nil;
- -- The set of relations between successors and predecessors, used to
- -- prevent duplicate edges in the graph.
+ Recorded_Edges : RE_Sets.Membership_Set := RE_Sets.Nil;
+ -- The set of recorded edges, used to prevent duplicate edges in the
+ -- graph.
- Unit_To_Vertex : UV.Dynamic_Hash_Table := UV.Nil;
+ Unit_To_Vertex : Unit_Tables.Dynamic_Hash_Table := Unit_Tables.Nil;
-- The map of unit -> vertex
- Vertex_Attributes : VA.Dynamic_Hash_Table := VA.Nil;
+ Vertex_Attributes : LGV_Tables.Dynamic_Hash_Table := LGV_Tables.Nil;
-- The map of vertex -> vertex attributes for all vertices in the
-- graph.
end record;
@@ -1238,10 +1715,12 @@ package Bindo.Graphs is
-- Iterators --
---------------
+ type All_Cycle_Iterator is new LGC_Lists.Iterator;
type All_Edge_Iterator is new DG.All_Edge_Iterator;
type All_Vertex_Iterator is new DG.All_Vertex_Iterator;
type Component_Iterator is new DG.Component_Iterator;
type Component_Vertex_Iterator is new DG.Component_Vertex_Iterator;
+ type Edges_Of_Cycle_Iterator is new LGE_Lists.Iterator;
type Edges_To_Successors_Iterator is new DG.Outgoing_Edge_Iterator;
end Library_Graphs;
diff --git a/gcc/ada/bindo-units.adb b/gcc/ada/bindo-units.adb
index de0afb9..284aa62 100644
--- a/gcc/ada/bindo-units.adb
+++ b/gcc/ada/bindo-units.adb
@@ -23,13 +23,17 @@
-- --
------------------------------------------------------------------------------
+with Bindo.Writers;
+use Bindo.Writers;
+use Bindo.Writers.Phase_Writers;
+
package body Bindo.Units is
-------------------
-- Signature set --
-------------------
- package SS is new Membership_Sets
+ package Signature_Sets is new Membership_Sets
(Element_Type => Invocation_Signature_Id,
"=" => "=",
Hash => Hash_Invocation_Signature);
@@ -41,11 +45,11 @@ package body Bindo.Units is
-- The following set stores all invocation signatures that appear in
-- elaborable units.
- Elaborable_Constructs : SS.Membership_Set := SS.Nil;
+ Elaborable_Constructs : Signature_Sets.Membership_Set := Signature_Sets.Nil;
-- The following set stores all units the need to be elaborated
- Elaborable_Units : US.Membership_Set := US.Nil;
+ Elaborable_Units : Unit_Sets.Membership_Set := Unit_Sets.Nil;
-----------------------
-- Local subprograms --
@@ -79,9 +83,13 @@ package body Bindo.Units is
procedure Collect_Elaborable_Units is
begin
+ Start_Phase (Unit_Collection);
+
for U_Id in ALI.Units.First .. ALI.Units.Last loop
Process_Unit (U_Id);
end loop;
+
+ End_Phase (Unit_Collection);
end Collect_Elaborable_Units;
------------------------
@@ -139,14 +147,27 @@ package body Bindo.Units is
return Corresponding_Unit (Name_Id (UNam));
end Corresponding_Unit;
+ ---------------
+ -- File_Name --
+ ---------------
+
+ function File_Name (U_Id : Unit_Id) return File_Name_Type is
+ pragma Assert (Present (U_Id));
+
+ U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
+
+ begin
+ return U_Rec.Sfile;
+ end File_Name;
+
--------------------
-- Finalize_Units --
--------------------
procedure Finalize_Units is
begin
- SS.Destroy (Elaborable_Constructs);
- US.Destroy (Elaborable_Units);
+ Signature_Sets.Destroy (Elaborable_Constructs);
+ Unit_Sets.Destroy (Elaborable_Units);
end Finalize_Units;
------------------------------
@@ -183,9 +204,22 @@ package body Bindo.Units is
function Has_Next (Iter : Elaborable_Units_Iterator) return Boolean is
begin
- return US.Has_Next (US.Iterator (Iter));
+ return Unit_Sets.Has_Next (Unit_Sets.Iterator (Iter));
end Has_Next;
+ -----------------------------
+ -- Has_No_Elaboration_Code --
+ -----------------------------
+
+ function Has_No_Elaboration_Code (U_Id : Unit_Id) return Boolean is
+ pragma Assert (Present (U_Id));
+
+ U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
+
+ begin
+ return U_Rec.No_Elab;
+ end Has_No_Elaboration_Code;
+
-------------------------------
-- Hash_Invocation_Signature --
-------------------------------
@@ -216,11 +250,27 @@ package body Bindo.Units is
procedure Initialize_Units is
begin
- Elaborable_Constructs := SS.Create (Number_Of_Units);
- Elaborable_Units := US.Create (Number_Of_Units);
+ Elaborable_Constructs := Signature_Sets.Create (Number_Of_Units);
+ Elaborable_Units := Unit_Sets.Create (Number_Of_Units);
end Initialize_Units;
-------------------------------
+ -- Invocation_Graph_Encoding --
+ -------------------------------
+
+ function Invocation_Graph_Encoding
+ (U_Id : Unit_Id) return Invocation_Graph_Encoding_Kind
+ is
+ pragma Assert (Present (U_Id));
+
+ U_Rec : Unit_Record renames ALI.Units.Table (U_Id);
+ U_ALI : ALIs_Record renames ALI.ALIs.Table (U_Rec.My_ALI);
+
+ begin
+ return U_ALI.Invocation_Graph_Encoding;
+ end Invocation_Graph_Encoding;
+
+ -------------------------------
-- Is_Dynamically_Elaborated --
-------------------------------
@@ -278,7 +328,7 @@ package body Bindo.Units is
function Iterate_Elaborable_Units return Elaborable_Units_Iterator is
begin
- return Elaborable_Units_Iterator (US.Iterate (Elaborable_Units));
+ return Elaborable_Units_Iterator (Unit_Sets.Iterate (Elaborable_Units));
end Iterate_Elaborable_Units;
----------
@@ -304,7 +354,7 @@ package body Bindo.Units is
begin
pragma Assert (Present (IS_Id));
- return SS.Contains (Elaborable_Constructs, IS_Id);
+ return Signature_Sets.Contains (Elaborable_Constructs, IS_Id);
end Needs_Elaboration;
-----------------------
@@ -315,7 +365,7 @@ package body Bindo.Units is
begin
pragma Assert (Present (U_Id));
- return US.Contains (Elaborable_Units, U_Id);
+ return Unit_Sets.Contains (Elaborable_Units, U_Id);
end Needs_Elaboration;
----------
@@ -327,7 +377,7 @@ package body Bindo.Units is
U_Id : out Unit_Id)
is
begin
- US.Next (US.Iterator (Iter), U_Id);
+ Unit_Sets.Next (Unit_Sets.Iterator (Iter), U_Id);
end Next;
--------------------------------
@@ -336,7 +386,7 @@ package body Bindo.Units is
function Number_Of_Elaborable_Units return Natural is
begin
- return US.Size (Elaborable_Units);
+ return Unit_Sets.Size (Elaborable_Units);
end Number_Of_Elaborable_Units;
---------------------
@@ -355,14 +405,12 @@ package body Bindo.Units is
procedure Process_Invocation_Construct (IC_Id : Invocation_Construct_Id) is
pragma Assert (Present (IC_Id));
- IC_Rec : Invocation_Construct_Record renames
- Invocation_Constructs.Table (IC_Id);
- IC_Sig : constant Invocation_Signature_Id := IC_Rec.Signature;
+ IS_Id : constant Invocation_Signature_Id := Signature (IC_Id);
- pragma Assert (Present (IC_Sig));
+ pragma Assert (Present (IS_Id));
begin
- SS.Insert (Elaborable_Constructs, IC_Sig);
+ Signature_Sets.Insert (Elaborable_Constructs, IS_Id);
end Process_Invocation_Construct;
-----------------------------------
@@ -402,7 +450,7 @@ package body Bindo.Units is
-- signatures of constructs it declares.
else
- US.Insert (Elaborable_Units, U_Id);
+ Unit_Sets.Insert (Elaborable_Units, U_Id);
Process_Invocation_Constructs (U_Id);
end if;
end Process_Unit;
diff --git a/gcc/ada/bindo-units.ads b/gcc/ada/bindo-units.ads
index 93caadf..5f045c8 100644
--- a/gcc/ada/bindo-units.ads
+++ b/gcc/ada/bindo-units.ads
@@ -33,6 +33,19 @@ with GNAT.Sets; use GNAT.Sets;
package Bindo.Units is
+ ---------------
+ -- Unit sets --
+ ---------------
+
+ function Hash_Unit (U_Id : Unit_Id) return Bucket_Range_Type;
+ pragma Inline (Hash_Unit);
+ -- Obtain the hash value of key U_Id
+
+ package Unit_Sets is new Membership_Sets
+ (Element_Type => Unit_Id,
+ "=" => "=",
+ Hash => Hash_Unit);
+
procedure Collect_Elaborable_Units;
pragma Inline (Collect_Elaborable_Units);
-- Gather all units in the bind that require elaboration. The units are
@@ -54,6 +67,10 @@ package Bindo.Units is
pragma Inline (Corresponding_Unit);
-- Obtain the unit which corresponds to name FNam
+ function File_Name (U_Id : Unit_Id) return File_Name_Type;
+ pragma Inline (File_Name);
+ -- Obtain the file name of unit U_Id
+
type Unit_Processor_Ptr is access procedure (U_Id : Unit_Id);
procedure For_Each_Elaborable_Unit (Processor : Unit_Processor_Ptr);
@@ -64,14 +81,20 @@ package Bindo.Units is
pragma Inline (For_Each_Unit);
-- Invoke Processor on each unit in the bind
+ function Has_No_Elaboration_Code (U_Id : Unit_Id) return Boolean;
+ pragma Inline (Has_No_Elaboration_Code);
+ -- Determine whether unit U_Id lacks elaboration code
+
function Hash_Invocation_Signature
(IS_Id : Invocation_Signature_Id) return Bucket_Range_Type;
pragma Inline (Hash_Invocation_Signature);
-- Obtain the hash value of key IS_Id
- function Hash_Unit (U_Id : Unit_Id) return Bucket_Range_Type;
- pragma Inline (Hash_Unit);
- -- Obtain the hash value of key U_Id
+ function Invocation_Graph_Encoding
+ (U_Id : Unit_Id) return Invocation_Graph_Encoding_Kind;
+ pragma Inline (Invocation_Graph_Encoding);
+ -- Obtain the encoding format used to capture invocation constructs and
+ -- relations in the ALI file of unit U_Id.
function Is_Dynamically_Elaborated (U_Id : Unit_Id) return Boolean;
pragma Inline (Is_Dynamically_Elaborated);
@@ -144,11 +167,6 @@ package Bindo.Units is
-- Initialize the internal structures of this unit
private
- package US is new Membership_Sets
- (Element_Type => Unit_Id,
- "=" => "=",
- Hash => Hash_Unit);
-
- type Elaborable_Units_Iterator is new US.Iterator;
+ type Elaborable_Units_Iterator is new Unit_Sets.Iterator;
end Bindo.Units;
diff --git a/gcc/ada/bindo-validators.adb b/gcc/ada/bindo-validators.adb
index 54d2fc6..584d33f 100644
--- a/gcc/ada/bindo-validators.adb
+++ b/gcc/ada/bindo-validators.adb
@@ -27,24 +27,194 @@ with Debug; use Debug;
with Output; use Output;
with Types; use Types;
-with Bindo.Units; use Bindo.Units;
+with Bindo.Units;
+use Bindo.Units;
-with GNAT; use GNAT;
-with GNAT.Sets; use GNAT.Sets;
+with Bindo.Writers;
+use Bindo.Writers;
+use Bindo.Writers.Phase_Writers;
package body Bindo.Validators is
+ -----------------------
+ -- Local subprograms --
+ -----------------------
+
+ procedure Write_Error
+ (Msg : String;
+ Flag : out Boolean);
+ pragma Inline (Write_Error);
+ -- Write error message Msg to standard output and set flag Flag to True
+
+ ----------------------
+ -- Cycle_Validators --
+ ----------------------
+
+ package body Cycle_Validators is
+ Has_Invalid_Cycle : Boolean := False;
+ -- Flag set when the library graph contains an invalid cycle
+
+ -----------------------
+ -- Local subprograms --
+ -----------------------
+
+ procedure Validate_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id);
+ pragma Inline (Validate_Cycle);
+ -- Ensure that a cycle meets the following requirements:
+ --
+ -- * Is of proper kind
+ -- * Has enough edges to form a circuit
+ -- * No edge is repeated
+
+ procedure Validate_Cycle_Path
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id);
+ pragma Inline (Validate_Cycle_Path);
+ -- Ensure that the path of a cycle meets the following requirements:
+ --
+ -- * No edge is repeated
+
+ --------------------
+ -- Validate_Cycle --
+ --------------------
+
+ procedure Validate_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id)
+ is
+ Msg : constant String := "Validate_Cycle";
+
+ begin
+ pragma Assert (Present (G));
+
+ if not Present (Cycle) then
+ Write_Error (Msg, Has_Invalid_Cycle);
+
+ Write_Str (" empty cycle");
+ Write_Eol;
+ Write_Eol;
+ return;
+ end if;
+
+ if Kind (G, Cycle) = No_Cycle_Kind then
+ Write_Error (Msg, Has_Invalid_Cycle);
+
+ Write_Str (" cycle (LGC_Id_");
+ Write_Int (Int (Cycle));
+ Write_Str (") is a No_Cycle");
+ Write_Eol;
+ Write_Eol;
+ end if;
+
+ -- A cycle requires at least one edge (self cycle) to form a circuit
+
+ if Length (G, Cycle) < 1 then
+ Write_Error (Msg, Has_Invalid_Cycle);
+
+ Write_Str (" cycle (LGC_Id_");
+ Write_Int (Int (Cycle));
+ Write_Str (") does not contain enough edges");
+ Write_Eol;
+ Write_Eol;
+ end if;
+
+ Validate_Cycle_Path (G, Cycle);
+ end Validate_Cycle;
+
+ -------------------------
+ -- Validate_Cycle_Path --
+ -------------------------
+
+ procedure Validate_Cycle_Path
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id)
+ is
+ Msg : constant String := "Validate_Cycle_Path";
+
+ Edge : Library_Graph_Edge_Id;
+ Edges : LGE_Sets.Membership_Set;
+ Iter : Edges_Of_Cycle_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ -- Use a set to detect duplicate edges while traversing the cycle
+
+ Edges := LGE_Sets.Create (Length (G, Cycle));
+
+ -- Inspect the edges of the cycle, trying to catch duplicates
+
+ Iter := Iterate_Edges_Of_Cycle (G, Cycle);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ -- The current edge has already been encountered while traversing
+ -- the cycle. This indicates that the cycle is malformed as edges
+ -- are not repeated in the circuit.
+
+ if LGE_Sets.Contains (Edges, Edge) then
+ Write_Error (Msg, Has_Invalid_Cycle);
+
+ Write_Str (" library graph edge (LGE_Id_");
+ Write_Int (Int (Edge));
+ Write_Str (") is repeated in cycle (LGC_Id_");
+ Write_Int (Int (Cycle));
+ Write_Str (")");
+ Write_Eol;
+
+ -- Otherwise add the current edge to the set of encountered edges
+
+ else
+ LGE_Sets.Insert (Edges, Edge);
+ end if;
+ end loop;
+
+ LGE_Sets.Destroy (Edges);
+ end Validate_Cycle_Path;
+
+ ---------------------
+ -- Validate_Cycles --
+ ---------------------
+
+ procedure Validate_Cycles (G : Library_Graph) is
+ Cycle : Library_Graph_Cycle_Id;
+ Iter : All_Cycle_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+
+ -- Nothing to do when switch -d_V (validate bindo cycles, graphs, and
+ -- order) is not in effect.
+
+ if not Debug_Flag_Underscore_VV then
+ return;
+ end if;
+
+ Start_Phase (Cycle_Validation);
+
+ Iter := Iterate_All_Cycles (G);
+ while Has_Next (Iter) loop
+ Next (Iter, Cycle);
+
+ Validate_Cycle (G, Cycle);
+ end loop;
+
+ End_Phase (Cycle_Validation);
+
+ if Has_Invalid_Cycle then
+ raise Invalid_Cycle;
+ end if;
+ end Validate_Cycles;
+ end Cycle_Validators;
+
----------------------------------
-- Elaboration_Order_Validators --
----------------------------------
package body Elaboration_Order_Validators is
- package US is new Membership_Sets
- (Element_Type => Unit_Id,
- "=" => "=",
- Hash => Hash_Unit);
- use US;
-
Has_Invalid_Data : Boolean := False;
-- Flag set when the elaboration order contains invalid data
@@ -52,7 +222,7 @@ package body Bindo.Validators is
-- Local subprograms --
-----------------------
- function Build_Elaborable_Unit_Set return Membership_Set;
+ function Build_Elaborable_Unit_Set return Unit_Sets.Membership_Set;
pragma Inline (Build_Elaborable_Unit_Set);
-- Create a set from all units that need to be elaborated
@@ -61,7 +231,7 @@ package body Bindo.Validators is
-- Emit an error concerning unit U_Id that must be elaborated, but was
-- not.
- procedure Report_Missing_Elaborations (Set : Membership_Set);
+ procedure Report_Missing_Elaborations (Set : Unit_Sets.Membership_Set);
pragma Inline (Report_Missing_Elaborations);
-- Emit errors on all units in set Set that must be elaborated, but were
-- not.
@@ -70,7 +240,9 @@ package body Bindo.Validators is
pragma Inline (Report_Spurious_Elaboration);
-- Emit an error concerning unit U_Id that is incorrectly elaborated
- procedure Validate_Unit (U_Id : Unit_Id; Elab_Set : Membership_Set);
+ procedure Validate_Unit
+ (U_Id : Unit_Id;
+ Elab_Set : Unit_Sets.Membership_Set);
pragma Inline (Validate_Unit);
-- Validate the elaboration status of unit U_Id. Elab_Set is the set of
-- all units that need to be elaborated.
@@ -79,28 +251,22 @@ package body Bindo.Validators is
pragma Inline (Validate_Units);
-- Validate all units in elaboration order Order
- procedure Write_Error (Msg : String);
- pragma Inline (Write_Error);
- -- Write error message Msg to standard output and signal that the
- -- elaboration order is incorrect.
-
-------------------------------
-- Build_Elaborable_Unit_Set --
-------------------------------
- function Build_Elaborable_Unit_Set return Membership_Set is
+ function Build_Elaborable_Unit_Set return Unit_Sets.Membership_Set is
Iter : Elaborable_Units_Iterator;
- Set : Membership_Set;
+ Set : Unit_Sets.Membership_Set;
U_Id : Unit_Id;
begin
- Set := Create (Number_Of_Elaborable_Units);
+ Set := Unit_Sets.Create (Number_Of_Elaborable_Units);
Iter := Iterate_Elaborable_Units;
while Has_Next (Iter) loop
Next (Iter, U_Id);
- pragma Assert (Present (U_Id));
- Insert (Set, U_Id);
+ Unit_Sets.Insert (Set, U_Id);
end loop;
return Set;
@@ -115,7 +281,7 @@ package body Bindo.Validators is
begin
pragma Assert (Present (U_Id));
- Write_Error (Msg);
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str ("unit (U_Id_");
Write_Int (Int (U_Id));
@@ -129,15 +295,14 @@ package body Bindo.Validators is
-- Report_Missing_Elaborations --
---------------------------------
- procedure Report_Missing_Elaborations (Set : Membership_Set) is
- Iter : Iterator;
+ procedure Report_Missing_Elaborations (Set : Unit_Sets.Membership_Set) is
+ Iter : Unit_Sets.Iterator;
U_Id : Unit_Id;
begin
- Iter := Iterate (Set);
- while Has_Next (Iter) loop
- Next (Iter, U_Id);
- pragma Assert (Present (U_Id));
+ Iter := Unit_Sets.Iterate (Set);
+ while Unit_Sets.Has_Next (Iter) loop
+ Unit_Sets.Next (Iter, U_Id);
Report_Missing_Elaboration (U_Id);
end loop;
@@ -152,7 +317,7 @@ package body Bindo.Validators is
begin
pragma Assert (Present (U_Id));
- Write_Error (Msg);
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str ("unit (U_Id_");
Write_Int (Int (U_Id));
@@ -167,15 +332,19 @@ package body Bindo.Validators is
procedure Validate_Elaboration_Order (Order : Unit_Id_Table) is
begin
- -- Nothing to do when switch -d_V (validate bindo graphs and order)
- -- is not in effect.
+ -- Nothing to do when switch -d_V (validate bindo cycles, graphs, and
+ -- order) is not in effect.
if not Debug_Flag_Underscore_VV then
return;
end if;
+ Start_Phase (Elaboration_Order_Validation);
+
Validate_Units (Order);
+ End_Phase (Elaboration_Order_Validation);
+
if Has_Invalid_Data then
raise Invalid_Elaboration_Order;
end if;
@@ -185,15 +354,18 @@ package body Bindo.Validators is
-- Validate_Unit --
-------------------
- procedure Validate_Unit (U_Id : Unit_Id; Elab_Set : Membership_Set) is
+ procedure Validate_Unit
+ (U_Id : Unit_Id;
+ Elab_Set : Unit_Sets.Membership_Set)
+ is
begin
pragma Assert (Present (U_Id));
-- The current unit in the elaboration order appears within the set
-- of units that require elaboration. Remove it from the set.
- if Contains (Elab_Set, U_Id) then
- Delete (Elab_Set, U_Id);
+ if Unit_Sets.Contains (Elab_Set, U_Id) then
+ Unit_Sets.Delete (Elab_Set, U_Id);
-- Otherwise the current unit in the elaboration order must not be
-- elaborated.
@@ -208,7 +380,7 @@ package body Bindo.Validators is
--------------------
procedure Validate_Units (Order : Unit_Id_Table) is
- Elab_Set : Membership_Set;
+ Elab_Set : Unit_Sets.Membership_Set;
begin
-- Collect all units in the compilation that need to be elaborated
@@ -219,7 +391,7 @@ package body Bindo.Validators is
-- Validate each unit in the elaboration order against the set of
-- units that need to be elaborated.
- for Index in Unit_Id_Tables.First .. Unit_Id_Tables.Last (Order) loop
+ for Index in Unit_Id_Tables.First .. Unit_Id_Tables.Last (Order) loop
Validate_Unit
(U_Id => Order.Table (Index),
Elab_Set => Elab_Set);
@@ -230,21 +402,8 @@ package body Bindo.Validators is
-- their elaboration.
Report_Missing_Elaborations (Elab_Set);
- Destroy (Elab_Set);
+ Unit_Sets.Destroy (Elab_Set);
end Validate_Units;
-
- -----------------
- -- Write_Error --
- -----------------
-
- procedure Write_Error (Msg : String) is
- begin
- Has_Invalid_Data := True;
-
- Write_Str ("ERROR: ");
- Write_Str (Msg);
- Write_Eol;
- end Write_Error;
end Elaboration_Order_Validators;
---------------------------------
@@ -260,10 +419,10 @@ package body Bindo.Validators is
-----------------------
procedure Validate_Invocation_Graph_Edge
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id);
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id);
pragma Inline (Validate_Invocation_Graph_Edge);
- -- Verify that the attributes of edge IGE_Id of invocation graph G are
+ -- Verify that the attributes of edge Edge of invocation graph G are
-- properly set.
procedure Validate_Invocation_Graph_Edges (G : Invocation_Graph);
@@ -273,9 +432,9 @@ package body Bindo.Validators is
procedure Validate_Invocation_Graph_Vertex
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id);
+ Vertex : Invocation_Graph_Vertex_Id);
pragma Inline (Validate_Invocation_Graph_Vertex);
- -- Verify that the attributes of vertex IGV_Id of inbocation graph G are
+ -- Verify that the attributes of vertex Vertex of invocation graph G are
-- properly set.
procedure Validate_Invocation_Graph_Vertices (G : Invocation_Graph);
@@ -283,11 +442,6 @@ package body Bindo.Validators is
-- Verify that the attributes of all vertices of invocation graph G are
-- properly set.
- procedure Write_Error (Msg : String);
- pragma Inline (Write_Error);
- -- Write error message Msg to standard output and signal that the
- -- invocation graph is incorrect.
-
-------------------------------
-- Validate_Invocation_Graph --
-------------------------------
@@ -296,15 +450,19 @@ package body Bindo.Validators is
begin
pragma Assert (Present (G));
- -- Nothing to do when switch -d_V (validate bindo graphs and order)
- -- is not in effect.
+ -- Nothing to do when switch -d_V (validate bindo cycles, graphs, and
+ -- order) is not in effect.
if not Debug_Flag_Underscore_VV then
return;
end if;
+ Start_Phase (Invocation_Graph_Validation);
+
Validate_Invocation_Graph_Vertices (G);
- Validate_Invocation_Graph_Edges (G);
+ Validate_Invocation_Graph_Edges (G);
+
+ End_Phase (Invocation_Graph_Validation);
if Has_Invalid_Data then
raise Invalid_Invocation_Graph;
@@ -316,38 +474,38 @@ package body Bindo.Validators is
------------------------------------
procedure Validate_Invocation_Graph_Edge
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id)
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id)
is
Msg : constant String := "Validate_Invocation_Graph_Edge";
begin
pragma Assert (Present (G));
- if not Present (IGE_Id) then
- Write_Error (Msg);
+ if not Present (Edge) then
+ Write_Error (Msg, Has_Invalid_Data);
- Write_Str (" emply invocation graph edge");
+ Write_Str (" empty invocation graph edge");
Write_Eol;
Write_Eol;
return;
end if;
- if not Present (Relation (G, IGE_Id)) then
- Write_Error (Msg);
+ if not Present (Relation (G, Edge)) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" invocation graph edge (IGE_Id_");
- Write_Int (Int (IGE_Id));
+ Write_Int (Int (Edge));
Write_Str (") lacks Relation");
Write_Eol;
Write_Eol;
end if;
- if not Present (Target (G, IGE_Id)) then
- Write_Error (Msg);
+ if not Present (Target (G, Edge)) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" invocation graph edge (IGE_Id_");
- Write_Int (Int (IGE_Id));
+ Write_Int (Int (Edge));
Write_Str (") lacks Target");
Write_Eol;
Write_Eol;
@@ -359,17 +517,17 @@ package body Bindo.Validators is
-------------------------------------
procedure Validate_Invocation_Graph_Edges (G : Invocation_Graph) is
- IGE_Id : Invocation_Graph_Edge_Id;
- Iter : Invocation_Graphs.All_Edge_Iterator;
+ Edge : Invocation_Graph_Edge_Id;
+ Iter : Invocation_Graphs.All_Edge_Iterator;
begin
pragma Assert (Present (G));
Iter := Iterate_All_Edges (G);
while Has_Next (Iter) loop
- Next (Iter, IGE_Id);
+ Next (Iter, Edge);
- Validate_Invocation_Graph_Edge (G, IGE_Id);
+ Validate_Invocation_Graph_Edge (G, Edge);
end loop;
end Validate_Invocation_Graph_Edges;
@@ -379,38 +537,48 @@ package body Bindo.Validators is
procedure Validate_Invocation_Graph_Vertex
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id)
+ Vertex : Invocation_Graph_Vertex_Id)
is
Msg : constant String := "Validate_Invocation_Graph_Vertex";
begin
pragma Assert (Present (G));
- if not Present (IGV_Id) then
- Write_Error (Msg);
+ if not Present (Vertex) then
+ Write_Error (Msg, Has_Invalid_Data);
- Write_Str (" emply invocation graph vertex");
+ Write_Str (" empty invocation graph vertex");
Write_Eol;
Write_Eol;
return;
end if;
- if not Present (Construct (G, IGV_Id)) then
- Write_Error (Msg);
+ if not Present (Body_Vertex (G, Vertex)) then
+ Write_Error (Msg, Has_Invalid_Data);
+
+ Write_Str (" invocation graph vertex (IGV_Id_");
+ Write_Int (Int (Vertex));
+ Write_Str (") lacks Body_Vertex");
+ Write_Eol;
+ Write_Eol;
+ end if;
+
+ if not Present (Construct (G, Vertex)) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" invocation graph vertex (IGV_Id_");
- Write_Int (Int (IGV_Id));
+ Write_Int (Int (Vertex));
Write_Str (") lacks Construct");
Write_Eol;
Write_Eol;
end if;
- if not Present (Lib_Vertex (G, IGV_Id)) then
- Write_Error (Msg);
+ if not Present (Spec_Vertex (G, Vertex)) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" invocation graph vertex (IGV_Id_");
- Write_Int (Int (IGV_Id));
- Write_Str (") lacks Lib_Vertex");
+ Write_Int (Int (Vertex));
+ Write_Str (") lacks Spec_Vertex");
Write_Eol;
Write_Eol;
end if;
@@ -421,32 +589,19 @@ package body Bindo.Validators is
----------------------------------------
procedure Validate_Invocation_Graph_Vertices (G : Invocation_Graph) is
- IGV_Id : Invocation_Graph_Vertex_Id;
Iter : Invocation_Graphs.All_Vertex_Iterator;
+ Vertex : Invocation_Graph_Vertex_Id;
begin
pragma Assert (Present (G));
Iter := Iterate_All_Vertices (G);
while Has_Next (Iter) loop
- Next (Iter, IGV_Id);
+ Next (Iter, Vertex);
- Validate_Invocation_Graph_Vertex (G, IGV_Id);
+ Validate_Invocation_Graph_Vertex (G, Vertex);
end loop;
end Validate_Invocation_Graph_Vertices;
-
- -----------------
- -- Write_Error --
- -----------------
-
- procedure Write_Error (Msg : String) is
- begin
- Has_Invalid_Data := True;
-
- Write_Str ("ERROR: ");
- Write_Str (Msg);
- Write_Eol;
- end Write_Error;
end Invocation_Graph_Validators;
------------------------------
@@ -462,10 +617,10 @@ package body Bindo.Validators is
-----------------------
procedure Validate_Library_Graph_Edge
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id);
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Validate_Library_Graph_Edge);
- -- Verify that the attributes of edge LGE_Id of library graph G are
+ -- Verify that the attributes of edge Edge of library graph G are
-- properly set.
procedure Validate_Library_Graph_Edges (G : Library_Graph);
@@ -475,9 +630,9 @@ package body Bindo.Validators is
procedure Validate_Library_Graph_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id);
+ Vertex : Library_Graph_Vertex_Id);
pragma Inline (Validate_Library_Graph_Vertex);
- -- Verify that the attributes of vertex LGV_Id of library graph G are
+ -- Verify that the attributes of vertex Vertex of library graph G are
-- properly set.
procedure Validate_Library_Graph_Vertices (G : Library_Graph);
@@ -485,11 +640,6 @@ package body Bindo.Validators is
-- Verify that the attributes of all vertices of library graph G are
-- properly set.
- procedure Write_Error (Msg : String);
- pragma Inline (Write_Error);
- -- Write error message Msg to standard output and signal that the
- -- library graph is incorrect.
-
----------------------------
-- Validate_Library_Graph --
----------------------------
@@ -498,15 +648,19 @@ package body Bindo.Validators is
begin
pragma Assert (Present (G));
- -- Nothing to do when switch -d_V (validate bindo graphs and order)
- -- is not in effect.
+ -- Nothing to do when switch -d_V (validate bindo cycles, graphs, and
+ -- order) is not in effect.
if not Debug_Flag_Underscore_VV then
return;
end if;
+ Start_Phase (Library_Graph_Validation);
+
Validate_Library_Graph_Vertices (G);
- Validate_Library_Graph_Edges (G);
+ Validate_Library_Graph_Edges (G);
+
+ End_Phase (Library_Graph_Validation);
if Has_Invalid_Data then
raise Invalid_Library_Graph;
@@ -518,57 +672,57 @@ package body Bindo.Validators is
---------------------------------
procedure Validate_Library_Graph_Edge
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id)
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id)
is
Msg : constant String := "Validate_Library_Graph_Edge";
begin
pragma Assert (Present (G));
- if not Present (LGE_Id) then
- Write_Error (Msg);
+ if not Present (Edge) then
+ Write_Error (Msg, Has_Invalid_Data);
- Write_Str (" emply library graph edge");
+ Write_Str (" empty library graph edge");
Write_Eol;
Write_Eol;
return;
end if;
- if Kind (G, LGE_Id) = No_Edge then
- Write_Error (Msg);
+ if Kind (G, Edge) = No_Edge then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" library graph edge (LGE_Id_");
- Write_Int (Int (LGE_Id));
+ Write_Int (Int (Edge));
Write_Str (") is not a valid edge");
Write_Eol;
Write_Eol;
- elsif Kind (G, LGE_Id) = Body_Before_Spec_Edge then
- Write_Error (Msg);
+ elsif Kind (G, Edge) = Body_Before_Spec_Edge then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" library graph edge (LGE_Id_");
- Write_Int (Int (LGE_Id));
+ Write_Int (Int (Edge));
Write_Str (") is a Body_Before_Spec edge");
Write_Eol;
Write_Eol;
end if;
- if not Present (Predecessor (G, LGE_Id)) then
- Write_Error (Msg);
+ if not Present (Predecessor (G, Edge)) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" library graph edge (LGE_Id_");
- Write_Int (Int (LGE_Id));
+ Write_Int (Int (Edge));
Write_Str (") lacks Predecessor");
Write_Eol;
Write_Eol;
end if;
- if not Present (Successor (G, LGE_Id)) then
- Write_Error (Msg);
+ if not Present (Successor (G, Edge)) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" library graph edge (LGE_Id_");
- Write_Int (Int (LGE_Id));
+ Write_Int (Int (Edge));
Write_Str (") lacks Successor");
Write_Eol;
Write_Eol;
@@ -580,18 +734,17 @@ package body Bindo.Validators is
----------------------------------
procedure Validate_Library_Graph_Edges (G : Library_Graph) is
- Iter : Library_Graphs.All_Edge_Iterator;
- LGE_Id : Library_Graph_Edge_Id;
+ Edge : Library_Graph_Edge_Id;
+ Iter : Library_Graphs.All_Edge_Iterator;
begin
pragma Assert (Present (G));
Iter := Iterate_All_Edges (G);
while Has_Next (Iter) loop
- Next (Iter, LGE_Id);
- pragma Assert (Present (LGE_Id));
+ Next (Iter, Edge);
- Validate_Library_Graph_Edge (G, LGE_Id);
+ Validate_Library_Graph_Edge (G, Edge);
end loop;
end Validate_Library_Graph_Edges;
@@ -601,15 +754,15 @@ package body Bindo.Validators is
procedure Validate_Library_Graph_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id)
is
Msg : constant String := "Validate_Library_Graph_Vertex";
begin
pragma Assert (Present (G));
- if not Present (LGV_Id) then
- Write_Error (Msg);
+ if not Present (Vertex) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" empty library graph vertex");
Write_Eol;
@@ -617,25 +770,25 @@ package body Bindo.Validators is
return;
end if;
- if (Is_Body_With_Spec (G, LGV_Id)
+ if (Is_Body_With_Spec (G, Vertex)
or else
- Is_Spec_With_Body (G, LGV_Id))
- and then not Present (Corresponding_Item (G, LGV_Id))
+ Is_Spec_With_Body (G, Vertex))
+ and then not Present (Corresponding_Item (G, Vertex))
then
- Write_Error (Msg);
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" library graph vertex (LGV_Id_");
- Write_Int (Int (LGV_Id));
+ Write_Int (Int (Vertex));
Write_Str (") lacks Corresponding_Item");
Write_Eol;
Write_Eol;
end if;
- if not Present (Unit (G, LGV_Id)) then
- Write_Error (Msg);
+ if not Present (Unit (G, Vertex)) then
+ Write_Error (Msg, Has_Invalid_Data);
Write_Str (" library graph vertex (LGV_Id_");
- Write_Int (Int (LGV_Id));
+ Write_Int (Int (Vertex));
Write_Str (") lacks Unit");
Write_Eol;
Write_Eol;
@@ -648,32 +801,34 @@ package body Bindo.Validators is
procedure Validate_Library_Graph_Vertices (G : Library_Graph) is
Iter : Library_Graphs.All_Vertex_Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
begin
pragma Assert (Present (G));
Iter := Iterate_All_Vertices (G);
while Has_Next (Iter) loop
- Next (Iter, LGV_Id);
- pragma Assert (Present (LGV_Id));
+ Next (Iter, Vertex);
- Validate_Library_Graph_Vertex (G, LGV_Id);
+ Validate_Library_Graph_Vertex (G, Vertex);
end loop;
end Validate_Library_Graph_Vertices;
-
- -----------------
- -- Write_Error --
- -----------------
-
- procedure Write_Error (Msg : String) is
- begin
- Has_Invalid_Data := True;
-
- Write_Str ("ERROR: ");
- Write_Str (Msg);
- Write_Eol;
- end Write_Error;
end Library_Graph_Validators;
+ -----------------
+ -- Write_Error --
+ -----------------
+
+ procedure Write_Error
+ (Msg : String;
+ Flag : out Boolean)
+ is
+ begin
+ Write_Str ("ERROR: ");
+ Write_Str (Msg);
+ Write_Eol;
+
+ Flag := True;
+ end Write_Error;
+
end Bindo.Validators;
diff --git a/gcc/ada/bindo-validators.ads b/gcc/ada/bindo-validators.ads
index 39fccc6..d70447b 100644
--- a/gcc/ada/bindo-validators.ads
+++ b/gcc/ada/bindo-validators.ads
@@ -35,6 +35,26 @@ use Bindo.Graphs.Library_Graphs;
package Bindo.Validators is
+ ----------------------
+ -- Cycle_Validators --
+ ----------------------
+
+ package Cycle_Validators is
+ Invalid_Cycle : exception;
+ -- Exception raised when the library graph contains an invalid cycle
+
+ procedure Validate_Cycles (G : Library_Graph);
+ -- Ensure that all cycles of library graph G meet the following
+ -- requirements:
+ --
+ -- * Are of proper kind
+ -- * Have enough edges to form a circuit
+ -- * No edge is repeated
+ --
+ -- Diagnose issues and raise Invalid_Cycle if this is not the case.
+
+ end Cycle_Validators;
+
----------------------------------
-- Elaboration_Order_Validators --
----------------------------------
diff --git a/gcc/ada/bindo-writers.adb b/gcc/ada/bindo-writers.adb
index 7450c15..1fcfb11 100644
--- a/gcc/ada/bindo-writers.adb
+++ b/gcc/ada/bindo-writers.adb
@@ -23,12 +23,15 @@
-- --
------------------------------------------------------------------------------
-with Debug; use Debug;
-with Fname; use Fname;
-with Opt; use Opt;
-with Output; use Output;
+with Binderr; use Binderr;
+with Butil; use Butil;
+with Debug; use Debug;
+with Fname; use Fname;
+with Opt; use Opt;
+with Output; use Output;
-with Bindo.Units; use Bindo.Units;
+with Bindo.Units;
+use Bindo.Units;
with GNAT; use GNAT;
with GNAT.Graphs; use GNAT.Graphs;
@@ -124,26 +127,27 @@ package body Bindo.Writers is
--------------------------------
procedure Write_Invocation_Construct (IC_Id : Invocation_Construct_Id) is
+ begin
pragma Assert (Present (IC_Id));
- IC_Rec : Invocation_Construct_Record renames
- Invocation_Constructs.Table (IC_Id);
-
- begin
Write_Str (" invocation construct (IC_Id_");
Write_Int (Int (IC_Id));
Write_Str (")");
Write_Eol;
+ Write_Str (" Body_Placement = ");
+ Write_Str (Body_Placement (IC_Id)'Img);
+ Write_Eol;
+
Write_Str (" Kind = ");
- Write_Str (IC_Rec.Kind'Img);
+ Write_Str (Kind (IC_Id)'Img);
Write_Eol;
- Write_Str (" Placement = ");
- Write_Str (IC_Rec.Placement'Img);
+ Write_Str (" Spec_Placement = ");
+ Write_Str (Spec_Placement (IC_Id)'Img);
Write_Eol;
- Write_Invocation_Signature (IC_Rec.Signature);
+ Write_Invocation_Signature (Signature (IC_Id));
Write_Eol;
end Write_Invocation_Construct;
@@ -152,20 +156,17 @@ package body Bindo.Writers is
-------------------------------
procedure Write_Invocation_Relation (IR_Id : Invocation_Relation_Id) is
+ begin
pragma Assert (Present (IR_Id));
- IR_Rec : Invocation_Relation_Record renames
- Invocation_Relations.Table (IR_Id);
-
- begin
Write_Str (" invocation relation (IR_Id_");
Write_Int (Int (IR_Id));
Write_Str (")");
Write_Eol;
- if Present (IR_Rec.Extra) then
+ if Present (Extra (IR_Id)) then
Write_Str (" Extra = ");
- Write_Name (IR_Rec.Extra);
+ Write_Name (Extra (IR_Id));
else
Write_Str (" Extra = none");
end if;
@@ -174,16 +175,16 @@ package body Bindo.Writers is
Write_Str (" Invoker");
Write_Eol;
- Write_Invocation_Signature (IR_Rec.Invoker);
+ Write_Invocation_Signature (Invoker (IR_Id));
Write_Str (" Kind = ");
- Write_Str (IR_Rec.Kind'Img);
+ Write_Str (Kind (IR_Id)'Img);
Write_Eol;
Write_Str (" Target");
Write_Eol;
- Write_Invocation_Signature (IR_Rec.Target);
+ Write_Invocation_Signature (Target (IR_Id));
Write_Eol;
end Write_Invocation_Relation;
@@ -192,39 +193,36 @@ package body Bindo.Writers is
--------------------------------
procedure Write_Invocation_Signature (IS_Id : Invocation_Signature_Id) is
+ begin
pragma Assert (Present (IS_Id));
- IS_Rec : Invocation_Signature_Record renames
- Invocation_Signatures.Table (IS_Id);
-
- begin
Write_Str (" Signature (IS_Id_");
Write_Int (Int (IS_Id));
Write_Str (")");
Write_Eol;
Write_Str (" Column = ");
- Write_Int (Int (IS_Rec.Column));
+ Write_Int (Int (Column (IS_Id)));
Write_Eol;
Write_Str (" Line = ");
- Write_Int (Int (IS_Rec.Line));
+ Write_Int (Int (Line (IS_Id)));
Write_Eol;
- if Present (IS_Rec.Locations) then
+ if Present (Locations (IS_Id)) then
Write_Str (" Locations = ");
- Write_Name (IS_Rec.Locations);
+ Write_Name (Locations (IS_Id));
else
Write_Str (" Locations = none");
end if;
Write_Eol;
Write_Str (" Name = ");
- Write_Name (IS_Rec.Name);
+ Write_Name (Name (IS_Id));
Write_Eol;
Write_Str (" Scope = ");
- Write_Name (IS_Rec.Scope);
+ Write_Name (Scope (IS_Id));
Write_Eol;
end Write_Invocation_Signature;
@@ -275,19 +273,19 @@ package body Bindo.Writers is
Write_Int (Int (U_Rec.Last_Invocation_Relation));
Write_Str (")");
Write_Eol;
+
+ Write_Str (" Invocation_Graph_Encoding = ");
+ Write_Str (Invocation_Graph_Encoding (U_Id)'Img);
+ Write_Eol;
Write_Eol;
- for IC_Id in U_Rec.First_Invocation_Construct ..
- U_Rec.Last_Invocation_Construct
- loop
- Write_Invocation_Construct (IC_Id);
- end loop;
+ For_Each_Invocation_Construct
+ (U_Id => U_Id,
+ Processor => Write_Invocation_Construct'Access);
- for IR_Id in U_Rec.First_Invocation_Relation ..
- U_Rec.Last_Invocation_Relation
- loop
- Write_Invocation_Relation (IR_Id);
- end loop;
+ For_Each_Invocation_Relation
+ (U_Id => U_Id,
+ Processor => Write_Invocation_Relation'Access);
end Write_Unit;
-----------------------
@@ -313,6 +311,320 @@ package body Bindo.Writers is
end Write_Unit_Common;
end ALI_Writers;
+ -------------------
+ -- Cycle_Writers --
+ -------------------
+
+ package body Cycle_Writers is
+
+ -----------------------
+ -- Local subprograms --
+ -----------------------
+
+ procedure Write_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id);
+ pragma Inline (Write_Cycle);
+ -- Write the path of cycle Cycle found in library graph G to standard
+ -- output.
+
+ procedure Write_Cyclic_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id);
+ pragma Inline (Write_Cyclic_Edge);
+ -- Write cyclic edge Edge of library graph G to standard
+
+ -----------
+ -- Debug --
+ -----------
+
+ procedure palgc (G : Library_Graph) renames Write_Cycles;
+ pragma Unreferenced (palgc);
+
+ procedure plgc
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id) renames Write_Cycle;
+ pragma Unreferenced (plgc);
+
+ -----------------
+ -- Write_Cycle --
+ -----------------
+
+ procedure Write_Cycle
+ (G : Library_Graph;
+ Cycle : Library_Graph_Cycle_Id)
+ is
+ Edge : Library_Graph_Edge_Id;
+ Iter : Edges_Of_Cycle_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Cycle));
+
+ -- Nothing to do when switch -d_P (output cycle paths) is not in
+ -- effect.
+
+ if not Debug_Flag_Underscore_PP then
+ return;
+ end if;
+
+ Write_Str ("cycle (LGC_Id_");
+ Write_Int (Int (Cycle));
+ Write_Str (")");
+ Write_Eol;
+
+ Iter := Iterate_Edges_Of_Cycle (G, Cycle);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ Write_Cyclic_Edge (G, Edge);
+ end loop;
+
+ Write_Eol;
+ end Write_Cycle;
+
+ ------------------
+ -- Write_Cycles --
+ ------------------
+
+ procedure Write_Cycles (G : Library_Graph) is
+ Cycle : Library_Graph_Cycle_Id;
+ Iter : All_Cycle_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+
+ Iter := Iterate_All_Cycles (G);
+ while Has_Next (Iter) loop
+ Next (Iter, Cycle);
+
+ Write_Cycle (G, Cycle);
+ end loop;
+ end Write_Cycles;
+
+ -----------------------
+ -- Write_Cyclic_Edge --
+ -----------------------
+
+ procedure Write_Cyclic_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
+
+ begin
+ Indent_By (Nested_Indentation);
+ Write_Name (Name (G, Succ));
+ Write_Str (" --> ");
+ Write_Name (Name (G, Pred));
+ Write_Str (" ");
+
+ if Is_Elaborate_All_Edge (G, Edge) then
+ Write_Str ("Elaborate_All edge");
+
+ elsif Is_Elaborate_Body_Edge (G, Edge) then
+ Write_Str ("Elaborate_Body edge");
+
+ elsif Is_Elaborate_Edge (G, Edge) then
+ Write_Str ("Elaborate edge");
+
+ elsif Is_Forced_Edge (G, Edge) then
+ Write_Str ("forced edge");
+
+ elsif Is_Invocation_Edge (G, Edge) then
+ Write_Str ("invocation edge");
+
+ else
+ pragma Assert (Is_With_Edge (G, Edge));
+
+ Write_Str ("with edge");
+ end if;
+
+ Write_Eol;
+ end Write_Cyclic_Edge;
+ end Cycle_Writers;
+
+ ------------------------
+ -- Dependency_Writers --
+ ------------------------
+
+ package body Dependency_Writers is
+
+ -----------------------
+ -- Local subprograms --
+ -----------------------
+
+ procedure Write_Dependencies_Of_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id);
+ pragma Inline (Write_Dependencies_Of_Vertex);
+ -- Write the dependencies of vertex Vertex of library graph G to
+ -- standard output.
+
+ procedure Write_Dependency_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id);
+ pragma Inline (Write_Dependency_Edge);
+ -- Write the dependency described by edge Edge of library graph G to
+ -- standard output.
+
+ ------------------------
+ -- Write_Dependencies --
+ ------------------------
+
+ procedure Write_Dependencies (G : Library_Graph) is
+ Use_Formatting : constant Boolean := not Zero_Formatting;
+
+ Iter : Library_Graphs.All_Vertex_Iterator;
+ Vertex : Library_Graph_Vertex_Id;
+
+ begin
+ pragma Assert (Present (G));
+
+ -- Nothing to do when switch -e (output complete list of elaboration
+ -- order dependencies) is not in effect.
+
+ if not Elab_Dependency_Output then
+ return;
+ end if;
+
+ if Use_Formatting then
+ Write_Eol;
+ Write_Line ("ELABORATION ORDER DEPENDENCIES");
+ Write_Eol;
+ end if;
+
+ Info_Prefix_Suppress := True;
+
+ Iter := Iterate_All_Vertices (G);
+ while Has_Next (Iter) loop
+ Next (Iter, Vertex);
+
+ Write_Dependencies_Of_Vertex (G, Vertex);
+ end loop;
+
+ Info_Prefix_Suppress := False;
+
+ if Use_Formatting then
+ Write_Eol;
+ end if;
+ end Write_Dependencies;
+
+ ----------------------------------
+ -- Write_Dependencies_Of_Vertex --
+ ----------------------------------
+
+ procedure Write_Dependencies_Of_Vertex
+ (G : Library_Graph;
+ Vertex : Library_Graph_Vertex_Id)
+ is
+ Edge : Library_Graph_Edge_Id;
+ Iter : Edges_To_Successors_Iterator;
+
+ begin
+ pragma Assert (Present (G));
+ pragma Assert (Present (Vertex));
+
+ -- Nothing to do for internal and predefined units
+
+ if Is_Internal_Unit (G, Vertex)
+ or else Is_Predefined_Unit (G, Vertex)
+ then
+ return;
+ end if;
+
+ Iter := Iterate_Edges_To_Successors (G, Vertex);
+ while Has_Next (Iter) loop
+ Next (Iter, Edge);
+
+ Write_Dependency_Edge (G, Edge);
+ end loop;
+ end Write_Dependencies_Of_Vertex;
+
+ ---------------------------
+ -- Write_Dependency_Edge --
+ ---------------------------
+
+ procedure Write_Dependency_Edge
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id)
+ is
+ pragma Assert (Present (G));
+ pragma Assert (Present (Edge));
+
+ Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
+
+ begin
+ -- Nothing to do for internal and predefined units
+
+ if Is_Internal_Unit (G, Succ)
+ or else Is_Predefined_Unit (G, Succ)
+ then
+ return;
+ end if;
+
+ Error_Msg_Unit_1 := Name (G, Pred);
+ Error_Msg_Unit_2 := Name (G, Succ);
+ Error_Msg_Output
+ (Msg => " unit $ must be elaborated before unit $",
+ Info => True);
+
+ Error_Msg_Unit_1 := Name (G, Succ);
+ Error_Msg_Unit_2 := Name (G, Pred);
+
+ if Is_Elaborate_All_Edge (G, Edge) then
+ Error_Msg_Output
+ (Msg =>
+ " reason: unit $ has with clause and pragma "
+ & "Elaborate_All for unit $",
+ Info => True);
+
+ elsif Is_Elaborate_Body_Edge (G, Edge) then
+ Error_Msg_Output
+ (Msg => " reason: unit $ has with clause for unit $",
+ Info => True);
+
+ elsif Is_Elaborate_Edge (G, Edge) then
+ Error_Msg_Output
+ (Msg =>
+ " reason: unit $ has with clause and pragma Elaborate "
+ & "for unit $",
+ Info => True);
+
+ elsif Is_Forced_Edge (G, Edge) then
+ Error_Msg_Output
+ (Msg =>
+ " reason: unit $ has a dependency on unit $ forced by -f "
+ & "switch",
+ Info => True);
+
+ elsif Is_Invocation_Edge (G, Edge) then
+ Error_Msg_Output
+ (Msg =>
+ " reason: unit $ invokes a construct of unit $ at "
+ & "elaboration time",
+ Info => True);
+
+ elsif Is_Spec_Before_Body_Edge (G, Edge) then
+ Error_Msg_Output
+ (Msg => " reason: spec must be elaborated before body",
+ Info => True);
+
+ else
+ pragma Assert (Is_With_Edge (G, Edge));
+
+ Error_Msg_Output
+ (Msg => " reason: unit $ has with clause for unit $",
+ Info => True);
+ end if;
+ end Write_Dependency_Edge;
+ end Dependency_Writers;
+
-------------------------------
-- Elaboration_Order_Writers --
-------------------------------
@@ -336,25 +648,27 @@ package body Bindo.Writers is
-----------------------------
procedure Write_Elaboration_Order (Order : Unit_Id_Table) is
+ Use_Formatting : constant Boolean := not Zero_Formatting;
+
begin
- -- Nothing to do when switch -d_O (output elaboration order) is not
- -- in effect.
+ -- Nothing to do when switch -l (output chosen elaboration order) is
+ -- not in effect.
- if not Debug_Flag_Underscore_OO then
+ if not Elab_Order_Output then
return;
end if;
- Write_Str ("Elaboration Order");
- Write_Eol;
- Write_Eol;
+ if Use_Formatting then
+ Write_Eol;
+ Write_Str ("ELABORATION ORDER");
+ Write_Eol;
+ end if;
Write_Units (Order);
- Write_Eol;
- Write_Str ("Elaboration Order end");
- Write_Eol;
-
- Write_Eol;
+ if Use_Formatting then
+ Write_Eol;
+ end if;
end Write_Elaboration_Order;
----------------
@@ -362,13 +676,16 @@ package body Bindo.Writers is
----------------
procedure Write_Unit (U_Id : Unit_Id) is
+ Use_Formatting : constant Boolean := not Zero_Formatting;
+
begin
pragma Assert (Present (U_Id));
- Write_Str ("unit (U_Id_");
- Write_Int (Int (U_Id));
- Write_Str (") name = ");
- Write_Name (Name (U_Id));
+ if Use_Formatting then
+ Write_Str (" ");
+ end if;
+
+ Write_Unit_Name (Name (U_Id));
Write_Eol;
end Write_Unit;
@@ -416,22 +733,23 @@ package body Bindo.Writers is
-- Write all elaboration roots of invocation graph G to standard output
procedure Write_Invocation_Graph_Edge
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id);
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id);
pragma Inline (Write_Invocation_Graph_Edge);
- -- Write edge IGE_Id of invocation graph G to standard output
+ -- Write edge Edge of invocation graph G to standard output
procedure Write_Invocation_Graph_Edges
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id);
+ Vertex : Invocation_Graph_Vertex_Id);
pragma Inline (Write_Invocation_Graph_Edges);
- -- Write all edges of invocation graph G to standard output
+ -- Write all edges to targets of vertex Vertex of invocation graph G to
+ -- standard output.
procedure Write_Invocation_Graph_Vertex
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id);
+ Vertex : Invocation_Graph_Vertex_Id);
pragma Inline (Write_Invocation_Graph_Vertex);
- -- Write vertex IGV_Id of invocation graph G to standard output
+ -- Write vertex Vertex of invocation graph G to standard output
procedure Write_Invocation_Graph_Vertices (G : Invocation_Graph);
pragma Inline (Write_Invocation_Graph_Vertices);
@@ -447,14 +765,13 @@ package body Bindo.Writers is
-----------
procedure pige
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id)
- renames Write_Invocation_Graph_Edge;
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id) renames Write_Invocation_Graph_Edge;
pragma Unreferenced (pige);
procedure pigv
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id)
+ Vertex : Invocation_Graph_Vertex_Id)
renames Write_Invocation_Graph_Vertex;
pragma Unreferenced (pigv);
@@ -498,7 +815,6 @@ package body Bindo.Writers is
Iter := Iterate_Elaboration_Roots (G);
while Has_Next (Iter) loop
Next (Iter, Root);
- pragma Assert (Present (Root));
Write_Elaboration_Root (G, Root);
end loop;
@@ -541,24 +857,22 @@ package body Bindo.Writers is
---------------------------------
procedure Write_Invocation_Graph_Edge
- (G : Invocation_Graph;
- IGE_Id : Invocation_Graph_Edge_Id)
+ (G : Invocation_Graph;
+ Edge : Invocation_Graph_Edge_Id)
is
pragma Assert (Present (G));
- pragma Assert (Present (IGE_Id));
+ pragma Assert (Present (Edge));
- Targ : constant Invocation_Graph_Vertex_Id := Target (G, IGE_Id);
-
- pragma Assert (Present (Targ));
+ Targ : constant Invocation_Graph_Vertex_Id := Target (G, Edge);
begin
Write_Str (" invocation graph edge (IGE_Id_");
- Write_Int (Int (IGE_Id));
+ Write_Int (Int (Edge));
Write_Str (")");
Write_Eol;
Write_Str (" Relation (IR_Id_");
- Write_Int (Int (Relation (G, IGE_Id)));
+ Write_Int (Int (Relation (G, Edge)));
Write_Str (")");
Write_Eol;
@@ -577,16 +891,16 @@ package body Bindo.Writers is
procedure Write_Invocation_Graph_Edges
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id)
+ Vertex : Invocation_Graph_Vertex_Id)
is
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
Num_Of_Edges : constant Natural :=
- Number_Of_Edges_To_Targets (G, IGV_Id);
+ Number_Of_Edges_To_Targets (G, Vertex);
- IGE_Id : Invocation_Graph_Edge_Id;
- Iter : Invocation_Graphs.Edges_To_Targets_Iterator;
+ Edge : Invocation_Graph_Edge_Id;
+ Iter : Invocation_Graphs.Edges_To_Targets_Iterator;
begin
Write_Str (" Edges to targets: ");
@@ -594,12 +908,11 @@ package body Bindo.Writers is
Write_Eol;
if Num_Of_Edges > 0 then
- Iter := Iterate_Edges_To_Targets (G, IGV_Id);
+ Iter := Iterate_Edges_To_Targets (G, Vertex);
while Has_Next (Iter) loop
- Next (Iter, IGE_Id);
- pragma Assert (Present (IGE_Id));
+ Next (Iter, Edge);
- Write_Invocation_Graph_Edge (G, IGE_Id);
+ Write_Invocation_Graph_Edge (G, Edge);
end loop;
else
Write_Eol;
@@ -612,29 +925,34 @@ package body Bindo.Writers is
procedure Write_Invocation_Graph_Vertex
(G : Invocation_Graph;
- IGV_Id : Invocation_Graph_Vertex_Id)
+ Vertex : Invocation_Graph_Vertex_Id)
is
begin
pragma Assert (Present (G));
- pragma Assert (Present (IGV_Id));
+ pragma Assert (Present (Vertex));
Write_Str ("invocation graph vertex (IGV_Id_");
- Write_Int (Int (IGV_Id));
+ Write_Int (Int (Vertex));
Write_Str (") name = ");
- Write_Name (Name (G, IGV_Id));
+ Write_Name (Name (G, Vertex));
+ Write_Eol;
+
+ Write_Str (" Body_Vertex (LGV_Id_");
+ Write_Int (Int (Body_Vertex (G, Vertex)));
+ Write_Str (")");
Write_Eol;
Write_Str (" Construct (IC_Id_");
- Write_Int (Int (Construct (G, IGV_Id)));
+ Write_Int (Int (Construct (G, Vertex)));
Write_Str (")");
Write_Eol;
- Write_Str (" Lib_Vertex (LGV_Id_");
- Write_Int (Int (Lib_Vertex (G, IGV_Id)));
+ Write_Str (" Spec_Vertex (LGV_Id_");
+ Write_Int (Int (Spec_Vertex (G, Vertex)));
Write_Str (")");
Write_Eol;
- Write_Invocation_Graph_Edges (G, IGV_Id);
+ Write_Invocation_Graph_Edges (G, Vertex);
end Write_Invocation_Graph_Vertex;
-------------------------------------
@@ -642,18 +960,17 @@ package body Bindo.Writers is
-------------------------------------
procedure Write_Invocation_Graph_Vertices (G : Invocation_Graph) is
- IGV_Id : Invocation_Graph_Vertex_Id;
Iter : Invocation_Graphs.All_Vertex_Iterator;
+ Vertex : Invocation_Graph_Vertex_Id;
begin
pragma Assert (Present (G));
Iter := Iterate_All_Vertices (G);
while Has_Next (Iter) loop
- Next (Iter, IGV_Id);
- pragma Assert (Present (IGV_Id));
+ Next (Iter, Vertex);
- Write_Invocation_Graph_Vertex (G, IGV_Id);
+ Write_Invocation_Graph_Vertex (G, Vertex);
end loop;
end Write_Invocation_Graph_Vertices;
@@ -714,27 +1031,27 @@ package body Bindo.Writers is
-- output.
procedure Write_Components (G : Library_Graph);
- pragma Inline (Write_Components);
+ pragma Inline (Write_Component);
-- Write all components of library graph G to standard output
procedure Write_Edges_To_Successors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id);
+ Vertex : Library_Graph_Vertex_Id);
pragma Inline (Write_Edges_To_Successors);
- -- Write all edges to successors of predecessor LGV_Id of library graph
+ -- Write all edges to successors of predecessor Vertex of library graph
-- G to standard output.
procedure Write_Library_Graph_Edge
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id);
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id);
pragma Inline (Write_Library_Graph_Edge);
- -- Write edge LGE_Id of library graph G to standard output
+ -- Write edge Edge of library graph G to standard output
procedure Write_Library_Graph_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id);
+ Vertex : Library_Graph_Vertex_Id);
pragma Inline (Write_Library_Graph_Vertex);
- -- Write vertex LGV_Id of library graph G to standard output
+ -- Write vertex Vertex of library graph G to standard output
procedure Write_Library_Graph_Vertices (G : Library_Graph);
pragma Inline (Write_Library_Graph_Vertices);
@@ -755,13 +1072,13 @@ package body Bindo.Writers is
pragma Unreferenced (pc);
procedure plge
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id) renames Write_Library_Graph_Edge;
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id) renames Write_Library_Graph_Edge;
pragma Unreferenced (plge);
procedure plgv
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id) renames Write_Library_Graph_Vertex;
+ Vertex : Library_Graph_Vertex_Id) renames Write_Library_Graph_Vertex;
pragma Unreferenced (plgv);
---------------------
@@ -781,11 +1098,17 @@ package body Bindo.Writers is
Write_Str (")");
Write_Eol;
- Write_Str (" Pending_Predecessors = ");
- Write_Int (Int (Pending_Predecessors (G, Comp)));
+ Write_Str (" Pending_Strong_Predecessors = ");
+ Write_Int (Int (Pending_Strong_Predecessors (G, Comp)));
+ Write_Eol;
+
+ Write_Str (" Pending_Weak_Predecessors = ");
+ Write_Int (Int (Pending_Weak_Predecessors (G, Comp)));
Write_Eol;
Write_Component_Vertices (G, Comp);
+
+ Write_Eol;
end Write_Component;
------------------------------
@@ -796,26 +1119,34 @@ package body Bindo.Writers is
(G : Library_Graph;
Comp : Component_Id)
is
- Iter : Component_Vertex_Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
-
- begin
pragma Assert (Present (G));
pragma Assert (Present (Comp));
- Iter := Iterate_Component_Vertices (G, Comp);
- while Has_Next (Iter) loop
- Next (Iter, LGV_Id);
- pragma Assert (Present (LGV_Id));
+ Num_Of_Vertices : constant Natural :=
+ Number_Of_Component_Vertices (G, Comp);
- Write_Str (" library graph vertex (LGV_Id_");
- Write_Int (Int (LGV_Id));
- Write_Str (") name = ");
- Write_Name (Name (G, LGV_Id));
- Write_Eol;
- end loop;
+ Iter : Component_Vertex_Iterator;
+ Vertex : Library_Graph_Vertex_Id;
+ begin
+ Write_Str (" Vertices: ");
+ Write_Int (Int (Num_Of_Vertices));
Write_Eol;
+
+ if Num_Of_Vertices > 0 then
+ Iter := Iterate_Component_Vertices (G, Comp);
+ while Has_Next (Iter) loop
+ Next (Iter, Vertex);
+
+ Write_Str (" library graph vertex (LGV_Id_");
+ Write_Int (Int (Vertex));
+ Write_Str (") name = ");
+ Write_Name (Name (G, Vertex));
+ Write_Eol;
+ end loop;
+ else
+ Write_Eol;
+ end if;
end Write_Component_Vertices;
----------------------
@@ -831,17 +1162,36 @@ package body Bindo.Writers is
Iter : Component_Iterator;
begin
+ -- Nothing to do when switch -d_L (output library item graph) is not
+ -- in effect.
+
+ if not Debug_Flag_Underscore_LL then
+ return;
+ end if;
+
+ Write_Str ("Library Graph components");
+ Write_Eol;
+ Write_Eol;
+
if Num_Of_Comps > 0 then
+ Write_Str ("Components: ");
+ Write_Num (Int (Num_Of_Comps));
+ Write_Eol;
+
Iter := Iterate_Components (G);
while Has_Next (Iter) loop
Next (Iter, Comp);
- pragma Assert (Present (Comp));
Write_Component (G, Comp);
end loop;
else
Write_Eol;
end if;
+
+ Write_Str ("Library Graph components end");
+ Write_Eol;
+
+ Write_Eol;
end Write_Components;
-------------------------------
@@ -850,16 +1200,16 @@ package body Bindo.Writers is
procedure Write_Edges_To_Successors
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id)
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
Num_Of_Edges : constant Natural :=
- Number_Of_Edges_To_Successors (G, LGV_Id);
+ Number_Of_Edges_To_Successors (G, Vertex);
- Iter : Edges_To_Successors_Iterator;
- LGE_Id : Library_Graph_Edge_Id;
+ Edge : Library_Graph_Edge_Id;
+ Iter : Edges_To_Successors_Iterator;
begin
Write_Str (" Edges to successors: ");
@@ -867,12 +1217,11 @@ package body Bindo.Writers is
Write_Eol;
if Num_Of_Edges > 0 then
- Iter := Iterate_Edges_To_Successors (G, LGV_Id);
+ Iter := Iterate_Edges_To_Successors (G, Vertex);
while Has_Next (Iter) loop
- Next (Iter, LGE_Id);
- pragma Assert (Present (LGE_Id));
+ Next (Iter, Edge);
- Write_Library_Graph_Edge (G, LGE_Id);
+ Write_Library_Graph_Edge (G, Edge);
end loop;
else
Write_Eol;
@@ -913,26 +1262,23 @@ package body Bindo.Writers is
------------------------------
procedure Write_Library_Graph_Edge
- (G : Library_Graph;
- LGE_Id : Library_Graph_Edge_Id)
+ (G : Library_Graph;
+ Edge : Library_Graph_Edge_Id)
is
pragma Assert (Present (G));
- pragma Assert (Present (LGE_Id));
-
- Pred : constant Library_Graph_Vertex_Id := Predecessor (G, LGE_Id);
- Succ : constant Library_Graph_Vertex_Id := Successor (G, LGE_Id);
+ pragma Assert (Present (Edge));
- pragma Assert (Present (Pred));
- pragma Assert (Present (Succ));
+ Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge);
+ Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge);
begin
Write_Str (" library graph edge (LGE_Id_");
- Write_Int (Int (LGE_Id));
+ Write_Int (Int (Edge));
Write_Str (")");
Write_Eol;
Write_Str (" Kind = ");
- Write_Str (Kind (G, LGE_Id)'Img);
+ Write_Str (Kind (G, Edge)'Img);
Write_Eol;
Write_Str (" Predecessor (LGV_Id_");
@@ -956,22 +1302,20 @@ package body Bindo.Writers is
procedure Write_Library_Graph_Vertex
(G : Library_Graph;
- LGV_Id : Library_Graph_Vertex_Id)
+ Vertex : Library_Graph_Vertex_Id)
is
pragma Assert (Present (G));
- pragma Assert (Present (LGV_Id));
+ pragma Assert (Present (Vertex));
Item : constant Library_Graph_Vertex_Id :=
- Corresponding_Item (G, LGV_Id);
- U_Id : constant Unit_Id := Unit (G, LGV_Id);
-
- pragma Assert (Present (U_Id));
+ Corresponding_Item (G, Vertex);
+ U_Id : constant Unit_Id := Unit (G, Vertex);
begin
Write_Str ("library graph vertex (LGV_Id_");
- Write_Int (Int (LGV_Id));
+ Write_Int (Int (Vertex));
Write_Str (") name = ");
- Write_Name (Name (G, LGV_Id));
+ Write_Name (Name (G, Vertex));
Write_Eol;
if Present (Item) then
@@ -986,19 +1330,23 @@ package body Bindo.Writers is
Write_Eol;
Write_Str (" In_Elaboration_Order = ");
- if In_Elaboration_Order (G, LGV_Id) then
+ if In_Elaboration_Order (G, Vertex) then
Write_Str ("True");
else
Write_Str ("False");
end if;
Write_Eol;
- Write_Str (" Pending_Predecessors = ");
- Write_Int (Int (Pending_Predecessors (G, LGV_Id)));
+ Write_Str (" Pending_Strong_Predecessors = ");
+ Write_Int (Int (Pending_Strong_Predecessors (G, Vertex)));
+ Write_Eol;
+
+ Write_Str (" Pending_Weak_Predecessors = ");
+ Write_Int (Int (Pending_Weak_Predecessors (G, Vertex)));
Write_Eol;
Write_Str (" Component (Comp_Id_");
- Write_Int (Int (Component (G, LGV_Id)));
+ Write_Int (Int (Component (G, Vertex)));
Write_Str (")");
Write_Eol;
@@ -1008,7 +1356,7 @@ package body Bindo.Writers is
Write_Name (Name (U_Id));
Write_Eol;
- Write_Edges_To_Successors (G, LGV_Id);
+ Write_Edges_To_Successors (G, Vertex);
end Write_Library_Graph_Vertex;
----------------------------------
@@ -1017,17 +1365,16 @@ package body Bindo.Writers is
procedure Write_Library_Graph_Vertices (G : Library_Graph) is
Iter : Library_Graphs.All_Vertex_Iterator;
- LGV_Id : Library_Graph_Vertex_Id;
+ Vertex : Library_Graph_Vertex_Id;
begin
pragma Assert (Present (G));
Iter := Iterate_All_Vertices (G);
while Has_Next (Iter) loop
- Next (Iter, LGV_Id);
- pragma Assert (Present (LGV_Id));
+ Next (Iter, Vertex);
- Write_Library_Graph_Vertex (G, LGV_Id);
+ Write_Library_Graph_Vertex (G, Vertex);
end loop;
end Write_Library_Graph_Vertices;
@@ -1062,6 +1409,94 @@ package body Bindo.Writers is
end Write_Statistics;
end Library_Graph_Writers;
+ -------------------
+ -- Phase_Writers --
+ -------------------
+
+ package body Phase_Writers is
+
+ subtype Phase_Message is String (1 .. 32);
+
+ -- The following table contains the phase-specific messages for phase
+ -- completion.
+
+ End_Messages : constant array (Elaboration_Phase) of Phase_Message :=
+ (Component_Discovery => "components discovered. ",
+ Cycle_Diagnostics => "cycle diagnosed. ",
+ Cycle_Discovery => "cycles discovered. ",
+ Cycle_Validation => "cycles validated. ",
+ Elaboration_Order_Validation => "elaboration order validated. ",
+ Invocation_Graph_Construction => "invocation graph constructed. ",
+ Invocation_Graph_Validation => "invocation graph validated. ",
+ Library_Graph_Augmentation => "library graph augmented. ",
+ Library_Graph_Construction => "library graph constructed. ",
+ Library_Graph_Elaboration => "library graph elaborated. ",
+ Library_Graph_Validation => "library graph validated. ",
+ Unit_Collection => "units collected. ",
+ Unit_Elaboration => "units elaborated. ");
+
+ -- The following table contains the phase-specific messages for phase
+ -- commencement.
+
+ Start_Messages : constant array (Elaboration_Phase) of Phase_Message :=
+ (Component_Discovery => "discovering components... ",
+ Cycle_Diagnostics => "diagnosing cycle... ",
+ Cycle_Discovery => "discovering cycles... ",
+ Cycle_Validation => "validating cycles... ",
+ Elaboration_Order_Validation => "validating elaboration order... ",
+ Invocation_Graph_Construction => "constructing invocation graph...",
+ Invocation_Graph_Validation => "validating invocation graph... ",
+ Library_Graph_Augmentation => "augmenting library graph... ",
+ Library_Graph_Construction => "constructing library graph... ",
+ Library_Graph_Elaboration => "elaborating library graph... ",
+ Library_Graph_Validation => "validating library graph... ",
+ Unit_Collection => "collecting units... ",
+ Unit_Elaboration => "elaborating units... ");
+
+ -----------------------
+ -- Local subprograms --
+ -----------------------
+
+ procedure Write_Phase_Message (Msg : Phase_Message);
+ pragma Inline (Write_Phase_Message);
+ -- Write elaboration phase-related message Msg to standard output
+
+ ---------------
+ -- End_Phase --
+ ---------------
+
+ procedure End_Phase (Phase : Elaboration_Phase) is
+ begin
+ Write_Phase_Message (End_Messages (Phase));
+ end End_Phase;
+
+ -----------------
+ -- Start_Phase --
+ -----------------
+
+ procedure Start_Phase (Phase : Elaboration_Phase) is
+ begin
+ Write_Phase_Message (Start_Messages (Phase));
+ end Start_Phase;
+
+ -------------------------
+ -- Write_Phase_Message --
+ -------------------------
+
+ procedure Write_Phase_Message (Msg : Phase_Message) is
+ begin
+ -- Nothing to do when switch -d_S (output elaboration order status)
+ -- is not in effect.
+
+ if not Debug_Flag_Underscore_SS then
+ return;
+ end if;
+
+ Write_Str (Msg);
+ Write_Eol;
+ end Write_Phase_Message;
+ end Phase_Writers;
+
--------------------------
-- Unit_Closure_Writers --
--------------------------
@@ -1071,11 +1506,11 @@ package body Bindo.Writers is
pragma Inline (Hash_File_Name);
-- Obtain the hash value of key Nam
- package FS is new Membership_Sets
+ package File_Name_Tables is new Membership_Sets
(Element_Type => File_Name_Type,
"=" => "=",
Hash => Hash_File_Name);
- use FS;
+ use File_Name_Tables;
-----------------------
-- Local subprograms --
@@ -1128,10 +1563,12 @@ package body Bindo.Writers is
---------------------
procedure Write_File_Name (Nam : File_Name_Type) is
+ Use_Formatting : constant Boolean := not Zero_Formatting;
+
begin
pragma Assert (Present (Nam));
- if not Zero_Formatting then
+ if Use_Formatting then
Write_Str (" ");
end if;
@@ -1193,6 +1630,8 @@ package body Bindo.Writers is
------------------------
procedure Write_Unit_Closure (Order : Unit_Id_Table) is
+ Use_Formatting : constant Boolean := not Zero_Formatting;
+
Set : Membership_Set;
begin
@@ -1203,7 +1642,7 @@ package body Bindo.Writers is
return;
end if;
- if not Zero_Formatting then
+ if Use_Formatting then
Write_Eol;
Write_Line ("REFERENCED SOURCES");
end if;
@@ -1217,7 +1656,7 @@ package body Bindo.Writers is
Destroy (Set);
- if not Zero_Formatting then
+ if Use_Formatting then
Write_Eol;
end if;
end Write_Unit_Closure;
@@ -1290,7 +1729,7 @@ package body Bindo.Writers is
is
function Digits_Indentation return Indentation_Level;
pragma Inline (Digits_Indentation);
- -- Determine the level of indentation the number requies in order to
+ -- Determine the level of indentation the number requires in order to
-- be right-justified by Val_Indent.
------------------------
diff --git a/gcc/ada/bindo-writers.ads b/gcc/ada/bindo-writers.ads
index 9ed598e..66483d0 100644
--- a/gcc/ada/bindo-writers.ads
+++ b/gcc/ada/bindo-writers.ads
@@ -81,6 +81,27 @@ package Bindo.Writers is
end ALI_Writers;
+ -------------------
+ -- Cycle_Writers --
+ -------------------
+
+ package Cycle_Writers is
+ procedure Write_Cycles (G : Library_Graph);
+ -- Write all cycles of library graph G to standard output
+
+ end Cycle_Writers;
+
+ ------------------------
+ -- Dependency_Writers --
+ ------------------------
+
+ package Dependency_Writers is
+ procedure Write_Dependencies (G : Library_Graph);
+ -- Write all elaboration dependencies of the units represented by
+ -- vertices of library graph G.
+
+ end Dependency_Writers;
+
-------------------------------
-- Elaboration_Order_Writers --
-------------------------------
@@ -111,6 +132,23 @@ package Bindo.Writers is
end Library_Graph_Writers;
+ -------------------
+ -- Phase_Writers --
+ -------------------
+
+ package Phase_Writers is
+ procedure End_Phase (Phase : Elaboration_Phase);
+ pragma Inline (End_Phase);
+ -- Write the end message associated with elaboration phase Phase to
+ -- standard output.
+
+ procedure Start_Phase (Phase : Elaboration_Phase);
+ pragma Inline (Start_Phase);
+ -- Write the start message associated with elaboration phase Phase to
+ -- standard output.
+
+ end Phase_Writers;
+
--------------------------
-- Unit_Closure_Writers --
--------------------------
diff --git a/gcc/ada/bindo.adb b/gcc/ada/bindo.adb
index 7d26476..249ce972 100644
--- a/gcc/ada/bindo.adb
+++ b/gcc/ada/bindo.adb
@@ -23,16 +23,19 @@
-- --
------------------------------------------------------------------------------
+with Binde;
+with Opt; use Opt;
+
with Bindo.Elaborators;
-use Bindo.Elaborators.Invocation_And_Library_Graph_Elaborators;
+use Bindo.Elaborators;
package body Bindo is
---------------------------------
- -- Elaboration order mechanism --
+ -- Elaboration-order mechanism --
---------------------------------
- -- The elaboration order (EO) mechanism implemented in this unit and its
+ -- The elaboration-order (EO) mechanism implemented in this unit and its
-- children has the following objectives:
--
-- * Find an ordering of all library items (historically referred to as
@@ -47,30 +50,44 @@ package body Bindo is
-- - The flow of execution at elaboration time.
--
-- - Additional dependencies between units supplied to the binder by
- -- means of a file.
+ -- means of a forced-elaboration-order file.
+ --
+ -- The high-level idea empoyed by the EO mechanism is to construct two
+ -- graphs and use the information they represent to find an ordering of
+ -- all units.
--
- -- The high-level idea is to construct two graphs:
+ -- The invocation graph represents the flow of execution at elaboration
+ -- time.
--
- -- - Invocation graph - Models the flow of execution at elaboration
- -- time.
+ -- The library graph captures the dependencies between units expressed
+ -- by with clause and elaboration-related pragmas. The library graph is
+ -- further augmented with additional information from the invocation
+ -- graph by exploring the execution paths from a unit with elaboration
+ -- code to other external units.
--
- -- - Library graph - Represents with clause and pragma dependencies
- -- between units.
+ -- The strongly connected components of the library graph are computed.
--
- -- The library graph is further augmented with additional information
- -- from the invocation graph by exploring the execution paths from a
- -- unit with elaboration code to other external units. All strongly
- -- connected components of the library graph are discovered. Finally,
- -- the order is obtained via a topological sort-like algorithm which
- -- attempts to order available units while enabling other units to be
+ -- The order is obtained using a topological sort-like algorithm which
+ -- traverses the library graph and its strongly connected components in
+ -- an attempt to order available units while enabling other units to be
-- ordered.
--
-- * Diagnose elaboration circularities between units
--
- -- The library graph may contain at least one cycle, in which case no
- -- ordering is possible.
+ -- An elaboration circularity arises when either
+ --
+ -- - At least one unit cannot be ordered, or
+ --
+ -- - All units can be ordered, but an edge with an Elaborate_All
+ -- pragma links two vertices within the same component of the
+ -- library graph.
+ --
+ -- The library graph is traversed to discover, collect, and sort all
+ -- cycles that hinder the elaboration order.
--
- -- ??? more on this later
+ -- The most important cycle is diagnosed by describing its effects on
+ -- the elaboration order and listing all units comprising the circuit.
+ -- Various suggestions on how to break the cycle are offered.
-----------------
-- Terminology --
@@ -78,6 +95,14 @@ package body Bindo is
-- * Component - A strongly connected component of a graph.
--
+ -- * Elaborable component - A component that is not waiting on other
+ -- components to be elaborated.
+ --
+ -- * Elaborable vertex - A vertex that is not waiting on strong and weak
+ -- predecessors, and whose component is elaborable.
+ --
+ -- * Elaboration circularity - A cycle involving units from the bind.
+ --
-- * Elaboration root - A special invocation construct which denotes the
-- elaboration procedure of a unit.
--
@@ -117,8 +142,23 @@ package body Bindo is
-- * Pending predecessor - A vertex that must be elaborated before another
-- vertex can be elaborated.
--
+ -- * Strong edge - A non-invocation library graph edge. Strong edges
+ -- represent the language-defined relations between units.
+ --
+ -- * Strong predecessor - A library graph vertex reachable via a strong
+ -- edge.
+ --
-- * Target - The destination construct of an invocation relation (the
-- generic, subprogram, or task type).
+ --
+ -- * Weak edge - An invocation library graph edge. Weak edges represent
+ -- the speculative flow of execution at elaboration time, which may or
+ -- may not take place.
+ --
+ -- * Weak predecessor - A library graph vertex reachable via a weak edge.
+ --
+ -- * Weakly elaborable vertex - A vertex that is waiting solely on weak
+ -- predecessors to be elaborated, and whose component is elaborable.
------------------
-- Architecture --
@@ -162,7 +202,11 @@ package body Bindo is
-- |
-- +------ | -------------- Diagnostics phase -------------------------+
-- | | |
- -- | +--> ??? more on this later |
+ -- | +--> Find_Cycles |
+ -- | +--> Validate_Cycles |
+ -- | +--> Write_Cycles |
+ -- | | |
+ -- | +--> Diagnose_Cycle / Diagnose_All_Cycles |
-- | |
-- +-------------------------------------------------------------------+
@@ -210,7 +254,7 @@ package body Bindo is
-- bodies as single vertices.
--
-- * Try to order as many vertices of the library graph as possible by
- -- peforming a topological sort based on the pending predecessors of
+ -- performing a topological sort based on the pending predecessors of
-- vertices across all components and within a single component.
--
-- * Validate the consistency of the order, only when switch -d_V is in
@@ -225,17 +269,74 @@ package body Bindo is
-- Diagnostics phase --
-----------------------
- -- ??? more on this later
+ -- The Diagnostics phase has the following objectives:
+ --
+ -- * Discover, save, and sort all cycles in the library graph. The cycles
+ -- are sorted based on the following heuristics:
+ --
+ -- - A cycle with higher precedence is preferred.
+ --
+ -- - A cycle with fewer invocation edges is preferred.
+ --
+ -- - A cycle with a shorter length is preferred.
+ --
+ -- * Validate the consistency of cycles, only when switch -d_V is in
+ -- effect.
+ --
+ -- * Write the contents of all cycles in human-readable form to standard
+ -- output when switch -d_O is in effect.
+ --
+ -- * Diagnose the most important cycle, or all cycles when switch -d_C is
+ -- in effect. The diagnostic consists of:
+ --
+ -- - The reason for the existence of the cycle, along with the unit
+ -- whose elaboration cannot be guaranteed.
+ --
+ -- - A detailed traceback of the cycle, showcasing the transition
+ -- between units, along with any other elaboration-order-related
+ -- information.
+ --
+ -- - A set of suggestions on how to break the cycle considering the
+ -- the edges comprising the circuit, the elaboration model used to
+ -- compile the units, the availability of invocation information,
+ -- and the state of various relevant switches.
--------------
-- Switches --
--------------
+ -- -d_a Ignore the effects of pragma Elaborate_All
+ --
+ -- GNATbind creates a regular with edge instead of an Elaborate_All
+ -- edge in the library graph, thus eliminating the effects of the
+ -- pragma.
+ --
+ -- -d_b Ignore the effects of pragma Elaborate_Body
+ --
+ -- GNATbind treats a spec and body pair as decoupled.
+ --
+ -- -d_e Ignore the effects of pragma Elaborate
+ --
+ -- GNATbind creates a regular with edge instead of an Elaborate edge
+ -- in the library graph, thus eliminating the effects of the pragma.
+ -- In addition, GNATbind does not create an edge to the body of the
+ -- pragma argument.
+ --
+ -- -d_t Output cycle-detection trace information
+ --
+ -- GNATbind outputs trace information on cycle-detection activities
+ -- to standard output.
+ --
-- -d_A Output ALI invocation tables
--
-- GNATbind outputs the contents of ALI table Invocation_Constructs
-- and Invocation_Edges in textual format to standard output.
--
+ -- -d_C Diagnose all cycles
+ --
+ -- GNATbind outputs diagnostics for all unique cycles in the bind,
+ -- rather than just the most important one.
+ --
-- -d_I Output invocation graph
--
-- GNATbind outputs the invocation graph in text format to standard
@@ -246,31 +347,148 @@ package body Bindo is
-- GNATbind outputs the library graph in textual format to standard
-- output.
--
- -- -d_N New bindo order
+ -- -d_P Output cycle paths
--
- -- GNATbind utilizes the new bindo elaboration order
+ -- GNATbind outputs the cycle paths in text format to standard output
--
- -- -d_O Output elaboration order
+ -- -d_S Output elaboration-order status information
--
- -- GNATbind outputs the elaboration order in text format to standard
+ -- GNATbind outputs trace information concerning the status of its
+ -- various phases to standard output.
+ --
+ -- -d_T Output elaboration-order trace information
+ --
+ -- GNATbind outputs trace information on elaboration-order detection
+ -- activities to standard output.
+ --
+ -- -d_V Validate bindo cycles, graphs, and order
+ --
+ -- GNATbind validates the invocation graph, library graph along with
+ -- its cycles, and elaboration order by detecting inconsistencies and
+ -- producing error reports.
+ --
+ -- -e Output complete list of elaboration-order dependencies
+ --
+ -- GNATbind outputs the dependencies between units to standard
-- output.
--
- -- -d_T Output elaboration order trace information
+ -- -f Force elaboration order from given file
--
- -- GNATbind outputs trace information on elaboration order activities
- -- to standard output.
+ -- GNATbind applies an additional set of edges to the library graph.
+ -- The edges are read from a file specified by the argument of the
+ -- flag.
+ --
+ -- -H Legacy elaboration-order model enabled
+ --
+ -- GNATbind uses the library-graph and heuristics-based elaboration-
+ -- order model.
+ --
+ -- -l Output chosen elaboration order
+ --
+ -- GNATbind outputs the elaboration order in text format to standard
+ -- output.
--
- -- -d_V Validate bindo graphs and order
+ -- -p Pessimistic (worst-case) elaboration order
--
- -- GNATbind validates the invocation graph, library graph, SCC graph
- -- and elaboration order by detecting inconsistencies and producing
- -- error reports.
+ -- This switch is not used in Bindo and its children.
----------------------------------------
- -- Debugging elaboration order issues --
+ -- Debugging elaboration-order issues --
----------------------------------------
- -- ??? more on this later
+ -- Prior to debugging elaboration-order-related issues, enable all relevant
+ -- debug flags to collect as much information as possible. Depending on the
+ -- number of files in the bind, Bindo may emit anywhere between several MBs
+ -- to several hundred MBs of data to standard output. The switches are:
+ --
+ -- -d_A -d_C -d_I -d_L -d_P -d_t -d_T -d_V
+ --
+ -- Bindo offers several debugging routines that can be invoked from gdb.
+ -- Those are defined in the body of Bindo.Writers, in sections denoted by
+ -- header Debug. For quick reference, the routines are:
+ --
+ -- palgc -- print all library-graph cycles
+ -- pau -- print all units
+ -- pc -- print component
+ -- pige -- print invocation-graph edge
+ -- pigv -- print invocation-graph vertex
+ -- plgc -- print library-graph cycle
+ -- plge -- print library-graph edge
+ -- plgv -- print library-graph vertex
+ -- pu -- print units
+ --
+ -- * Apparent infinite loop
+ --
+ -- The elaboration order mechanism appears to be stuck in an infinite
+ -- loop. Use switch -d_S to output the status of each elaboration phase.
+ --
+ -- * Invalid elaboration order
+ --
+ -- The elaboration order is invalid when:
+ --
+ -- - A unit that requires elaboration is missing from the order
+ -- - A unit that does not require elaboration is present in the order
+ --
+ -- Examine the output of the elaboration algorithm available via switch
+ -- -d_T to determine how the related units were included in or excluded
+ -- from the order. Determine whether the library graph contains all the
+ -- relevant edges for those units.
+ --
+ -- Units and routines of interest:
+ -- Bindo.Elaborators
+ -- Elaborate_Library_Graph
+ -- Elaborate_Units
+ --
+ -- * Invalid invocation graph
+ --
+ -- The invocation graph is invalid when:
+ --
+ -- - An edge lacks an attribute
+ -- - A vertex lacks an attribute
+ --
+ -- Find the malformed edge or vertex and determine which attribute is
+ -- missing. Examine the contents of the invocation-related ALI tables
+ -- available via switch -d_A. If the invocation construct or relation
+ -- is missing, verify the ALI file. If the ALI lacks all the relevant
+ -- information, then Sem_Elab most likely failed to discover a valid
+ -- elaboration path.
+ --
+ -- Units and routines of interest:
+ -- Bindo.Builders
+ -- Bindo.Graphs
+ -- Add_Edge
+ -- Add_Vertex
+ -- Build_Invocation_Graph
+ --
+ -- * Invalid library graph
+ --
+ -- The library graph is invalid when:
+ --
+ -- - An edge lacks an attribute
+ -- - A vertex lacks an attribute
+ --
+ -- Find the malformed edge or vertex and determine which attribute is
+ -- missing.
+ --
+ -- Units and routines of interest:
+ -- Bindo.Builders
+ -- Bindo.Graphs
+ -- Add_Edge
+ -- Add_Vertex
+ -- Build_Library_Graph
+ --
+ -- * Invalid library-graph cycle
+ --
+ -- A library-graph cycle is invalid when:
+ --
+ -- - It lacks enough edges to form a circuit
+ -- - At least one edge in the circuit is repeated
+ --
+ -- Find the malformed cycle and determine which attribute is missing.
+ --
+ -- Units and routines of interest:
+ -- Bindo.Graphs
+ -- Find_Cycles
----------------------------
-- Find_Elaboration_Order --
@@ -281,7 +499,20 @@ package body Bindo is
Main_Lib_File : File_Name_Type)
is
begin
- Elaborate_Units (Order, Main_Lib_File);
+ -- Use the library graph and heuristic-based elaboration order when
+ -- switch -H (legacy elaboration-order mode enabled).
+
+ if Legacy_Elaboration_Order then
+ Binde.Find_Elab_Order (Order, Main_Lib_File);
+
+ -- Otherwise use the invocation and library-graph-based elaboration
+ -- order.
+
+ else
+ Invocation_And_Library_Graph_Elaborators.Elaborate_Units
+ (Order => Order,
+ Main_Lib_File => Main_Lib_File);
+ end if;
end Find_Elaboration_Order;
end Bindo;
diff --git a/gcc/ada/bindo.ads b/gcc/ada/bindo.ads
index 39cf7a4..ae35c95 100644
--- a/gcc/ada/bindo.ads
+++ b/gcc/ada/bindo.ads
@@ -31,6 +31,32 @@ with Namet; use Namet;
package Bindo is
+ -- The following type represents the various phases of the elaboration
+ -- order mechanism.
+
+ type Elaboration_Phase is
+ (Component_Discovery,
+ Cycle_Diagnostics,
+ Cycle_Discovery,
+ Cycle_Validation,
+ Elaboration_Order_Validation,
+ Invocation_Graph_Construction,
+ Invocation_Graph_Validation,
+ Library_Graph_Augmentation,
+ Library_Graph_Construction,
+ Library_Graph_Elaboration,
+ Library_Graph_Validation,
+ Unit_Collection,
+ Unit_Elaboration);
+
+ -- The following type represents the various kinds of precedence between
+ -- two items.
+
+ type Precedence_Kind is
+ (Lower_Precedence,
+ Equal_Precedence,
+ Higher_Precedence);
+
procedure Find_Elaboration_Order
(Order : out Unit_Id_Table;
Main_Lib_File : File_Name_Type);
diff --git a/gcc/ada/bindusg.adb b/gcc/ada/bindusg.adb
index 8c51d11..8331745 100644
--- a/gcc/ada/bindusg.adb
+++ b/gcc/ada/bindusg.adb
@@ -143,6 +143,11 @@ package body Bindusg is
Write_Line
(" -h Output this usage (help) information");
+ -- Line for -H switch
+
+ Write_Line
+ (" -H Legacy elaboration order model enabled");
+
-- Lines for -I switch
Write_Line
@@ -173,6 +178,12 @@ package body Bindusg is
(" -mnnn Limit number of detected errors/warnings to nnn "
& "(1-999999)");
+ -- Line for -minimal switch
+
+ Write_Line
+ (" -minimal Generate binder file suitable for space-constrained "
+ & "applications");
+
-- Line for -M switch
Write_Line
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 33fb27e..708bd9e 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -435,7 +435,7 @@ package body Checks is
-- Fall through for cases where we do set the flag
- Set_Do_Overflow_Check (N, True);
+ Set_Do_Overflow_Check (N);
Possible_Local_Raise (N, Standard_Constraint_Error);
end Activate_Overflow_Check;
@@ -577,8 +577,10 @@ package body Checks is
Typ : Entity_Id;
Insert_Node : Node_Id)
is
- Loc : constant Source_Ptr := Sloc (N);
- Param_Ent : Entity_Id := Param_Entity (N);
+ Loc : constant Source_Ptr := Sloc (N);
+
+ Check_Cond : Node_Id;
+ Param_Ent : Entity_Id := Param_Entity (N);
Param_Level : Node_Id;
Type_Level : Node_Id;
@@ -617,21 +619,49 @@ package body Checks is
Param_Level :=
New_Occurrence_Of (Extra_Accessibility (Param_Ent), Loc);
- Type_Level :=
- Make_Integer_Literal (Loc, Deepest_Type_Access_Level (Typ));
+ -- Use the dynamic accessibility parameter for the function's result
+ -- when one has been created instead of statically referring to the
+ -- deepest type level so as to appropriatly handle the rules for
+ -- RM 3.10.2 (10.1/3).
+
+ if Ekind_In (Scope (Param_Ent), E_Function,
+ E_Operator,
+ E_Subprogram_Type)
+ and then Present (Extra_Accessibility_Of_Result (Scope (Param_Ent)))
+ then
+ Type_Level :=
+ New_Occurrence_Of
+ (Extra_Accessibility_Of_Result (Scope (Param_Ent)), Loc);
+ else
+ Type_Level :=
+ Make_Integer_Literal (Loc, Deepest_Type_Access_Level (Typ));
+ end if;
-- Raise Program_Error if the accessibility level of the access
-- parameter is deeper than the level of the target access type.
+ Check_Cond :=
+ Make_Op_Gt (Loc,
+ Left_Opnd => Param_Level,
+ Right_Opnd => Type_Level);
+
Insert_Action (Insert_Node,
Make_Raise_Program_Error (Loc,
- Condition =>
- Make_Op_Gt (Loc,
- Left_Opnd => Param_Level,
- Right_Opnd => Type_Level),
- Reason => PE_Accessibility_Check_Failed));
+ Condition => Check_Cond,
+ Reason => PE_Accessibility_Check_Failed));
Analyze_And_Resolve (N);
+
+ -- If constant folding has happened on the condition for the
+ -- generated error, then warn about it being unconditional.
+
+ if Nkind (Check_Cond) = N_Identifier
+ and then Entity (Check_Cond) = Standard_True
+ then
+ Error_Msg_Warn := SPARK_Mode /= On;
+ Error_Msg_N ("accessibility check fails<<", N);
+ Error_Msg_N ("\Program_Error [<<", N);
+ end if;
end if;
end Apply_Accessibility_Check;
@@ -2707,6 +2737,41 @@ package body Checks is
-- Here for normal case of predicate active
else
+ -- If the expression is an IN parameter, the predicate will have
+ -- been applied at the point of call. An additional check would
+ -- be redundant, or will lead to out-of-scope references if the
+ -- call appears within an aspect specification for a precondition.
+
+ -- However, if the reference is within the body of the subprogram
+ -- that declares the formal, the predicate can safely be applied,
+ -- which may be necessary for a nested call whose formal has a
+ -- different predicate.
+
+ if Is_Entity_Name (N)
+ and then Ekind (Entity (N)) = E_In_Parameter
+ then
+ declare
+ In_Body : Boolean := False;
+ P : Node_Id := Parent (N);
+
+ begin
+ while Present (P) loop
+ if Nkind (P) = N_Subprogram_Body
+ and then Corresponding_Spec (P) = Scope (Entity (N))
+ then
+ In_Body := True;
+ exit;
+ end if;
+
+ P := Parent (P);
+ end loop;
+
+ if not In_Body then
+ return;
+ end if;
+ end;
+ end if;
+
-- If the type has a static predicate and the expression is known
-- at compile time, see if the expression satisfies the predicate.
@@ -3557,13 +3622,14 @@ package body Checks is
-- will not be generated.
if GNATprove_Mode
- or else not Is_Fixed_Point_Type (Expr_Type)
+ or else (not Is_Fixed_Point_Type (Expr_Type)
+ and then not Is_Fixed_Point_Type (Target_Type))
then
Apply_Scalar_Range_Check
(Expr, Target_Type, Fixed_Int => Conv_OK);
else
- Set_Do_Range_Check (Expression (N), False);
+ Set_Do_Range_Check (Expr, False);
end if;
-- If the target type has predicates, we need to indicate
@@ -6775,18 +6841,19 @@ package body Checks is
Source_Base_Type : constant Entity_Id := Base_Type (Source_Type);
Target_Base_Type : constant Entity_Id := Base_Type (Target_Type);
- procedure Convert_And_Check_Range;
- -- Convert the conversion operand to the target base type and save in
- -- a temporary. Then check the converted value against the range of the
- -- target subtype.
+ procedure Convert_And_Check_Range (Suppress : Check_Id);
+ -- Convert N to the target base type and save the result in a temporary.
+ -- The action is analyzed using the default checks as modified by the
+ -- given Suppress argument. Then check the converted value against the
+ -- range of the target subtype.
-----------------------------
-- Convert_And_Check_Range --
-----------------------------
- procedure Convert_And_Check_Range is
- Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
- Conv_Node : Node_Id;
+ procedure Convert_And_Check_Range (Suppress : Check_Id) is
+ Tnn : constant Entity_Id := Make_Temporary (Loc, 'T', N);
+ Conv_N : Node_Id;
begin
-- For enumeration types with non-standard representation this is a
@@ -6801,36 +6868,26 @@ package body Checks is
and then Present (Enum_Pos_To_Rep (Source_Base_Type))
and then Is_Integer_Type (Target_Base_Type)
then
- Conv_Node :=
- OK_Convert_To
- (Typ => Target_Base_Type,
- Expr => Duplicate_Subexpr (N));
-
- -- Common case
-
+ Conv_N := OK_Convert_To (Target_Base_Type, Duplicate_Subexpr (N));
else
- Conv_Node :=
- Make_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Target_Base_Type, Loc),
- Expression => Duplicate_Subexpr (N));
+ Conv_N := Convert_To (Target_Base_Type, Duplicate_Subexpr (N));
end if;
- -- We make a temporary to hold the value of the converted value
- -- (converted to the base type), and then do the test against this
- -- temporary. The conversion itself is replaced by an occurrence of
- -- Tnn and followed by the explicit range check. Note that checks
- -- are suppressed for this code, since we don't want a recursive
- -- range check popping up.
+ -- We make a temporary to hold the value of the conversion to the
+ -- target base type, and then do the test against this temporary.
+ -- N itself is replaced by an occurrence of Tnn and followed by
+ -- the explicit range check.
-- Tnn : constant Target_Base_Type := Target_Base_Type (N);
-- [constraint_error when Tnn not in Target_Type]
+ -- Tnn
Insert_Actions (N, New_List (
Make_Object_Declaration (Loc,
Defining_Identifier => Tnn,
Object_Definition => New_Occurrence_Of (Target_Base_Type, Loc),
Constant_Present => True,
- Expression => Conv_Node),
+ Expression => Conv_N),
Make_Raise_Constraint_Error (Loc,
Condition =>
@@ -6838,7 +6895,7 @@ package body Checks is
Left_Opnd => New_Occurrence_Of (Tnn, Loc),
Right_Opnd => New_Occurrence_Of (Target_Type, Loc)),
Reason => Reason)),
- Suppress => All_Checks);
+ Suppress => Suppress);
Rewrite (N, New_Occurrence_Of (Tnn, Loc));
@@ -6855,7 +6912,7 @@ package body Checks is
-- First special case, if the source type is already within the range
-- of the target type, then no check is needed (probably we should have
-- stopped Do_Range_Check from being set in the first place, but better
- -- late than never in preventing junk code and junk flag settings.
+ -- late than never in preventing junk code and junk flag settings).
if In_Subrange_Of (Source_Type, Target_Type)
@@ -6932,7 +6989,8 @@ package body Checks is
-- Next test for the case where the target type is within the bounds
-- of the base type of the source type, since in this case we can
- -- simply convert these bounds to the base type of T to do the test.
+ -- simply convert the bounds of the target type to this base bype
+ -- to do the test.
-- [constraint_error when N not in
-- Source_Base_Type (Target_Type'First)
@@ -6981,26 +7039,32 @@ package body Checks is
Suppress => All_Checks);
-- For conversions involving at least one type that is not discrete,
- -- first convert to target type and then generate the range check.
- -- This avoids problems with values that are close to a bound of the
- -- target type that would fail a range check when done in a larger
- -- source type before converting but would pass if converted with
+ -- first convert to the target base type and then generate the range
+ -- check. This avoids problems with values that are close to a bound
+ -- of the target type that would fail a range check when done in a
+ -- larger source type before converting but pass if converted with
-- rounding and then checked (such as in float-to-float conversions).
+ -- Note that overflow checks are not suppressed for this code because
+ -- we do not know whether the source type is in range of the target
+ -- base type (unlike in the next case below).
+
else
- Convert_And_Check_Range;
+ Convert_And_Check_Range (Suppress => Range_Check);
end if;
- -- Note that at this stage we now that the Target_Base_Type is not in
+ -- Note that at this stage we know that the Target_Base_Type is not in
-- the range of the Source_Base_Type (since even the Target_Type itself
-- is not in this range). It could still be the case that Source_Type is
-- in range of the target base type since we have not checked that case.
-- If that is the case, we can freely convert the source to the target,
- -- and then test the target result against the bounds.
+ -- and then test the target result against the bounds. Note that checks
+ -- are suppressed for this code, since we don't want a recursive range
+ -- check popping up.
elsif In_Subrange_Of (Source_Type, Target_Base_Type) then
- Convert_And_Check_Range;
+ Convert_And_Check_Range (Suppress => All_Checks);
-- At this stage, we know that we have two scalar types, which are
-- directly convertible, and where neither scalar type has a base
diff --git a/gcc/ada/cio.c b/gcc/ada/cio.c
index dd91a3e..7fca412 100644
--- a/gcc/ada/cio.c
+++ b/gcc/ada/cio.c
@@ -30,8 +30,7 @@
****************************************************************************/
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
+#include "runtime.h"
#include <sys/stat.h>
#else
#include "config.h"
diff --git a/gcc/ada/clean.adb b/gcc/ada/clean.adb
index fa522ee..565d22e 100644
--- a/gcc/ada/clean.adb
+++ b/gcc/ada/clean.adb
@@ -854,7 +854,7 @@ package body Clean is
then
Project_File_Name :=
new String'
- (Prj (Prj'First + 1 .. Prj'Last));
+ (Prj (Prj'First + 1 .. Prj'Last));
else
Project_File_Name := new String'(Prj);
end if;
diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb
index af7c1b9..4610b53 100644
--- a/gcc/ada/contracts.adb
+++ b/gcc/ada/contracts.adb
@@ -25,7 +25,6 @@
with Aspects; use Aspects;
with Atree; use Atree;
-with Debug; use Debug;
with Einfo; use Einfo;
with Elists; use Elists;
with Errout; use Errout;
@@ -51,7 +50,6 @@ with Sinfo; use Sinfo;
with Snames; use Snames;
with Stand; use Stand;
with Stringt; use Stringt;
-with SCIL_LL; use SCIL_LL;
with Tbuild; use Tbuild;
package body Contracts is
@@ -63,11 +61,6 @@ package body Contracts is
--
-- Part_Of
- procedure Build_And_Analyze_Contract_Only_Subprograms (L : List_Id);
- -- (CodePeer): Subsidiary procedure to Analyze_Contracts which builds the
- -- contract-only subprogram body of eligible subprograms found in L, adds
- -- them to their corresponding list of declarations, and analyzes them.
-
procedure Expand_Subprogram_Contract (Body_Id : Entity_Id);
-- Expand the contracts of a subprogram body and its correspoding spec (if
-- any). This routine processes all [refined] pre- and postconditions as
@@ -354,10 +347,6 @@ package body Contracts is
Decl : Node_Id;
begin
- if CodePeer_Mode and then Debug_Flag_Dot_KK then
- Build_And_Analyze_Contract_Only_Subprograms (L);
- end if;
-
Decl := First (L);
while Present (Decl) loop
@@ -1305,490 +1294,6 @@ package body Contracts is
Restore_SPARK_Mode (Saved_SM, Saved_SMP);
end Analyze_Task_Contract;
- -------------------------------------------------
- -- Build_And_Analyze_Contract_Only_Subprograms --
- -------------------------------------------------
-
- procedure Build_And_Analyze_Contract_Only_Subprograms (L : List_Id) is
- procedure Analyze_Contract_Only_Subprograms;
- -- Analyze the contract-only subprograms of L
-
- procedure Append_Contract_Only_Subprograms (Subp_List : List_Id);
- -- Append the contract-only bodies of Subp_List to its declarations list
-
- function Build_Contract_Only_Subprogram (E : Entity_Id) return Node_Id;
- -- If E is an entity for a non-imported subprogram specification with
- -- pre/postconditions and we are compiling with CodePeer mode, then
- -- this procedure will create a wrapper to help Gnat2scil process its
- -- contracts. Return Empty if the wrapper cannot be built.
-
- function Build_Contract_Only_Subprograms (L : List_Id) return List_Id;
- -- Build the contract-only subprograms of all eligible subprograms found
- -- in list L.
-
- function Has_Private_Declarations (N : Node_Id) return Boolean;
- -- Return True for package specs, task definitions, and protected type
- -- definitions whose list of private declarations is not empty.
-
- ---------------------------------------
- -- Analyze_Contract_Only_Subprograms --
- ---------------------------------------
-
- procedure Analyze_Contract_Only_Subprograms is
- procedure Analyze_Contract_Only_Bodies;
- -- Analyze all the contract-only bodies of L
-
- ----------------------------------
- -- Analyze_Contract_Only_Bodies --
- ----------------------------------
-
- procedure Analyze_Contract_Only_Bodies is
- Decl : Node_Id;
-
- begin
- Decl := First (L);
- while Present (Decl) loop
- if Nkind (Decl) = N_Subprogram_Body
- and then Is_Contract_Only_Body
- (Defining_Unit_Name (Specification (Decl)))
- then
- Analyze (Decl);
- end if;
-
- Next (Decl);
- end loop;
- end Analyze_Contract_Only_Bodies;
-
- -- Start of processing for Analyze_Contract_Only_Subprograms
-
- begin
- if Ekind (Current_Scope) /= E_Package then
- Analyze_Contract_Only_Bodies;
-
- else
- declare
- Pkg_Spec : constant Node_Id :=
- Package_Specification (Current_Scope);
-
- begin
- if not Has_Private_Declarations (Pkg_Spec) then
- Analyze_Contract_Only_Bodies;
-
- -- For packages with private declarations, the contract-only
- -- bodies of subprograms defined in the visible part of the
- -- package are added to its private declarations (to ensure
- -- that they do not cause premature freezing of types and also
- -- that they are analyzed with proper visibility). Hence they
- -- will be analyzed later.
-
- elsif Visible_Declarations (Pkg_Spec) = L then
- null;
-
- elsif Private_Declarations (Pkg_Spec) = L then
- Analyze_Contract_Only_Bodies;
- end if;
- end;
- end if;
- end Analyze_Contract_Only_Subprograms;
-
- --------------------------------------
- -- Append_Contract_Only_Subprograms --
- --------------------------------------
-
- procedure Append_Contract_Only_Subprograms (Subp_List : List_Id) is
- begin
- if No (Subp_List) then
- return;
- end if;
-
- if Ekind (Current_Scope) /= E_Package then
- Append_List (Subp_List, To => L);
-
- else
- declare
- Pkg_Spec : constant Node_Id :=
- Package_Specification (Current_Scope);
-
- begin
- if not Has_Private_Declarations (Pkg_Spec) then
- Append_List (Subp_List, To => L);
-
- -- If the package has private declarations then append them to
- -- its private declarations; they will be analyzed when the
- -- contracts of its private declarations are analyzed.
-
- else
- Append_List
- (List => Subp_List,
- To => Private_Declarations (Pkg_Spec));
- end if;
- end;
- end if;
- end Append_Contract_Only_Subprograms;
-
- ------------------------------------
- -- Build_Contract_Only_Subprogram --
- ------------------------------------
-
- -- This procedure takes care of building a wrapper to generate better
- -- analysis results in the case of a call to a subprogram whose body
- -- is unavailable to CodePeer but whose specification includes Pre/Post
- -- conditions. The body might be unavailable for any of a number or
- -- reasons (it is imported, the .adb file is simply missing, or the
- -- subprogram might be subject to an Annotate (CodePeer, Skip_Analysis)
- -- pragma). The built subprogram has the following contents:
- -- * check preconditions
- -- * call the subprogram
- -- * check postconditions
-
- function Build_Contract_Only_Subprogram (E : Entity_Id) return Node_Id is
- Loc : constant Source_Ptr := Sloc (E);
-
- Missing_Body_Name : constant Name_Id :=
- New_External_Name (Chars (E), "__missing_body");
-
- function Build_Missing_Body_Decls return List_Id;
- -- Build the declaration of the missing body subprogram and its
- -- corresponding pragma Import.
-
- function Build_Missing_Body_Subprogram_Call return Node_Id;
- -- Build the call to the missing body subprogram
-
- function Skip_Contract_Only_Subprogram (E : Entity_Id) return Boolean;
- -- Return True for cases where the wrapper is not needed or we cannot
- -- build it.
-
- ------------------------------
- -- Build_Missing_Body_Decls --
- ------------------------------
-
- function Build_Missing_Body_Decls return List_Id is
- Spec : constant Node_Id := Declaration_Node (E);
- Decl : Node_Id;
- Prag : Node_Id;
-
- begin
- Decl :=
- Make_Subprogram_Declaration (Loc, Copy_Subprogram_Spec (Spec));
- Set_Chars (Defining_Entity (Decl), Missing_Body_Name);
-
- Prag :=
- Make_Pragma (Loc,
- Chars => Name_Import,
- Pragma_Argument_Associations => New_List (
- Make_Pragma_Argument_Association (Loc,
- Expression => Make_Identifier (Loc, Name_Ada)),
-
- Make_Pragma_Argument_Association (Loc,
- Expression => Make_Identifier (Loc, Missing_Body_Name))));
-
- return New_List (Decl, Prag);
- end Build_Missing_Body_Decls;
-
- ----------------------------------------
- -- Build_Missing_Body_Subprogram_Call --
- ----------------------------------------
-
- function Build_Missing_Body_Subprogram_Call return Node_Id is
- Forml : Entity_Id;
- Parms : List_Id;
-
- begin
- Parms := New_List;
-
- -- Build parameter list that we need
-
- Forml := First_Formal (E);
- while Present (Forml) loop
- Append_To (Parms, Make_Identifier (Loc, Chars (Forml)));
- Next_Formal (Forml);
- end loop;
-
- -- Build the call to the missing body subprogram
-
- if Ekind_In (E, E_Function, E_Generic_Function) then
- return
- Make_Simple_Return_Statement (Loc,
- Expression =>
- Make_Function_Call (Loc,
- Name =>
- Make_Identifier (Loc, Missing_Body_Name),
- Parameter_Associations => Parms));
-
- else
- return
- Make_Procedure_Call_Statement (Loc,
- Name =>
- Make_Identifier (Loc, Missing_Body_Name),
- Parameter_Associations => Parms);
- end if;
- end Build_Missing_Body_Subprogram_Call;
-
- -----------------------------------
- -- Skip_Contract_Only_Subprogram --
- -----------------------------------
-
- function Skip_Contract_Only_Subprogram
- (E : Entity_Id) return Boolean
- is
- function Depends_On_Enclosing_Private_Type return Boolean;
- -- Return True if some formal of E (or its return type) are
- -- private types defined in an enclosing package.
-
- function Some_Enclosing_Package_Has_Private_Decls return Boolean;
- -- Return True if some enclosing package of the current scope has
- -- private declarations.
-
- ---------------------------------------
- -- Depends_On_Enclosing_Private_Type --
- ---------------------------------------
-
- function Depends_On_Enclosing_Private_Type return Boolean is
- function Defined_In_Enclosing_Package
- (Typ : Entity_Id) return Boolean;
- -- Return True if Typ is an entity defined in an enclosing
- -- package of the current scope.
-
- ----------------------------------
- -- Defined_In_Enclosing_Package --
- ----------------------------------
-
- function Defined_In_Enclosing_Package
- (Typ : Entity_Id) return Boolean
- is
- Scop : Entity_Id := Scope (Current_Scope);
-
- begin
- while Scop /= Scope (Typ)
- and then not Is_Compilation_Unit (Scop)
- loop
- Scop := Scope (Scop);
- end loop;
-
- return Scop = Scope (Typ);
- end Defined_In_Enclosing_Package;
-
- -- Local variables
-
- Param_E : Entity_Id;
- Typ : Entity_Id;
-
- -- Start of processing for Depends_On_Enclosing_Private_Type
-
- begin
- Param_E := First_Entity (E);
- while Present (Param_E) loop
- Typ := Etype (Param_E);
-
- if Is_Private_Type (Typ)
- and then Defined_In_Enclosing_Package (Typ)
- then
- return True;
- end if;
-
- Next_Entity (Param_E);
- end loop;
-
- return
- Ekind (E) = E_Function
- and then Is_Private_Type (Etype (E))
- and then Defined_In_Enclosing_Package (Etype (E));
- end Depends_On_Enclosing_Private_Type;
-
- ----------------------------------------------
- -- Some_Enclosing_Package_Has_Private_Decls --
- ----------------------------------------------
-
- function Some_Enclosing_Package_Has_Private_Decls return Boolean is
- Scop : Entity_Id := Current_Scope;
- Pkg_Spec : Node_Id := Package_Specification (Scop);
-
- begin
- loop
- if Ekind (Scop) = E_Package
- and then Has_Private_Declarations
- (Package_Specification (Scop))
- then
- Pkg_Spec := Package_Specification (Scop);
- end if;
-
- exit when Is_Compilation_Unit (Scop);
- Scop := Scope (Scop);
- end loop;
-
- return Pkg_Spec /= Package_Specification (Current_Scope);
- end Some_Enclosing_Package_Has_Private_Decls;
-
- -- Start of processing for Skip_Contract_Only_Subprogram
-
- begin
- if not CodePeer_Mode
- or else Inside_A_Generic
- or else not Is_Subprogram (E)
- or else Is_Abstract_Subprogram (E)
- or else Is_Imported (E)
- or else No (Contract (E))
- or else No (Pre_Post_Conditions (Contract (E)))
- or else Is_Contract_Only_Body (E)
- or else Convention (E) = Convention_Protected
- then
- return True;
-
- -- We do not support building the contract-only subprogram if E
- -- is a subprogram declared in a nested package that has some
- -- formal or return type depending on a private type defined in
- -- an enclosing package.
-
- elsif Ekind (Current_Scope) = E_Package
- and then Some_Enclosing_Package_Has_Private_Decls
- and then Depends_On_Enclosing_Private_Type
- then
- if Debug_Flag_Dot_KK then
- declare
- Saved_Mode : constant Warning_Mode_Type := Warning_Mode;
-
- begin
- -- Warnings are disabled by default under CodePeer_Mode
- -- (see switch-c). Enable them temporarily.
-
- Warning_Mode := Normal;
- Error_Msg_N
- ("cannot generate contract-only subprogram?", E);
- Warning_Mode := Saved_Mode;
- end;
- end if;
-
- return True;
- end if;
-
- return False;
- end Skip_Contract_Only_Subprogram;
-
- -- Start of processing for Build_Contract_Only_Subprogram
-
- begin
- -- Test cases where the wrapper is not needed and cases where we
- -- cannot build it.
-
- if Skip_Contract_Only_Subprogram (E) then
- return Empty;
- end if;
-
- -- Note on calls to Copy_Separate_Tree. The trees we are copying
- -- here are fully analyzed, but we definitely want fully syntactic
- -- unanalyzed trees in the body we construct, so that the analysis
- -- generates the right visibility, and that is exactly what the
- -- calls to Copy_Separate_Tree give us.
-
- declare
- Name : constant Name_Id :=
- New_External_Name (Chars (E), "__contract_only");
- Id : Entity_Id;
- Bod : Node_Id;
-
- begin
- Bod :=
- Make_Subprogram_Body (Loc,
- Specification =>
- Copy_Subprogram_Spec (Declaration_Node (E)),
- Declarations =>
- Build_Missing_Body_Decls,
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (
- Build_Missing_Body_Subprogram_Call),
- End_Label => Make_Identifier (Loc, Name)));
-
- Id := Defining_Unit_Name (Specification (Bod));
-
- -- Copy only the pre/postconditions of the original contract
- -- since it is what we need, but also because pragmas stored in
- -- the other fields have N_Pragmas with N_Aspect_Specifications
- -- that reference their associated pragma (thus causing an endless
- -- loop when trying to copy the subtree).
-
- declare
- New_Contract : constant Node_Id := Make_Contract (Sloc (E));
-
- begin
- Set_Pre_Post_Conditions (New_Contract,
- Copy_Separate_Tree (Pre_Post_Conditions (Contract (E))));
- Set_Contract (Id, New_Contract);
- end;
-
- -- Fix the name of this new subprogram and link the original
- -- subprogram with its Contract_Only_Body subprogram.
-
- Set_Chars (Id, Name);
- Set_Is_Contract_Only_Body (Id);
- Set_Contract_Only_Body (E, Id);
-
- return Bod;
- end;
- end Build_Contract_Only_Subprogram;
-
- -------------------------------------
- -- Build_Contract_Only_Subprograms --
- -------------------------------------
-
- function Build_Contract_Only_Subprograms (L : List_Id) return List_Id is
- Decl : Node_Id;
- New_Subp : Node_Id;
- Result : List_Id := No_List;
- Subp_Id : Entity_Id;
-
- begin
- Decl := First (L);
- while Present (Decl) loop
- if Nkind (Decl) = N_Subprogram_Declaration then
- Subp_Id := Defining_Unit_Name (Specification (Decl));
- New_Subp := Build_Contract_Only_Subprogram (Subp_Id);
-
- if Present (New_Subp) then
- if No (Result) then
- Result := New_List;
- end if;
-
- Append_To (Result, New_Subp);
- end if;
- end if;
-
- Next (Decl);
- end loop;
-
- return Result;
- end Build_Contract_Only_Subprograms;
-
- ------------------------------
- -- Has_Private_Declarations --
- ------------------------------
-
- function Has_Private_Declarations (N : Node_Id) return Boolean is
- begin
- if not Nkind_In (N, N_Package_Specification,
- N_Protected_Definition,
- N_Task_Definition)
- then
- return False;
- else
- return
- Present (Private_Declarations (N))
- and then Is_Non_Empty_List (Private_Declarations (N));
- end if;
- end Has_Private_Declarations;
-
- -- Local variables
-
- Subp_List : List_Id;
-
- -- Start of processing for Build_And_Analyze_Contract_Only_Subprograms
-
- begin
- Subp_List := Build_Contract_Only_Subprograms (L);
- Append_Contract_Only_Subprograms (Subp_List);
- Analyze_Contract_Only_Subprograms;
- end Build_And_Analyze_Contract_Only_Subprograms;
-
-----------------------------
-- Create_Generic_Contract --
-----------------------------
diff --git a/gcc/ada/cstreams.c b/gcc/ada/cstreams.c
index e37070d..92392fc 100644
--- a/gcc/ada/cstreams.c
+++ b/gcc/ada/cstreams.c
@@ -53,9 +53,7 @@
#endif
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
-#include <sys/stat.h>
+#include <string.h>
#else
#include "config.h"
#include "system.h"
diff --git a/gcc/ada/ctrl_c.c b/gcc/ada/ctrl_c.c
index 546faa7..0e427ea 100644
--- a/gcc/ada/ctrl_c.c
+++ b/gcc/ada/ctrl_c.c
@@ -29,11 +29,7 @@
* *
****************************************************************************/
-#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
-#include <sys/stat.h>
-#else
+#ifndef IN_RTS
#include "config.h"
#include "system.h"
#endif
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index d76d93d..6a5d0ea 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -128,7 +128,7 @@ package body Debug is
-- d.H GNSA mode for ASIS
-- d.I Do not ignore enum representation clauses in CodePeer mode
-- d.J Relaxed rules for pragma No_Return
- -- d.K Enable generation of contract-only procedures in CodePeer mode
+ -- d.K
-- d.L Depend on back end for limited types in if and case expressions
-- d.M Relaxed RM semantics
-- d.N Add node to all entities
@@ -154,7 +154,7 @@ package body Debug is
-- d_g
-- d_h
-- d_i Ignore activations and calls to instances for elaboration
- -- d_j
+ -- d_j Read JSON files and populate Repinfo tables (opposite of -gnatRjs)
-- d_k
-- d_l
-- d_m
@@ -178,7 +178,7 @@ package body Debug is
-- d_D
-- d_E
-- d_F Encode full invocation paths in ALI files
- -- d_G Encode invocation graph in ALI files
+ -- d_G
-- d_H
-- d_I
-- d_J
@@ -349,11 +349,11 @@ package body Debug is
-- d.8
-- d.9
- -- d_a
- -- d_b
+ -- d_a Ignore the effects of pragma Elaborate_All
+ -- d_b Ignore the effects of pragma Elaborate_Body
-- d_c
-- d_d
- -- d_e
+ -- d_e Ignore the effects of pragma Elaborate
-- d_f
-- d_g
-- d_h
@@ -368,7 +368,7 @@ package body Debug is
-- d_q
-- d_r
-- d_s
- -- d_t
+ -- d_t Output cycle-detection trace information
-- d_u
-- d_v
-- d_w
@@ -378,8 +378,9 @@ package body Debug is
-- d_A Output ALI invocation tables
-- d_B
- -- d_C
+ -- d_C Diagnose all cycles
-- d_D
+ -- d_E
-- d_F
-- d_G
-- d_H
@@ -388,15 +389,15 @@ package body Debug is
-- d_K
-- d_L Output library graph
-- d_M
- -- d_N New bindo order
- -- d_O Output elaboration order
- -- d_P
+ -- d_N
+ -- d_O
+ -- d_P Output cycle paths
-- d_Q
-- d_R
- -- d_S
- -- d_T Output elaboration order trace information
+ -- d_S Output elaboration-order status
+ -- d_T Output elaboration-order trace information
-- d_U
- -- d_V Validate bindo graphs and order
+ -- d_V Validate bindo cycles, graphs, and order
-- d_W
-- d_X
-- d_Y
@@ -601,10 +602,11 @@ package body Debug is
-- dE Apply compile time elaboration checking for with relations between
-- predefined units. Normally no checks are made.
- -- dF Perform the new SPARK checking rules for pointer aliasing. This is
- -- only activated in GNATprove mode and on SPARK code. These rules are
- -- not yet part of the official SPARK language, but are expected to be
- -- included in a future version of SPARK.
+ -- dF Disable the new SPARK checking rules for pointer aliasing. This is
+ -- only activated as part of GNATprove mode and on SPARK code. Now
+ -- that pointer support is part of the official SPARK language, this
+ -- switch allows reverting to the previous version of GNATprove
+ -- rejecting pointers.
-- dG Generate all warnings. Normally Errout suppresses warnings on
-- units that are not part of the main extended source, and also
@@ -904,13 +906,6 @@ package body Debug is
-- for that. If the procedure does in fact return normally, execution
-- is erroneous, and therefore unpredictable.
- -- d.K Enable generation of contract-only procedures in CodePeer mode and
- -- report a warning on subprograms for which the contract-only body
- -- cannot be built. Currently reported on subprograms defined in
- -- nested package specs that have some formal (or return type) whose
- -- type is a private type defined in some enclosing package and that
- -- have pre/postconditions.
-
-- d.L Normally the front end generates special expansion for conditional
-- expressions of a limited type. This debug flag removes this special
-- case expansion, leaving it up to the back end to handle conditional
@@ -994,6 +989,10 @@ package body Debug is
-- subprogram or task type defined in an external instance for both
-- the static and dynamic elaboration models.
+ -- d_j The compiler reads JSON files that would be generated by the same
+ -- compilation session if -gnatRjs was passed, in order to populate
+ -- the internal tables of the Repinfo unit from them.
+
-- d_p The compiler ignores calls to subprograms which verify the run-time
-- semantics of invariants and postconditions in both the static and
-- dynamic elaboration models.
@@ -1008,9 +1007,6 @@ package body Debug is
-- an external target, offering additional information to GNATBIND for
-- purposes of error diagnostics.
- -- d_G The compiler encodes the invocation graph of a unit in its ALI
- -- file.
-
-- d_L Output trace information on elaboration checking. This debug switch
-- causes output to be generated showing each call or instantiation as
-- it is checked, and the progress of the recursive trace through
@@ -1148,24 +1144,42 @@ package body Debug is
-- dx Force the binder to read (and then ignore) the xref information
-- in ali files (used to check that read circuit is working OK).
+ -- d_a GNATBIND ignores the effects of pragma Elaborate_All in the case of
+ -- elaboration order and treats the associated dependency as a regular
+ -- with edge.
+
+ -- d_b GNATBIND ignores the effects of pragma Elaborate_Body in the case
+ -- of elaboration order and treats the spec and body as decoupled.
+
+ -- d_e GNATBIND ignores the effects of pragma Elaborate in the case of
+ -- elaboration order and no longer creates an implicit dependency on
+ -- the body of the argument.
+
+ -- d_t GNATBIND output trace information of cycle-detection activities to
+ -- standard output.
+
-- d_A GNATBIND output the contents of all ALI invocation-related tables
-- in textual format to standard output.
- --
+
+ -- d_C GNATBIND diagnoses all unique cycles within the bind, rather than
+ -- just the most important one.
+
-- d_I GNATBIND outputs the contents of the invocation graph in textual
-- format to standard output.
- --
+
-- d_L GNATBIND outputs the contents of the library graph in textual
-- format to standard output.
- --
- -- d_N GNATBIND utilizes the elaboration order provided by bindo
- --
- -- d_O GNATBIND outputs the elaboration order of units to standard output
- --
- -- d_T GNATBIND outputs trace information of elaboration order activities
- -- to standard output.
- --
- -- d_V GNATBIND validates the invocation graph, library graph, SCC graph
- -- and elaboration order.
+
+ -- d_P GNATBIND outputs the cycle paths to standard output
+
+ -- d_S GNATBIND outputs trace information concerning the status of its
+ -- various phases to standard output.
+
+ -- d_T GNATBIND outputs trace information of elaboration order detection
+ -- activities to standard output.
+
+ -- d_V GNATBIND validates the invocation graph, library graph along with
+ -- its cycles, and the elaboration order.
--------------------------------------------
-- Documentation for gnatmake Debug Flags --
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
index 0b4f780..db75ea7 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
@@ -479,17 +479,17 @@ Attribute Img
=============
.. index:: Img
-The ``Img`` attribute differs from ``Image`` in that it is applied
-directly to an object, and yields the same result as
-``Image`` for the subtype of the object. This is convenient for
-debugging:
+The ``Img`` attribute differs from ``Image`` in that, while both can be
+applied directly to an object, ``Img`` cannot be applied to types.
+
+Example usage of the attribute:
.. code-block:: ada
Put_Line ("X = " & X'Img);
-has the same meaning as the more verbose:
+which has the same meaning as the more verbose:
.. code-block:: ada
@@ -967,8 +967,8 @@ of the use of this feature:
-- the former is used.
-Other properties are as for standard representation attribute ``Bit_Order``,
-as defined by Ada RM 13.5.3(4). The default is ``System.Default_Bit_Order``.
+Other properties are as for the standard representation attribute ``Bit_Order``
+defined by Ada RM 13.5.3(4). The default is ``System.Default_Bit_Order``.
For a record type ``T``, if ``T'Scalar_Storage_Order`` is
specified explicitly, it shall be equal to ``T'Bit_Order``. Note:
@@ -978,8 +978,8 @@ specified explicitly and set to the same value.
Derived types inherit an explicitly set scalar storage order from their parent
types. This may be overridden for the derived type by giving an explicit scalar
-storage order for the derived type. For a record extension, the derived type
-must have the same scalar storage order as the parent type.
+storage order for it. However, for a record extension, the derived type must
+have the same scalar storage order as the parent type.
A component of a record type that is itself a record or an array and that does
not start and end on a byte boundary must have have the same scalar storage
@@ -1018,15 +1018,18 @@ inheritance in the case of a derived type), then the default is normally
the native ordering of the target, but this default can be overridden using
pragma ``Default_Scalar_Storage_Order``.
-Note that if a component of ``T`` is itself of a record or array type,
-the specfied ``Scalar_Storage_Order`` does *not* apply to that nested type:
-an explicit attribute definition clause must be provided for the component
-type as well if desired.
+If a component of ``T`` is itself of a record or array type, the specfied
+``Scalar_Storage_Order`` does *not* apply to that nested type: an explicit
+attribute definition clause must be provided for the component type as well
+if desired.
Note that the scalar storage order only affects the in-memory data
representation. It has no effect on the representation used by stream
attributes.
+Note that debuggers may be unable to display the correct value of scalar
+components of a type for which the opposite storage order is specified.
+
.. _Attribute_Simple_Storage_Pool:
Attribute Simple_Storage_Pool
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
index 955a137..04b0def 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
@@ -719,7 +719,7 @@ Syntax:
.. code-block:: ada
- pragma Asynch_Readers [ (boolean_EXPRESSION) ];
+ pragma Async_Readers [ (boolean_EXPRESSION) ];
For the semantics of this pragma, see the entry for aspect ``Async_Readers`` in
the SPARK 2014 Reference Manual, section 7.1.2.
@@ -733,7 +733,7 @@ Syntax:
.. code-block:: ada
- pragma Asynch_Writers [ (boolean_EXPRESSION) ];
+ pragma Async_Writers [ (boolean_EXPRESSION) ];
For the semantics of this pragma, see the entry for aspect ``Async_Writers`` in
the SPARK 2014 Reference Manual, section 7.1.2.
@@ -2432,7 +2432,7 @@ with Import and Export pragmas. There are two cases to consider:
``As_Is`` provides the normal default behavior in which the casing is
taken from the string provided.
-This pragma may appear anywhere that a pragma is valid. In particular, it
+This pragma may appear anywhere that a pragma is valid. In particular, it
can be used as a configuration pragma in the :file:`gnat.adc` file, in which
case it applies to all subsequent compilations, or it can be used as a program
unit pragma, in which case it only applies to the current unit, or it can
@@ -2999,58 +2999,87 @@ Syntax:
.. code-block:: ada
- pragma Initialize_Scalars;
+ pragma Initialize_Scalars
+ [ ( TYPE_VALUE_PAIR {, TYPE_VALUE_PAIR} ) ];
+ TYPE_VALUE_PAIR ::=
+ SCALAR_TYPE => static_EXPRESSION
-This pragma is similar to ``Normalize_Scalars`` conceptually but has
-two important differences. First, there is no requirement for the pragma
-to be used uniformly in all units of a partition, in particular, it is fine
-to use this just for some or all of the application units of a partition,
-without needing to recompile the run-time library.
+ SCALAR_TYPE :=
+ Short_Float
+ | Float
+ | Long_Float
+ | Long_Long_Flat
+ | Signed_8
+ | Signed_16
+ | Signed_32
+ | Signed_64
+ | Unsigned_8
+ | Unsigned_16
+ | Unsigned_32
+ | Unsigned_64
-In the case where some units are compiled with the pragma, and some without,
-then a declaration of a variable where the type is defined in package
-Standard or is locally declared will always be subject to initialization,
-as will any declaration of a scalar variable. For composite variables,
-whether the variable is initialized may also depend on whether the package
-in which the type of the variable is declared is compiled with the pragma.
-The other important difference is that you can control the value used
-for initializing scalar objects. At bind time, you can select several
-options for initialization. You can
-initialize with invalid values (similar to Normalize_Scalars, though for
-Initialize_Scalars it is not always possible to determine the invalid
-values in complex cases like signed component fields with non-standard
-sizes). You can also initialize with high or
-low values, or with a specified bit pattern. See the GNAT
-User's Guide for binder options for specifying these cases.
+This pragma is similar to ``Normalize_Scalars`` conceptually but has two
+important differences.
-This means that you can compile a program, and then without having to
-recompile the program, you can run it with different values being used
-for initializing otherwise uninitialized values, to test if your program
-behavior depends on the choice. Of course the behavior should not change,
-and if it does, then most likely you have an incorrect reference to an
-uninitialized value.
+First, there is no requirement for the pragma to be used uniformly in all units
+of a partition. In particular, it is fine to use this just for some or all of
+the application units of a partition, without needing to recompile the run-time
+library. In the case where some units are compiled with the pragma, and some
+without, then a declaration of a variable where the type is defined in package
+Standard or is locally declared will always be subject to initialization, as
+will any declaration of a scalar variable. For composite variables, whether the
+variable is initialized may also depend on whether the package in which the
+type of the variable is declared is compiled with the pragma.
-It is even possible to change the value at execution time eliminating even
-the need to rebind with a different switch using an environment variable.
-See the GNAT User's Guide for details.
+The other important difference is that the programmer can control the value
+used for initializing scalar objects. This effect can be achieved in several
+different ways:
+
+* At compile time, the programmer can specify the invalid value for a
+ particular family of scalar types using the optional arguments of the pragma.
+
+ The compile-time approach is intended to optimize the generated code for the
+ pragma, by possibly using fast operations such as ``memset``.
+
+* At bind time, the programmer has several options:
+
+ * Initialization with invalid values (similar to Normalize_Scalars, though
+ for Initialize_Scalars it is not always possible to determine the invalid
+ values in complex cases like signed component fields with nonstandard
+ sizes).
+
+ * Initialization with high values.
+
+ * Initialization with low values.
+
+ * Initialization with a specific bit pattern.
-Note that pragma ``Initialize_Scalars`` is particularly useful in
-conjunction with the enhanced validity checking that is now provided
-in GNAT, which checks for invalid values under more conditions.
-Using this feature (see description of the *-gnatV* flag in the
-GNAT User's Guide) in conjunction with
-pragma ``Initialize_Scalars``
-provides a powerful new tool to assist in the detection of problems
-caused by uninitialized variables.
-
-Note: the use of ``Initialize_Scalars`` has a fairly extensive
-effect on the generated code. This may cause your code to be
-substantially larger. It may also cause an increase in the amount
-of stack required, so it is probably a good idea to turn on stack
-checking (see description of stack checking in the GNAT
-User's Guide) when using this pragma.
+ See the GNAT User's Guide for binder options for specifying these cases.
+
+ The bind-time approach is intended to provide fast turnaround for testing
+ with different values, without having to recompile the program.
+
+* At execution time, the programmer can speify the invalid values using an
+ environment variable. See the GNAT User's Guide for details.
+
+ The execution-time approach is intended to provide fast turnaround for
+ testing with different values, without having to recompile and rebind the
+ program.
+
+Note that pragma ``Initialize_Scalars`` is particularly useful in conjunction
+with the enhanced validity checking that is now provided in GNAT, which checks
+for invalid values under more conditions. Using this feature (see description
+of the *-gnatV* flag in the GNAT User's Guide) in conjunction with pragma
+``Initialize_Scalars`` provides a powerful new tool to assist in the detection
+of problems caused by uninitialized variables.
+
+Note: the use of ``Initialize_Scalars`` has a fairly extensive effect on the
+generated code. This may cause your code to be substantially larger. It may
+also cause an increase in the amount of stack required, so it is probably a
+good idea to turn on stack checking (see description of stack checking in the
+GNAT User's Guide) when using this pragma.
.. _Pragma-Initializes:
@@ -7312,11 +7341,10 @@ methods can be used to enable validity checking for mode ``in`` and
The form ALL_CHECKS activates all standard checks (its use is equivalent
-to the use of the :switch:`gnatva` switch.
+to the use of the :switch:`gnatVa` switch).
-The forms with ``Off`` and ``On``
-can be used to temporarily disable validity checks
-as shown in the following example:
+The forms with ``Off`` and ``On`` can be used to temporarily disable
+validity checks as shown in the following example:
.. code-block:: ada
diff --git a/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst b/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst
index 7b599be..56dd6a7 100644
--- a/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst
+++ b/gcc/ada/doc/gnat_rm/standard_and_implementation_defined_restrictions.rst
@@ -356,7 +356,9 @@ No_Exceptions
.. index:: No_Exceptions
[RM H.4] This restriction ensures at compile time that there are no
-raise statements and no exception handlers.
+raise statements and no exception handlers and also suppresses the
+generation of language-defined run-time checks.
+
No_Finalization
---------------
@@ -633,7 +635,7 @@ No_Stream_Optimizations
[GNAT] This restriction affects the performance of stream operations on types
``String``, ``Wide_String`` and ``Wide_Wide_String``. By default, the
compiler uses block reads and writes when manipulating ``String`` objects
-due to their supperior performance. When this restriction is in effect, the
+due to their superior performance. When this restriction is in effect, the
compiler performs all IO operations on a per-character basis.
No_Streams
diff --git a/gcc/ada/doc/gnat_rm/the_gnat_library.rst b/gcc/ada/doc/gnat_rm/the_gnat_library.rst
index e15e239..6b9a410 100644
--- a/gcc/ada/doc/gnat_rm/the_gnat_library.rst
+++ b/gcc/ada/doc/gnat_rm/the_gnat_library.rst
@@ -722,6 +722,17 @@ Provides access to key=value associations captured at bind time.
These associations can be specified using the :switch:`-V` binder command
line switch.
+.. _`GNAT.Branch_Prediction_(g-brapre.ads)`:
+
+``GNAT.Branch_Prediction`` (:file:`g-brapre.ads`)
+=================================================
+
+.. index:: GNAT.Branch_Prediction (g-brapre.ads)
+
+.. index:: Branch Prediction
+
+Provides routines giving hints to the branch predictor of the code generator.
+
.. _`GNAT.Bounded_Buffers_(g-boubuf.ads)`:
``GNAT.Bounded_Buffers`` (:file:`g-boubuf.ads`)
@@ -937,7 +948,7 @@ programs written in Ada.
Provides a high level interface to ``Ada.Command_Line`` facilities,
including the ability to scan for named switches with optional parameters
-and expand file names using wild card notations.
+and expand file names using wildcard notations.
.. _`GNAT.Compiler_Version_(g-comver.ads)`:
diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
index 57c3fe1..2e867e2 100644
--- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -1836,7 +1836,8 @@ Alphabetical List of All Switches
.. index:: -gnatE (gcc)
:switch:`-gnatE`
- Full dynamic elaboration checks.
+ Dynamic elaboration checking mode enabled. For further details see
+ :ref:`Elaboration_Order_Handling_in_GNAT`.
.. index:: -gnatf (gcc)
@@ -1878,8 +1879,9 @@ Alphabetical List of All Switches
.. index:: -gnatH (gcc)
:switch:`-gnatH`
- Legacy elaboration-checking mode enabled. When this switch is in effect, the
- pre-18.x access-before-elaboration model becomes the de facto model.
+ Legacy elaboration-checking mode enabled. When this switch is in effect,
+ the pre-18.x access-before-elaboration model becomes the de facto model.
+ For further details see :ref:`Elaboration_Order_Handling_in_GNAT`.
.. index:: -gnati (gcc)
@@ -1935,7 +1937,8 @@ Alphabetical List of All Switches
- Select statements
- Synchronous task suspension
- and does not emit compile-time diagnostics or run-time checks.
+ and does not emit compile-time diagnostics or run-time checks. For further
+ details see :ref:`Elaboration_Order_Handling_in_GNAT`.
.. index:: -gnatk (gcc)
@@ -2839,6 +2842,29 @@ of the pragma in the :title:`GNAT_Reference_manual`).
compile time that the assertion will fail.
+.. index:: -gnatw_a
+
+:switch:`-gnatw_a`
+ *Activate warnings on anonymous allocators.*
+
+ .. index:: Anonymous allocators
+
+ This switch activates warnings for allocators of anonymous access types,
+ which can involve run-time accessibility checks and lead to unexpected
+ accessibility violations. For more details on the rules involved, see
+ RM 3.10.2 (14).
+
+
+.. index:: -gnatw_A
+
+:switch:`-gnatw_A`
+ *Supress warnings on anonymous allocators.*
+
+ .. index:: Anonymous allocators
+
+ This switch suppresses warnings for anonymous access type allocators.
+
+
.. index:: -gnatwb (gcc)
:switch:`-gnatwb`
@@ -5290,7 +5316,7 @@ Using ``gcc`` for Syntax Checking
compiles file :file:`x.adb` in syntax-check-only mode. You can check a
series of files in a single command
- , and can use wild cards to specify such a group of files.
+ , and can use wildcards to specify such a group of files.
Note that you must specify the :switch:`-c` (compile
only) flag in addition to the :switch:`-gnats` flag.
@@ -6368,7 +6394,9 @@ be presented in subsequent sections.
.. index:: -f (gnatbind)
:switch:`-f{elab-order}`
- Force elaboration order.
+ Force elaboration order. For further details see :ref:`Elaboration_Control`
+ and :ref:`Elaboration_Order_Handling_in_GNAT`.
+
.. index:: -F (gnatbind)
@@ -6388,15 +6416,22 @@ be presented in subsequent sections.
Output usage (help) information.
- .. index:: -H32 (gnatbind)
+.. index:: -H (gnatbind)
+
+:switch:`-H`
+ Legacy elaboration order model enabled. For further details see
+ :ref:`Elaboration_Order_Handling_in_GNAT`.
+
+
+.. index:: -H32 (gnatbind)
:switch:`-H32`
Use 32-bit allocations for ``__gnat_malloc`` (and thus for access types).
For further details see :ref:`Dynamic_Allocation_Control`.
- .. index:: -H64 (gnatbind)
- .. index:: __gnat_malloc
+.. index:: -H64 (gnatbind)
+.. index:: __gnat_malloc
:switch:`-H64`
Use 64-bit allocations for ``__gnat_malloc`` (and thus for access types).
@@ -6440,7 +6475,6 @@ be presented in subsequent sections.
Rename generated main program from main to xyz. This option is
supported on cross environments only.
-
.. index:: -m (gnatbind)
:switch:`-m{n}`
@@ -6453,6 +6487,16 @@ be presented in subsequent sections.
A value of zero means that no limit is enforced. The equal
sign is optional.
+ .. index:: -minimal (gnatbind)
+
+:switch:`-minimal`
+ Generate a binder file suitable for space-constrained applications. When
+ active, binder-generated objects not required for program operation are no
+ longer generated. **Warning:** this option comes with the following
+ limitations:
+
+ * Debugging will not work;
+ * Programs using GNAT.Compiler_Version will not link.
.. index:: -n (gnatbind)
@@ -6816,7 +6860,7 @@ Elaboration Control
^^^^^^^^^^^^^^^^^^^
The following switches provide additional control over the elaboration
-order. For full details see :ref:`Elaboration_Order_Handling_in_GNAT`.
+order. For further details see :ref:`Elaboration_Order_Handling_in_GNAT`.
.. index:: -f (gnatbind)
@@ -6860,28 +6904,32 @@ order. For full details see :ref:`Elaboration_Order_Handling_in_GNAT`.
ignored.
- .. index:: -p (gnatbind)
+.. index:: -p (gnatbind)
:switch:`-p`
- Normally the binder attempts to choose an elaboration order that is
- likely to minimize the likelihood of an elaboration order error resulting
- in raising a ``Program_Error`` exception. This switch reverses the
- action of the binder, and requests that it deliberately choose an order
- that is likely to maximize the likelihood of an elaboration error.
- This is useful in ensuring portability and avoiding dependence on
- accidental fortuitous elaboration ordering.
-
- Normally it only makes sense to use the :switch:`-p`
- switch if dynamic
+ Pessimistic elaboration order
+
+ This switch is only applicable to the pre-20.x legacy elaboration models.
+ The post-20.x elaboration model uses a more informed approach of ordering
+ the units.
+
+ Normally the binder attempts to choose an elaboration order that is likely to
+ minimize the likelihood of an elaboration order error resulting in raising a
+ ``Program_Error`` exception. This switch reverses the action of the binder,
+ and requests that it deliberately choose an order that is likely to maximize
+ the likelihood of an elaboration error. This is useful in ensuring
+ portability and avoiding dependence on accidental fortuitous elaboration
+ ordering.
+
+ Normally it only makes sense to use the :switch:`-p` switch if dynamic
elaboration checking is used (:switch:`-gnatE` switch used for compilation).
This is because in the default static elaboration mode, all necessary
``Elaborate`` and ``Elaborate_All`` pragmas are implicitly inserted.
- These implicit pragmas are still respected by the binder in
- :switch:`-p` mode, so a
- safe elaboration order is assured.
+ These implicit pragmas are still respected by the binder in :switch:`-p`
+ mode, so a safe elaboration order is assured.
- Note that :switch:`-p` is not intended for
- production use; it is more for debugging/experimental use.
+ Note that :switch:`-p` is not intended for production use; it is more for
+ debugging/experimental use.
.. _Output_Control:
diff --git a/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst b/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst
index 336555c..eb0f905 100644
--- a/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/elaboration_order_handling_in_gnat.rst
@@ -50,9 +50,14 @@ Elaboration code is executed as follows:
In addition to the Ada terminology, this appendix defines the following terms:
+* *Invocation*
+
+ The act of calling a subprogram, instantiating a generic, or activating a
+ task.
+
* *Scenario*
- A construct that is elaborated or executed by elaboration code is referred to
+ A construct that is elaborated or invoked by elaboration code is referred to
as an *elaboration scenario* or simply a **scenario**. GNAT recognizes the
following scenarios:
@@ -102,7 +107,7 @@ Elaboration code may appear in two distinct contexts:
In the example above, the call to ``Server.Func`` is an elaboration scenario
because it appears at the library level of package ``Client``. Note that the
declaration of package ``Nested`` is ignored according to the definition
- given above. As a result, the call to ``Server.Func`` will be executed when
+ given above. As a result, the call to ``Server.Func`` will be invoked when
the spec of unit ``Client`` is elaborated.
* *Package body statements*
@@ -124,7 +129,7 @@ Elaboration code may appear in two distinct contexts:
In the example above, the call to ``Proc`` is an elaboration scenario because
it appears within the statement sequence of package body ``Client``. As a
- result, the call to ``Proc`` will be executed when the body of ``Client`` is
+ result, the call to ``Proc`` will be invoked when the body of ``Client`` is
elaborated.
.. _Elaboration_Order:
@@ -137,19 +142,19 @@ executed is referred to as **elaboration order**.
Within a single unit, elaboration code is executed in sequential order.
-::
+ ::
- package body Client is
- Result : ... := Server.Func;
+ package body Client is
+ Result : ... := Server.Func;
- procedure Proc is
- package Inst is new Server.Gen;
- begin
- Inst.Eval (Result);
- end Proc;
- begin
- Proc;
- end Client;
+ procedure Proc is
+ package Inst is new Server.Gen;
+ begin
+ Inst.Eval (Result);
+ end Proc;
+ begin
+ Proc;
+ end Client;
In the example above, the elaboration order within package body ``Client`` is
as follows:
@@ -173,52 +178,56 @@ factors:
* |withed| units
+* parent units
+
* purity of units
* preelaborability of units
-* presence of elaboration control pragmas
+* presence of elaboration-control pragmas
+
+* invocations performed in elaboration code
A program may have several elaboration orders depending on its structure.
-::
+ ::
- package Server is
- function Func (Index : Integer) return Integer;
- end Server;
+ package Server is
+ function Func (Index : Integer) return Integer;
+ end Server;
-::
+ ::
- package body Server is
- Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5);
+ package body Server is
+ Results : array (1 .. 5) of Integer := (1, 2, 3, 4, 5);
- function Func (Index : Integer) return Integer is
- begin
- return Results (Index);
- end Func;
- end Server;
+ function Func (Index : Integer) return Integer is
+ begin
+ return Results (Index);
+ end Func;
+ end Server;
-::
+ ::
- with Server;
- package Client is
- Val : constant Integer := Server.Func (3);
- end Client;
+ with Server;
+ package Client is
+ Val : constant Integer := Server.Func (3);
+ end Client;
-::
+ ::
- with Client;
- procedure Main is begin null; end Main;
+ with Client;
+ procedure Main is begin null; end Main;
The following elaboration order exhibits a fundamental problem referred to as
*access-before-elaboration* or simply **ABE**.
-::
+ ::
- spec of Server
- spec of Client
- body of Server
- body of Main
+ spec of Server
+ spec of Client
+ body of Server
+ body of Main
The elaboration of ``Server``'s spec materializes function ``Func``, making it
callable. The elaboration of ``Client``'s spec elaborates the declaration of
@@ -236,26 +245,27 @@ vein as index or null exclusion checks. A failed ABE check raises exception
The following elaboration order avoids the ABE problem and the program can be
successfully elaborated.
-::
+ ::
- spec of Server
- body of Server
- spec of Client
- body of Main
+ spec of Server
+ body of Server
+ spec of Client
+ body of Main
Ada states that a total elaboration order must exist, but it does not define
what this order is. A compiler is thus tasked with choosing a suitable
elaboration order which satisfies the dependencies imposed by |with| clauses,
-unit categorization, and elaboration control pragmas. Ideally an order which
-avoids ABE problems should be chosen, however a compiler may not always find
-such an order due to complications with respect to control and data flow.
+unit categorization, elaboration-control pragmas, and invocations performed in
+elaboration code. Ideally an order that avoids ABE problems should be chosen,
+however a compiler may not always find such an order due to complications with
+respect to control and data flow.
.. _Checking_the_Elaboration_Order:
Checking the Elaboration Order
==============================
-To avoid placing the entire elaboration order burden on the programmer, Ada
+To avoid placing the entire elaboration-order burden on the programmer, Ada
provides three lines of defense:
* *Static semantics*
@@ -268,7 +278,7 @@ provides three lines of defense:
* *Dynamic semantics*
Dynamic checks are performed at run time, to ensure that a target is
- elaborated prior to a scenario that executes it, thus avoiding ABE problems.
+ elaborated prior to a scenario that invokes it, thus avoiding ABE problems.
A failed run-time check raises exception ``Program_Error``. The following
restrictions apply:
@@ -290,8 +300,7 @@ provides three lines of defense:
The restrictions above can be summarized by the following rule:
*If a target has a body, then this body must be elaborated prior to the
- execution of the scenario that invokes, instantiates, or activates the
- target.*
+ scenario that invokes the target.*
* *Elaboration control*
@@ -346,7 +355,7 @@ the desired elaboration order and avoiding ABE problems altogether.
Pragma ``Elaborate_Body`` requires that the body of a unit is elaborated
immediately after its spec. This restriction guarantees that no client
- scenario can execute a server target before the target body has been
+ scenario can invoke a server target before the target body has been
elaborated because the spec and body are effectively "glued" together.
::
@@ -536,7 +545,7 @@ depend on.
be elaborated prior to ``Client``.
Removing pragma ``Elaborate_All`` could result in the following incorrect
- elaboration order
+ elaboration order:
::
@@ -601,24 +610,53 @@ elaboration order and to diagnose elaboration problems.
* *Dynamic elaboration model*
- This is the most permissive of the three elaboration models. When the
- dynamic model is in effect, GNAT assumes that all code within all units in
- a partition is elaboration code. GNAT performs very few diagnostics and
- generates run-time checks to verify the elaboration order of a program. This
- behavior is identical to that specified by the Ada Reference Manual. The
- dynamic model is enabled with compiler switch :switch:`-gnatE`.
+ This is the most permissive of the three elaboration models and emulates the
+ behavior specified by the Ada Reference Manual. When the dynamic model is in
+ effect, GNAT makes the following assumptions:
+
+ - All code within all units in a partition is considered to be elaboration
+ code.
+
+ - Some of the invocations in elaboration code may not take place at run time
+ due to conditional execution.
+
+ GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
+ that invoke internal targets. In addition, GNAT generates run-time checks for
+ all external targets and for all scenarios that may exhibit ABE problems.
+
+ The elaboration order is obtained by honoring all |with| clauses, purity and
+ preelaborability of units, and elaboration-control pragmas. The dynamic model
+ attempts to take all invocations in elaboration code into account. If an
+ invocation leads to a circularity, GNAT ignores the invocation based on the
+ assumptions stated above. An order obtained using the dynamic model may fail
+ an ABE check at run time when GNAT ignored an invocation.
+
+ The dynamic model is enabled with compiler switch :switch:`-gnatE`.
.. index:: Static elaboration model
* *Static elaboration model*
This is the middle ground of the three models. When the static model is in
- effect, GNAT performs extensive diagnostics on a unit-by-unit basis for all
- scenarios that elaborate or execute internal targets. GNAT also generates
- run-time checks for all external targets and for all scenarios that may
- exhibit ABE problems. Finally, GNAT installs implicit ``Elaborate`` and
- ``Elaborate_All`` pragmas for server units based on the dependencies of
- client units. The static model is the default model in GNAT.
+ effect, GNAT makes the following assumptions:
+
+ - Only code at the library level and in package body statements within all
+ units in a partition is considered to be elaboration code.
+
+ - All invocations in elaboration will take place at run time, regardless of
+ conditional execution.
+
+ GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
+ that invoke internal targets. In addition, GNAT generates run-time checks for
+ all external targets and for all scenarios that may exhibit ABE problems.
+
+ The elaboration order is obtained by honoring all |with| clauses, purity and
+ preelaborability of units, presence of elaboration-control pragmas, and all
+ invocations in elaboration code. An order obtained using the static model is
+ guaranteed to be ABE problem-free, excluding dispatching calls and
+ access-to-subprogram types.
+
+ The static model is the default model in GNAT.
.. index:: SPARK elaboration model
@@ -627,17 +665,23 @@ elaboration order and to diagnose elaboration problems.
This is the most conservative of the three models and enforces the SPARK
rules of elaboration as defined in the SPARK Reference Manual, section 7.7.
The SPARK model is in effect only when a scenario and a target reside in a
- region subject to SPARK_Mode On, otherwise the dynamic or static model is in
- effect.
+ region subject to ``SPARK_Mode On``, otherwise the dynamic or static model
+ is in effect.
-.. index:: Legacy elaboration model
+ The SPARK model is enabled with compiler switch :switch:`-gnatd.v`.
-* *Legacy elaboration model*
+.. index:: Legacy elaboration models
+
+* *Legacy elaboration models*
In addition to the three elaboration models outlined above, GNAT provides the
- elaboration model of pre-18.x versions referred to as `legacy elaboration
- model`. The legacy elaboration model is enabled with compiler switch
- :switch:`-gnatH`.
+ following legacy models:
+
+ - `Legacy elaboration-checking model` available in pre-18.x versions of GNAT.
+ This model is enabled with compiler switch :switch:`-gnatH`.
+
+ - `Legacy elaboration-order model` available in pre-20.x versions of GNAT.
+ This model is enabled with binder switch :switch:`-H`.
.. index:: Relaxed elaboration mode
@@ -645,812 +689,447 @@ The dynamic, legacy, and static models can be relaxed using compiler switch
:switch:`-gnatJ`, making them more permissive. Note that in this mode, GNAT
may not diagnose certain elaboration issues or install run-time checks.
-.. _Common_Elaboration_Model_Traits":
+.. _Mixing_Elaboration_Models:
-Common Elaboration-model Traits
-===============================
+Mixing Elaboration Models
+=========================
-All three GNAT models are able to detect elaboration problems related to
-dispatching calls and a particular kind of ABE referred to as *guaranteed ABE*.
+It is possible to mix units compiled with a different elaboration model,
+however the following rules must be observed:
-* *Dispatching calls*
+* A client unit compiled with the dynamic model can only |with| a server unit
+ that meets at least one of the following criteria:
- GNAT installs run-time checks for each primitive subprogram of each tagged
- type defined in a partition on the assumption that a dispatching call
- invoked at elaboration time will execute one of these primitives. As a
- result, a dispatching call that executes a primitive whose body has not
- been elaborated yet will raise exception ``Program_Error`` at run time. The
- checks can be suppressed using pragma ``Suppress (Elaboration_Check)``.
+ - The server unit is compiled with the dynamic model.
-* *Guaranteed ABE*
+ - The server unit is a GNAT implementation unit from the ``Ada``, ``GNAT``,
+ ``Interfaces``, or ``System`` hierarchies.
- A guaranteed ABE arises when the body of a target is not elaborated early
- enough, and causes all scenarios that directly execute the target to fail.
+ - The server unit has pragma ``Pure`` or ``Preelaborate``.
- ::
+ - The client unit has an explicit ``Elaborate_All`` pragma for the server
+ unit.
- package body Guaranteed_ABE is
- function ABE return Integer;
+These rules ensure that elaboration checks are not omitted. If the rules are
+violated, the binder emits a warning:
- Val : constant Integer := ABE;
+ ::
- function ABE return Integer is
- begin
- ...
- end ABE;
- end Guaranteed_ABE;
+ warning: "x.ads" has dynamic elaboration checks and with's
+ warning: "y.ads" which has static elaboration checks
- In the example above, the elaboration of ``Guaranteed_ABE``'s body elaborates
- the declaration of ``Val``. This invokes function ``ABE``, however the body
- of ``ABE`` has not been elaborated yet. GNAT emits similar diagnostics in all
- three models:
+The warnings can be suppressed by binder switch :switch:`-ws`.
- ::
+.. _ABE_Diagnostics:
- 1. package body Guaranteed_ABE is
- 2. function ABE return Integer;
- 3.
- 4. Val : constant Integer := ABE;
- |
- >>> warning: cannot call "ABE" before body seen
- >>> warning: Program_Error will be raised at run time
+ABE Diagnostics
+===============
- 5.
- 6. function ABE return Integer is
- 7. begin
- 8. ...
- 9. end ABE;
- 10. end Guaranteed_ABE;
+GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
+that invoke internal targets, regardless of whether the dynamic, SPARK, or
+static model is in effect.
Note that GNAT emits warnings rather than hard errors whenever it encounters an
elaboration problem. This is because the elaboration model in effect may be too
-conservative, or a particular scenario may not be elaborated or executed due to
-data and control flow. The warnings can be suppressed selectively with ``pragma
-Warnigns (Off)`` or globally with compiler switch :switch:`-gnatwL`.
-
-.. _Dynamic_Elaboration_Model_in_GNAT:
-
-Dynamic Elaboration Model in GNAT
-=================================
-
-The dynamic model assumes that all code within all units in a partition is
-elaboration code. As a result, run-time checks are installed for each scenario
-regardless of whether the target is internal or external. The checks can be
-suppressed using pragma ``Suppress (Elaboration_Check)``. This behavior is
-identical to that specified by the Ada Reference Manual. The following example
-showcases run-time checks installed by GNAT to verify the elaboration state of
-package ``Dynamic_Model``.
-
-::
+conservative, or a particular scenario may not be invoked due conditional
+execution. The warnings can be suppressed selectively with ``pragma Warnings
+(Off)`` or globally with compiler switch :switch:`-gnatwL`.
- with Server;
- package body Dynamic_Model is
- procedure API is
- begin
- ...
- end API;
+A *guaranteed ABE* arises when the body of a target is not elaborated early
+enough, and causes *all* scenarios that directly invoke the target to fail.
- <check that the body of Server.Gen is elaborated>
- package Inst is new Server.Gen;
-
- T : Server.Task_Type;
-
- begin
- <check that the body of Server.Task_Type is elaborated>
-
- <check that the body of Server.Proc is elaborated>
- Server.Proc;
- end Dynamic_Model;
-
-The checks verify that the body of a target has been successfully elaborated
-before a scenario activates, calls, or instantiates a target.
-
-Note that no scenario within package ``Dynamic_Model`` calls procedure ``API``.
-In fact, procedure ``API`` may not be invoked by elaboration code within the
-partition, however the dynamic model assumes that this can happen.
+ ::
-The dynamic model emits very few diagnostics, but can make suggestions on
-missing ``Elaborate`` and ``Elaborate_All`` pragmas for library-level
-scenarios. This information is available when compiler switch :switch:`-gnatel`
-is in effect.
+ package body Guaranteed_ABE is
+ function ABE return Integer;
-::
+ Val : constant Integer := ABE;
- 1. with Server;
- 2. package body Dynamic_Model is
- 3. Val : constant Integer := Server.Func;
- |
- >>> info: call to "Func" during elaboration
- >>> info: missing pragma "Elaborate_All" for unit "Server"
+ function ABE return Integer is
+ begin
+ ...
+ end ABE;
+ end Guaranteed_ABE;
- 4. end Dynamic_Model;
+In the example above, the elaboration of ``Guaranteed_ABE``'s body elaborates
+the declaration of ``Val``. This invokes function ``ABE``, however the body of
+``ABE`` has not been elaborated yet. GNAT emits the following diagnostic:
-.. _Static_Elaboration_Model_in_GNAT:
+ ::
-Static Elaboration Model in GNAT
-================================
+ 4. Val : constant Integer := ABE;
+ |
+ >>> warning: cannot call "ABE" before body seen
+ >>> warning: Program_Error will be raised at run time
-In contrast to the dynamic model, the static model is more precise in its
-analysis of elaboration code. The model makes a clear distinction between
-internal and external targets, and resorts to different diagnostics and
-run-time checks based on the nature of the target.
+A *conditional ABE* arises when the body of a target is not elaborated early
+enough, and causes *some* scenarios that directly invoke the target to fail.
-* *Internal targets*
+ ::
- The static model performs extensive diagnostics on scenarios which elaborate
- or execute internal targets. The warnings resulting from these diagnostics
- are enabled by default, but can be suppressed selectively with ``pragma
- Warnings (Off)`` or globally with compiler switch :switch:`-gnatwL`.
+ 1. package body Conditional_ABE is
+ 2. procedure Force_Body is null;
+ 3.
+ 4. generic
+ 5. with function Func return Integer;
+ 6. package Gen is
+ 7. Val : constant Integer := Func;
+ 8. end Gen;
+ 9.
+ 10. function ABE return Integer;
+ 11.
+ 12. function Cause_ABE return Boolean is
+ 13. package Inst is new Gen (ABE);
+ 14. begin
+ 15. ...
+ 16. end Cause_ABE;
+ 17.
+ 18. Val : constant Boolean := Cause_ABE;
+ 19.
+ 20. function ABE return Integer is
+ 21. begin
+ 22. ...
+ 23. end ABE;
+ 24.
+ 25. Safe : constant Boolean := Cause_ABE;
+ 26. end Conditional_ABE;
+
+In the example above, the elaboration of package body ``Conditional_ABE``
+elaborates the declaration of ``Val``. This invokes function ``Cause_ABE``,
+which instantiates generic unit ``Gen`` as ``Inst``. The elaboration of
+``Inst`` invokes function ``ABE``, however the body of ``ABE`` has not been
+elaborated yet. GNAT emits the following diagnostic:
::
- 1. package body Static_Model is
- 2. generic
- 3. with function Func return Integer;
- 4. package Gen is
- 5. Val : constant Integer := Func;
- 6. end Gen;
- 7.
- 8. function ABE return Integer;
- 9.
- 10. function Cause_ABE return Boolean is
- 11. package Inst is new Gen (ABE);
+ 13. package Inst is new Gen (ABE);
|
- >>> warning: in instantiation at line 5
+ >>> warning: in instantiation at line 7
>>> warning: cannot call "ABE" before body seen
>>> warning: Program_Error may be raised at run time
- >>> warning: body of unit "Static_Model" elaborated
- >>> warning: function "Cause_ABE" called at line 16
- >>> warning: function "ABE" called at line 5, instance at line 11
-
- 12. begin
- 13. ...
- 14. end Cause_ABE;
- 15.
- 16. Val : constant Boolean := Cause_ABE;
- 17.
- 18. function ABE return Integer is
- 19. begin
- 20. ...
- 21. end ABE;
- 22. end Static_Model;
-
- The example above illustrates an ABE problem within package ``Static_Model``,
- which is hidden by several layers of indirection. The elaboration of package
- body ``Static_Model`` elaborates the declaration of ``Val``. This invokes
- function ``Cause_ABE``, which instantiates generic unit ``Gen`` as ``Inst``.
- The elaboration of ``Inst`` invokes function ``ABE``, however the body of
- ``ABE`` has not been elaborated yet.
-
-* *External targets*
-
- The static model installs run-time checks to verify the elaboration status
- of server targets only when the scenario that elaborates or executes that
- target is part of the elaboration code of the client unit. The checks can be
- suppressed using pragma ``Suppress (Elaboration_Check)``.
+ >>> warning: body of unit "Conditional_ABE" elaborated
+ >>> warning: function "Cause_ABE" called at line 18
+ >>> warning: function "ABE" called at line 7, instance at line 13
- ::
+Note that the same ABE problem does not occur with the elaboration of
+declaration ``Safe`` because the body of function ``ABE`` has already been
+elaborated at that point.
- with Server;
- package body Static_Model is
- generic
- with function Func return Integer;
- package Gen is
- Val : constant Integer := Func;
- end Gen;
-
- function Call_Func return Boolean is
- <check that the body of Server.Func is elaborated>
- package Inst is new Gen (Server.Func);
- begin
- ...
- end Call_Func;
-
- Val : constant Boolean := Call_Func;
- end Static_Model;
+.. _SPARK_Diagnostics:
- In the example above, the elaboration of package body ``Static_Model``
- elaborates the declaration of ``Val``. This invokes function ``Call_Func``,
- which instantiates generic unit ``Gen`` as ``Inst``. The elaboration of
- ``Inst`` invokes function ``Server.Func``. Since ``Server.Func`` is an
- external target, GNAT installs a run-time check to verify that its body has
- been elaborated.
+SPARK Diagnostics
+=================
- In addition to checks, the static model installs implicit ``Elaborate`` and
- ``Elaborate_All`` pragmas to guarantee safe elaboration use of server units.
- This information is available when compiler switch :switch:`-gnatel` is in
- effect.
+GNAT enforces the SPARK rules of elaboration as defined in the SPARK Reference
+Manual section 7.7 when compiler switch :switch:`-gnatd.v` is in effect. Note
+that GNAT emits hard errors whenever it encounters a violation of the SPARK
+rules.
::
- 1. with Server;
- 2. package body Static_Model is
- 3. generic
- 4. with function Func return Integer;
- 5. package Gen is
- 6. Val : constant Integer := Func;
- 7. end Gen;
- 8.
- 9. function Call_Func return Boolean is
- 10. package Inst is new Gen (Server.Func);
- |
- >>> info: instantiation of "Gen" during elaboration
- >>> info: in instantiation at line 6
- >>> info: call to "Func" during elaboration
- >>> info: in instantiation at line 6
- >>> info: implicit pragma "Elaborate_All" generated for unit "Server"
- >>> info: body of unit "Static_Model" elaborated
- >>> info: function "Call_Func" called at line 15
- >>> info: function "Func" called at line 6, instance at line 10
-
- 11. begin
- 12. ...
- 13. end Call_Func;
- 14.
- 15. Val : constant Boolean := Call_Func;
- |
- >>> info: call to "Call_Func" during elaboration
-
- 16. end Static_Model;
-
- In the example above, the elaboration of package body ``Static_Model``
- elaborates the declaration of ``Val``. This invokes function ``Call_Func``,
- which instantiates generic unit ``Gen`` as ``Inst``. The elaboration of
- ``Inst`` invokes function ``Server.Func``. Since ``Server.Func`` is an
- external target, GNAT installs an implicit ``Elaborate_All`` pragma for unit
- ``Server``. The pragma guarantees that both the spec and body of ``Server``,
- along with any additional dependencies that ``Server`` may require, are
- elaborated prior to the body of ``Static_Model``.
-
-.. _SPARK_Elaboration_Model_in_GNAT:
-
-SPARK Elaboration Model in GNAT
-===============================
-
-The SPARK model is identical to the static model in its handling of internal
-targets. The SPARK model, however, requires explicit ``Elaborate`` or
-``Elaborate_All`` pragmas to be present in the program when a target is
-external, and compiler switch :switch:`-gnatd.v` is in effect.
-
-::
-
- 1. with Server;
- 2. package body SPARK_Model with SPARK_Mode is
- 3. Val : constant Integer := Server.Func;
- |
- >>> call to "Func" during elaboration in SPARK
- >>> unit "SPARK_Model" requires pragma "Elaborate_All" for "Server"
- >>> body of unit "SPARK_Model" elaborated
- >>> function "Func" called at line 3
-
- 4. end SPARK_Model;
-
-Legacy Elaboration Model in GNAT
-================================
-
-The legacy elaboration model is provided for compatibility with code bases
-developed with pre-18.x versions of GNAT. It is similar in functionality to
-the dynamic and static models of post-18.x version of GNAT, but may differ
-in terms of diagnostics and run-time checks. The legacy elaboration model is
-enabled with compiler switch :switch:`-gnatH`.
+ 1. with Server;
+ 2. package body SPARK_Diagnostics with SPARK_Mode is
+ 3. Val : constant Integer := Server.Func;
+ |
+ >>> call to "Func" during elaboration in SPARK
+ >>> unit "SPARK_Diagnostics" requires pragma "Elaborate_All" for "Server"
+ >>> body of unit "SPARK_Model" elaborated
+ >>> function "Func" called at line 3
-.. _Mixing_Elaboration_Models:
+ 4. end SPARK_Diagnostics;
-Mixing Elaboration Models
-=========================
+.. _Elaboration_Circularities:
-It is possible to mix units compiled with a different elaboration model,
-however the following rules must be observed:
+Elaboration Circularities
+=========================
-* A client unit compiled with the dynamic model can only |with| a server unit
- that meets at least one of the following criteria:
+An **elaboration circularity** occurs whenever the elaboration of a set of
+units enters a deadlocked state, where each unit is waiting for another unit
+to be elaborated. This situation may be the result of improper use of |with|
+clauses, elaboration-control pragmas, or invocations in elaboration code.
- - The server unit is compiled with the dynamic model.
+The following example exhibits an elaboration circularity.
- - The server unit is a GNAT implementation unit from the Ada, GNAT,
- Interfaces, or System hierarchies.
+ ::
- - The server unit has pragma ``Pure`` or ``Preelaborate``.
+ with B; pragma Elaborate (B);
+ package A is
+ end A;
- - The client unit has an explicit ``Elaborate_All`` pragma for the server
- unit.
+ ::
-These rules ensure that elaboration checks are not omitted. If the rules are
-violated, the binder emits a warning:
+ package B is
+ procedure Force_Body;
+ end B;
-::
+ ::
- warning: "x.ads" has dynamic elaboration checks and with's
- warning: "y.ads" which has static elaboration checks
+ with C;
+ package body B is
+ procedure Force_Body is null;
-The warnings can be suppressed by binder switch :switch:`-ws`.
+ Elab : constant Integer := C.Func;
+ end B;
-.. _Elaboration_Circularities:
+ ::
-Elaboration Circularities
-=========================
+ package C is
+ function Func return Integer;
+ end C;
-If the binder cannot find an acceptable elaboration order, it outputs detailed
-diagnostics describing an **elaboration circularity**.
+ ::
-::
+ with A;
+ package body C is
+ function Func return Integer is
+ begin
+ ...
+ end Func;
+ end C;
- package Server is
- function Func return Integer;
- end Server;
+The binder emits the following diagnostic:
-::
+ ::
- with Client;
- package body Server is
- function Func return Integer is
- begin
- ...
- end Func;
- end Server;
+ error: Elaboration circularity detected
+ info:
+ info: Reason:
+ info:
+ info: unit "a (spec)" depends on its own elaboration
+ info:
+ info: Circularity:
+ info:
+ info: unit "a (spec)" has with clause and pragma Elaborate for unit "b (spec)"
+ info: unit "b (body)" is in the closure of pragma Elaborate
+ info: unit "b (body)" invokes a construct of unit "c (body)" at elaboration time
+ info: unit "c (body)" has with clause for unit "a (spec)"
+ info:
+ info: Suggestions:
+ info:
+ info: remove pragma Elaborate for unit "b (body)" in unit "a (spec)"
+ info: use the dynamic elaboration model (compiler switch -gnatE)
-::
+The diagnostic consist of the following sections:
- with Server;
- package Client is
- Val : constant Integer := Server.Func;
- end Client;
+* Reason
-::
+ This section provides a short explanation describing why the set of units
+ could not be ordered.
- with Client;
- procedure Main is begin null; end Main;
+* Circularity
-::
+ This section enumerates the units comprising the deadlocked set, along with
+ their interdependencies.
- error: elaboration circularity detected
- info: "server (body)" must be elaborated before "client (spec)"
- info: reason: implicit Elaborate_All in unit "client (spec)"
- info: recompile "client (spec)" with -gnatel for full details
- info: "server (body)"
- info: must be elaborated along with its spec:
- info: "server (spec)"
- info: which is withed by:
- info: "client (spec)"
- info: "client (spec)" must be elaborated before "server (body)"
- info: reason: with clause
+* Suggestions
-In the example above, ``Client`` must be elaborated prior to ``Main`` by virtue
-of a |with| clause. The elaboration of ``Client`` invokes ``Server.Func``, and
-static model generates an implicit ``Elaborate_All`` pragma for ``Server``. The
-pragma implies that both the spec and body of ``Server``, along with any units
-they |with|, must be elaborated prior to ``Client``. However, ``Server``'s body
-|withs| ``Client``, implying that ``Client`` must be elaborated prior to
-``Server``. The end result is that ``Client`` must be elaborated prior to
-``Client``, and this leads to a circularity.
+ This section enumerates various tactics for eliminating the circularity.
.. _Resolving_Elaboration_Circularities:
Resolving Elaboration Circularities
===================================
-When faced with an elaboration circularity, a programmer has several options
-available.
-
-* *Fix the program*
+The most desirable option from the point of view of long-term maintenance is to
+rearrange the program so that the elaboration problems are avoided. One useful
+technique is to place the elaboration code into separate child packages.
+Another is to move some of the initialization code to explicitly invoked
+subprograms, where the program controls the order of initialization explicitly.
+Although this is the most desirable option, it may be impractical and involve
+too much modification, especially in the case of complex legacy code.
- The most desirable option from the point of view of long-term maintenance
- is to rearrange the program so that the elaboration problems are avoided.
- One useful technique is to place the elaboration code into separate child
- packages. Another is to move some of the initialization code to explicitly
- invoked subprograms, where the program controls the order of initialization
- explicitly. Although this is the most desirable option, it may be impractical
- and involve too much modification, especially in the case of complex legacy
- code.
+When faced with an elaboration circularity, the programmer should also consider
+the tactics given in the suggestions section of the circularity diagnostic.
+Depending on the units involved in the circularity, their |with| clauses,
+purity, preelaborability, presence of elaboration-control pragmas and
+invocations at elaboration time, the binder may suggest one or more of the
+following tactics to eliminate the circularity:
-* *Switch to more permissive elaboration model*
+* Pragma Elaborate elimination
- If the compilation was performed using the static model, enable the dynamic
- model with compiler switch :switch:`-gnatE`. GNAT will no longer generate
- implicit ``Elaborate`` and ``Elaborate_All`` pragmas, resulting in a behavior
- identical to that specified by the Ada Reference Manual. The binder will
- generate an executable program that may or may not raise ``Program_Error``,
- and it is the programmer's responsibility to ensure that it does not raise
- ``Program_Error``.
+ ::
- If the compilation was performed using a post-18.x version of GNAT, consider
- using the legacy elaboration model, in the following order:
+ remove pragma Elaborate for unit "..." in unit "..."
- - Use the relaxed static elaboration model, with compiler switch
- :switch:`-gnatJ`.
+ This tactic is suggested when the binder has determined that pragma
+ ``Elaborate``:
- - Use the relaxed dynamic elaboration model, with compiler switches
- :switch:`-gnatE` :switch:`-gnatJ`.
+ - Prevents a set of units from being elaborated.
- - Use the legacy static elaboration model, with compiler switch
- :switch:`-gnatH`.
+ - The removal of the pragma will not eliminate the semantic effects of the
+ pragma. In other words, the argument of the pragma will still be elaborated
+ prior to the unit containing the pragma.
- - Use the legacy dynamic elaboration model, with compiler switches
- :switch:`-gnatE` :switch:`-gnatH`.
+ - The removal of the pragma will enable the successful ordering of the units.
-* *Suppress all elaboration checks*
+ The programmer should remove the pragma as advised, and rebuild the program.
- The drawback of run-time checks is that they generate overhead at run time,
- both in space and time. If the programmer is absolutely sure that a program
- will not raise an elaboration-related ``Program_Error``, then using the
- pragma ``Suppress (Elaboration_Check)`` globally (as a configuration pragma)
- will eliminate all run-time checks.
+* Pragma Elaborate_All elimination
-* *Suppress elaboration checks selectively*
+ ::
- If a scenario cannot possibly lead to an elaboration ``Program_Error``,
- and the binder nevertheless complains about implicit ``Elaborate`` and
- ``Elaborate_All`` pragmas that lead to elaboration circularities, it
- is possible to suppress the generation of implicit ``Elaborate`` and
- ``Elaborate_All`` pragmas, as well as run-time checks. Clearly this can
- be unsafe, and it is the responsibility of the programmer to make sure
- that the resulting program has no elaboration anomalies. Pragma
- ``Suppress (Elaboration_Check)`` can be used with different levels of
- granularity to achieve these effects.
+ remove pragma Elaborate_All for unit "..." in unit "..."
- - *Target suppression*
+ This tactic is suggested when the binder has determined that pragma
+ ``Elaborate_All``:
- When the pragma is placed in a declarative part, without a second argument
- naming an entity, it will suppress implicit ``Elaborate`` and
- ``Elaborate_All`` pragma generation, as well as run-time checks, on all
- targets within the region.
+ - Prevents a set of units from being elaborated.
- ::
+ - The removal of the pragma will not eliminate the semantic effects of the
+ pragma. In other words, the argument of the pragma along with its |with|
+ closure will still be elaborated prior to the unit containing the pragma.
- package Range_Suppress is
- pragma Suppress (Elaboration_Check);
+ - The removal of the pragma will enable the successful ordering of the units.
- function Func return Integer;
+ The programmer should remove the pragma as advised, and rebuild the program.
- generic
- procedure Gen;
+* Pragma Elaborate_All downgrade
- pragma Unsuppress (Elaboration_Check);
+ ::
- task type Tsk;
- end Range_Suppress;
+ change pragma Elaborate_All for unit "..." to Elaborate in unit "..."
- In the example above, a pair of Suppress/Unsuppress pragmas define a region
- of suppression within package ``Range_Suppress``. As a result, no implicit
- ``Elaborate`` and ``Elaborate_All`` pragmas, nor any run-time checks, will
- be generated by callers of ``Func`` and instantiators of ``Gen``. Note that
- task type ``Tsk`` is not within this region.
+ This tactic is always suggested with the pragma ``Elaborate_All`` elimination
+ tactic. It offers a different alernative of guaranteeing that the argument of
+ the pragma will still be elaborated prior to the unit containing the pragma.
- An alternative to the region-based suppression is to use multiple
- ``Suppress`` pragmas with arguments naming specific entities for which
- elaboration checks should be suppressed:
+ The programmer should update the pragma as advised, and rebuild the program.
- ::
+* Pragma Elaborate_Body elimination
- package Range_Suppress is
- function Func return Integer;
- pragma Suppress (Elaboration_Check, Func);
+ ::
- generic
- procedure Gen;
- pragma Suppress (Elaboration_Check, Gen);
+ remove pragma Elaborate_Body in unit "..."
- task type Tsk;
- end Range_Suppress;
+ This tactic is suggested when the binder has determined that pragma
+ ``Elaborate_Body``:
- - *Scenario suppression*
+ - Prevents a set of units from being elaborated.
- When the pragma ``Suppress`` is placed in a declarative or statement
- part, without an entity argument, it will suppress implicit ``Elaborate``
- and ``Elaborate_All`` pragma generation, as well as run-time checks, on
- all scenarios within the region.
+ - The removal of the pragma will enable the successful ordering of the units.
- ::
+ Note that the binder cannot determine whether the pragma is required for
+ other purposes, such as guaranteeing the initialization of a variable
+ declared in the spec by elaboration code in the body.
- with Server;
- package body Range_Suppress is
- pragma Suppress (Elaboration_Check);
+ The programmer should remove the pragma as advised, and rebuild the program.
- function Func return Integer is
- begin
- return Server.Func;
- end Func;
+* Use of pragma Restrictions
- procedure Gen is
- begin
- Server.Proc;
- end Gen;
+ ::
- pragma Unsuppress (Elaboration_Check);
+ use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code)
- task body Tsk is
- begin
- Server.Proc;
- end Tsk;
- end Range_Suppress;
-
- In the example above, a pair of Suppress/Unsuppress pragmas define a region
- of suppression within package body ``Range_Suppress``. As a result, the
- calls to ``Server.Func`` in ``Func`` and ``Server.Proc`` in ``Gen`` will
- not generate any implicit ``Elaborate`` and ``Elaborate_All`` pragmas or
- run-time checks.
-
-.. _Resolving_Task_Issues:
-
-Resolving Task Issues
-=====================
-
-The model of execution in Ada dictates that elaboration must first take place,
-and only then can the main program be started. Tasks which are activated during
-elaboration violate this model and may lead to serious concurrent problems at
-elaboration time.
-
-A task can be activated in two different ways:
-
-* The task is created by an allocator in which case it is activated immediately
- after the allocator is evaluated.
-
-* The task is declared at the library level or within some nested master in
- which case it is activated before starting execution of the statement
- sequence of the master defining the task.
-
-Since the elaboration of a partition is performed by the environment task
-servicing that partition, any tasks activated during elaboration may be in
-a race with the environment task, and lead to unpredictable state and behavior.
-The static model seeks to avoid such interactions by assuming that all code in
-the task body is executed at elaboration time, if the task was activated by
-elaboration code.
-
-::
-
- package Decls is
- task Lib_Task is
- entry Start;
- end Lib_Task;
-
- type My_Int is new Integer;
-
- function Ident (M : My_Int) return My_Int;
- end Decls;
-
-::
-
- with Utils;
- package body Decls is
- task body Lib_Task is
- begin
- accept Start;
- Utils.Put_Val (2);
- end Lib_Task;
-
- function Ident (M : My_Int) return My_Int is
- begin
- return M;
- end Ident;
- end Decls;
-
-::
-
- with Decls;
- package Utils is
- procedure Put_Val (Arg : Decls.My_Int);
- end Utils;
-
-::
-
- with Ada.Text_IO; use Ada.Text_IO;
- package body Utils is
- procedure Put_Val (Arg : Decls.My_Int) is
- begin
- Put_Line (Arg'Img);
- end Put_Val;
- end Utils;
-
-::
-
- with Decls;
- procedure Main is
- begin
- Decls.Lib_Task.Start;
- end Main;
-
-When the above example is compiled with the static model, an elaboration
-circularity arises:
-
-::
-
- error: elaboration circularity detected
- info: "decls (body)" must be elaborated before "decls (body)"
- info: reason: implicit Elaborate_All in unit "decls (body)"
- info: recompile "decls (body)" with -gnatel for full details
- info: "decls (body)"
- info: must be elaborated along with its spec:
- info: "decls (spec)"
- info: which is withed by:
- info: "utils (spec)"
- info: which is withed by:
- info: "decls (body)"
-
-In the above example, ``Decls`` must be elaborated prior to ``Main`` by virtue
-of a with clause. The elaboration of ``Decls`` activates task ``Lib_Task``. The
-static model conservatibely assumes that all code within the body of
-``Lib_Task`` is executed, and generates an implicit ``Elaborate_All`` pragma
-for ``Units`` due to the call to ``Utils.Put_Val``. The pragma implies that
-both the spec and body of ``Utils``, along with any units they |with|,
-must be elaborated prior to ``Decls``. However, ``Utils``'s spec |withs|
-``Decls``, implying that ``Decls`` must be elaborated before ``Utils``. The end
-result is that ``Utils`` must be elaborated prior to ``Utils``, and this
-leads to a circularity.
-
-In reality, the example above will not exhibit an ABE problem at run time.
-When the body of task ``Lib_Task`` is activated, execution will wait for entry
-``Start`` to be accepted, and the call to ``Utils.Put_Val`` will not take place
-at elaboration time. Task ``Lib_Task`` will resume its execution after the main
-program is executed because ``Main`` performs a rendezvous with
-``Lib_Task.Start``, and at that point all units have already been elaborated.
-As a result, the static model may seem overly conservative, partly because it
-does not take control and data flow into account.
-
-When faced with a task elaboration circularity, a programmer has several
-options available:
-
-* *Use the dynamic model*
-
- The dynamic model does not generate implicit ``Elaborate`` and
- ``Elaborate_All`` pragmas. Instead, it will install checks prior to every
- call in the example above, thus verifying the successful elaboration of
- ``Utils.Put_Val`` in case the call to it takes place at elaboration time.
- The dynamic model is enabled with compiler switch :switch:`-gnatE`.
+ This tactic is suggested when the binder has determined that a task
+ activation at elaboration time:
-* *Isolate the tasks*
+ - Prevents a set of units from being elaborated.
- Relocating tasks in their own separate package could decouple them from
- dependencies that would otherwise cause an elaboration circularity. The
- example above can be rewritten as follows:
+ Note that the binder cannot determine with certainty whether the task will
+ block at elaboration time.
- ::
+ The programmer should create a configuration file, place the pragma within,
+ update the general compilation arguments, and rebuild the program.
- package Decls1 is -- new
- task Lib_Task is
- entry Start;
- end Lib_Task;
- end Decls1;
+* Use of dynamic elaboration model
::
- with Utils;
- package body Decls1 is -- new
- task body Lib_Task is
- begin
- accept Start;
- Utils.Put_Val (2);
- end Lib_Task;
- end Decls1;
+ use the dynamic elaboration model (compiler switch -gnatE)
- ::
+ This tactic is suggested when the binder has determined that an invocation at
+ elaboration time:
- package Decls2 is -- new
- type My_Int is new Integer;
- function Ident (M : My_Int) return My_Int;
- end Decls2;
+ - Prevents a set of units from being elaborated.
- ::
+ - The use of the dynamic model will enable the successful ordering of the
+ units.
- with Utils;
- package body Decls2 is -- new
- function Ident (M : My_Int) return My_Int is
- begin
- return M;
- end Ident;
- end Decls2;
+ The programmer has two options:
- ::
+ - Determine the units involved in the invocation using the detailed
+ invocation information, and add compiler switch :switch:`-gnatE` to the
+ compilation arguments of selected files only. This approach will yield
+ safer elaboration orders compared to the other option because it will
+ minimize the opportunities presented to the dynamic model for ignoring
+ invocations.
- with Decls2;
- package Utils is
- procedure Put_Val (Arg : Decls2.My_Int);
- end Utils;
+ - Add compiler switch :switch:`-gnatE` to the general compilation arguments.
+
+* Use of detailed invocation information
::
- with Ada.Text_IO; use Ada.Text_IO;
- package body Utils is
- procedure Put_Val (Arg : Decls2.My_Int) is
- begin
- Put_Line (Arg'Img);
- end Put_Val;
- end Utils;
+ use detailed invocation information (compiler switch -gnatd_F)
- ::
+ This tactic is always suggested with the use of the dynamic model tactic. It
+ causes the circularity section of the circularity diagnostic to describe the
+ flow of elaboration code from a unit to a unit, enumerating all such paths in
+ the process.
- with Decls1;
- procedure Main is
- begin
- Decls1.Lib_Task.Start;
- end Main;
-
-* *Declare the tasks*
+ The programmer should analyze this information to determine which units
+ should be compiled with the dynamic model.
- The original example uses a single task declaration for ``Lib_Task``. An
- explicit task type declaration and a properly placed task object could avoid
- the dependencies that would otherwise cause an elaboration circularity. The
- example can be rewritten as follows:
+* Forced-dependency elimination
::
- package Decls is
- task type Lib_Task is -- new
- entry Start;
- end Lib_Task;
+ remove the dependency of unit "..." on unit "..." from the argument of switch -f
- type My_Int is new Integer;
+ This tactic is suggested when the binder has determined that a dependency
+ present in the forced-elaboration-order file indicated by binder switch
+ :switch:`-f`:
- function Ident (M : My_Int) return My_Int;
- end Decls;
+ - Prevents a set of units from being elaborated.
- ::
+ - The removal of the dependency will enable the successful ordering of the
+ units.
- with Utils;
- package body Decls is
- task body Lib_Task is
- begin
- accept Start;
- Utils.Put_Val (2);
- end Lib_Task;
+ The programmer should edit the forced-elaboration-order file, remove the
+ dependency, and rebind the program.
- function Ident (M : My_Int) return My_Int is
- begin
- return M;
- end Ident;
- end Decls;
+* All forced-dependency elimination
::
- with Decls;
- package Utils is
- procedure Put_Val (Arg : Decls.My_Int);
- end Utils;
+ remove switch -f
- ::
+ This tactic is suggested in case editing the forced-elaboration-order file is
+ not an option.
- with Ada.Text_IO; use Ada.Text_IO;
- package body Utils is
- procedure Put_Val (Arg : Decls.My_Int) is
- begin
- Put_Line (Arg'Img);
- end Put_Val;
- end Utils;
-
- ::
+ The programmer should remove binder switch :switch:`-f` from the binder
+ arguments, and rebind.
- with Decls;
- package Obj_Decls is -- new
- Task_Obj : Decls.Lib_Task;
- end Obj_Decls;
+* Multiple-circularities diagnostic
::
- with Obj_Decls;
- procedure Main is
- begin
- Obj_Decls.Task_Obj.Start; -- new
- end Main;
+ diagnose all circularities (binder switch -d_C)
-* *Use restriction No_Entry_Calls_In_Elaboration_Code*
+ By default, the binder will diagnose only the highest-precedence circularity.
+ If the program contains multiple circularities, the binder will suggest the
+ use of binder switch :switch:`-d_C` in order to obtain the diagnostics of all
+ circularities.
- The issue exhibited in the original example under this section revolves
- around the body of ``Lib_Task`` blocking on an accept statement. There is
- no rule to prevent elaboration code from performing entry calls, however in
- practice this is highly unusual. In addition, the pattern of starting tasks
- at elaboration time and then immediately blocking on accept or select
- statements is quite common.
+ The programmer should add binder switch :switch:`-d_C` to the binder
+ arguments, and rebind.
- If a programmer knows that elaboration code will not perform any entry
- calls, then the programmer can indicate that the static model should not
- process the remainder of a task body once an accept or select statement has
- been encountered. This behavior can be specified by a configuration pragma:
+If none of the tactics suggested by the binder eliminate the elaboration
+circularity, the programmer should consider using one of the legacy elaboration
+models, in the following order:
- ::
+* Use the pre-20.x legacy elaboration-order model, with binder switch
+ :switch:`-H`.
+
+* Use both pre-18.x and pre-20.x legacy elaboration models, with compiler
+ switch :switch:`-gnatH` and binder switch :switch:`-H`.
- pragma Restrictions (No_Entry_Calls_In_Elaboration_Code);
+* Use the relaxed static-elaboration model, with compiler switches
+ :switch:`-gnatH` :switch:`-gnatJ` and binder switch :switch:`-H`.
- In addition to the change in behavior with respect to task bodies, the
- static model will verify that no entry calls take place at elaboration time.
+* Use the relaxed dynamic-elaboration model, with compiler switches
+ :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE` and binder switch
+ :switch:`-H`.
.. _Elaboration_Related_Compiler_Switches:
@@ -1465,13 +1144,17 @@ the elaboration order chosen by the binder.
:switch:`-gnatE`
Dynamic elaboration checking mode enabled
- When this switch is in effect, GNAT activates the dynamic elaboration model.
+ When this switch is in effect, GNAT activates the dynamic model.
.. index:: -gnatel (gnat)
:switch:`-gnatel`
Turn on info messages on generated Elaborate[_All] pragmas
+ This switch is only applicable to the pre-20.x legacy elaboration models.
+ The post-20.x elaboration model no longer relies on implicitly generated
+ ``Elaborate`` and ``Elaborate_All`` pragmas to order units.
+
When this switch is in effect, GNAT will emit the following supplementary
information depending on the elaboration model in effect.
@@ -1482,7 +1165,7 @@ the elaboration order chosen by the binder.
- *Static model*
- GNAT will indicate all scenarios executed during elaboration. In addition,
+ GNAT will indicate all scenarios invoked during elaboration. In addition,
it will provide detailed traceback when an implicit ``Elaborate`` or
``Elaborate_All`` pragma is generated.
@@ -1615,29 +1298,24 @@ options:
as their origins. Elaboration warnings are enabled with compiler switch
:switch:`-gnatwl`.
-* Use switch :switch:`-gnatel` to obtain messages on generated implicit
- ``Elaborate`` and ``Elaborate_All`` pragmas. The trace information could
- indicate why a server unit must be elaborated prior to a client unit.
-
-* If the warnings produced by the static model indicate that a task is
- involved, consider the options in section `Resolving Task Issues`_.
+* Cosider the tactics given in the suggestions section of the circularity
+ diagnostic.
* If none of the steps outlined above resolve the circularity, use a more
permissive elaboration model, in the following order:
- - Use the dynamic elaboration model, with compiler switch :switch:`-gnatE`.
-
- - Use the legacy static elaboration model, with compiler switch
- :switch:`-gnatH`.
+ - Use the pre-20.x legacy elaboration-order model, with binder switch
+ :switch:`-H`.
- - Use the legacy dynamic elaboration model, with compiler switches
- :switch:`-gnatH` :switch:`-gnatE`.
+ - Use both pre-18.x and pre-20.x legacy elaboration models, with compiler
+ switch :switch:`-gnatH` and binder switch :switch:`-H`.
- - Use the relaxed legacy static elaboration model, with compiler switches
- :switch:`-gnatH` :switch:`-gnatJ`.
+ - Use the relaxed static elaboration model, with compiler switches
+ :switch:`-gnatH` :switch:`-gnatJ` and binder switch :switch:`-H`.
- - Use the relaxed legacy dynamic elaboration model, with compiler switches
- :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE`.
+ - Use the relaxed dynamic elaboration model, with compiler switches
+ :switch:`-gnatH` :switch:`-gnatJ` :switch:`-gnatE` and binder switch
+ :switch:`-H`.
.. _Inspecting_the_Chosen_Elaboration_Order:
@@ -1650,128 +1328,128 @@ elaboration order appears as a sequence of calls to ``Elab_Body`` and
``Elab_Spec``, interspersed with assignments to `Exxx` which indicates that a
particular unit is elaborated. For example:
-::
-
- System.Soft_Links'Elab_Body;
- E14 := True;
- System.Secondary_Stack'Elab_Body;
- E18 := True;
- System.Exception_Table'Elab_Body;
- E24 := True;
- Ada.Io_Exceptions'Elab_Spec;
- E67 := True;
- Ada.Tags'Elab_Spec;
- Ada.Streams'Elab_Spec;
- E43 := True;
- Interfaces.C'Elab_Spec;
- E69 := True;
- System.Finalization_Root'Elab_Spec;
- E60 := True;
- System.Os_Lib'Elab_Body;
- E71 := True;
- System.Finalization_Implementation'Elab_Spec;
- System.Finalization_Implementation'Elab_Body;
- E62 := True;
- Ada.Finalization'Elab_Spec;
- E58 := True;
- Ada.Finalization.List_Controller'Elab_Spec;
- E76 := True;
- System.File_Control_Block'Elab_Spec;
- E74 := True;
- System.File_Io'Elab_Body;
- E56 := True;
- Ada.Tags'Elab_Body;
- E45 := True;
- Ada.Text_Io'Elab_Spec;
- Ada.Text_Io'Elab_Body;
- E07 := True;
+ ::
+
+ System.Soft_Links'Elab_Body;
+ E14 := True;
+ System.Secondary_Stack'Elab_Body;
+ E18 := True;
+ System.Exception_Table'Elab_Body;
+ E24 := True;
+ Ada.Io_Exceptions'Elab_Spec;
+ E67 := True;
+ Ada.Tags'Elab_Spec;
+ Ada.Streams'Elab_Spec;
+ E43 := True;
+ Interfaces.C'Elab_Spec;
+ E69 := True;
+ System.Finalization_Root'Elab_Spec;
+ E60 := True;
+ System.Os_Lib'Elab_Body;
+ E71 := True;
+ System.Finalization_Implementation'Elab_Spec;
+ System.Finalization_Implementation'Elab_Body;
+ E62 := True;
+ Ada.Finalization'Elab_Spec;
+ E58 := True;
+ Ada.Finalization.List_Controller'Elab_Spec;
+ E76 := True;
+ System.File_Control_Block'Elab_Spec;
+ E74 := True;
+ System.File_Io'Elab_Body;
+ E56 := True;
+ Ada.Tags'Elab_Body;
+ E45 := True;
+ Ada.Text_Io'Elab_Spec;
+ Ada.Text_Io'Elab_Body;
+ E07 := True;
Note also binder switch :switch:`-l`, which outputs the chosen elaboration
order and provides a more readable form of the above:
-::
-
- ada (spec)
- interfaces (spec)
- system (spec)
- system.case_util (spec)
- system.case_util (body)
- system.concat_2 (spec)
- system.concat_2 (body)
- system.concat_3 (spec)
- system.concat_3 (body)
- system.htable (spec)
- system.parameters (spec)
- system.parameters (body)
- system.crtl (spec)
- interfaces.c_streams (spec)
- interfaces.c_streams (body)
- system.restrictions (spec)
- system.restrictions (body)
- system.standard_library (spec)
- system.exceptions (spec)
- system.exceptions (body)
- system.storage_elements (spec)
- system.storage_elements (body)
- system.secondary_stack (spec)
- system.stack_checking (spec)
- system.stack_checking (body)
- system.string_hash (spec)
- system.string_hash (body)
- system.htable (body)
- system.strings (spec)
- system.strings (body)
- system.traceback (spec)
- system.traceback (body)
- system.traceback_entries (spec)
- system.traceback_entries (body)
- ada.exceptions (spec)
- ada.exceptions.last_chance_handler (spec)
- system.soft_links (spec)
- system.soft_links (body)
- ada.exceptions.last_chance_handler (body)
- system.secondary_stack (body)
- system.exception_table (spec)
- system.exception_table (body)
- ada.io_exceptions (spec)
- ada.tags (spec)
- ada.streams (spec)
- interfaces.c (spec)
- interfaces.c (body)
- system.finalization_root (spec)
- system.finalization_root (body)
- system.memory (spec)
- system.memory (body)
- system.standard_library (body)
- system.os_lib (spec)
- system.os_lib (body)
- system.unsigned_types (spec)
- system.stream_attributes (spec)
- system.stream_attributes (body)
- system.finalization_implementation (spec)
- system.finalization_implementation (body)
- ada.finalization (spec)
- ada.finalization (body)
- ada.finalization.list_controller (spec)
- ada.finalization.list_controller (body)
- system.file_control_block (spec)
- system.file_io (spec)
- system.file_io (body)
- system.val_uns (spec)
- system.val_util (spec)
- system.val_util (body)
- system.val_uns (body)
- system.wch_con (spec)
- system.wch_con (body)
- system.wch_cnv (spec)
- system.wch_jis (spec)
- system.wch_jis (body)
- system.wch_cnv (body)
- system.wch_stw (spec)
- system.wch_stw (body)
- ada.tags (body)
- ada.exceptions (body)
- ada.text_io (spec)
- ada.text_io (body)
- text_io (spec)
- gdbstr (body)
+ ::
+
+ ada (spec)
+ interfaces (spec)
+ system (spec)
+ system.case_util (spec)
+ system.case_util (body)
+ system.concat_2 (spec)
+ system.concat_2 (body)
+ system.concat_3 (spec)
+ system.concat_3 (body)
+ system.htable (spec)
+ system.parameters (spec)
+ system.parameters (body)
+ system.crtl (spec)
+ interfaces.c_streams (spec)
+ interfaces.c_streams (body)
+ system.restrictions (spec)
+ system.restrictions (body)
+ system.standard_library (spec)
+ system.exceptions (spec)
+ system.exceptions (body)
+ system.storage_elements (spec)
+ system.storage_elements (body)
+ system.secondary_stack (spec)
+ system.stack_checking (spec)
+ system.stack_checking (body)
+ system.string_hash (spec)
+ system.string_hash (body)
+ system.htable (body)
+ system.strings (spec)
+ system.strings (body)
+ system.traceback (spec)
+ system.traceback (body)
+ system.traceback_entries (spec)
+ system.traceback_entries (body)
+ ada.exceptions (spec)
+ ada.exceptions.last_chance_handler (spec)
+ system.soft_links (spec)
+ system.soft_links (body)
+ ada.exceptions.last_chance_handler (body)
+ system.secondary_stack (body)
+ system.exception_table (spec)
+ system.exception_table (body)
+ ada.io_exceptions (spec)
+ ada.tags (spec)
+ ada.streams (spec)
+ interfaces.c (spec)
+ interfaces.c (body)
+ system.finalization_root (spec)
+ system.finalization_root (body)
+ system.memory (spec)
+ system.memory (body)
+ system.standard_library (body)
+ system.os_lib (spec)
+ system.os_lib (body)
+ system.unsigned_types (spec)
+ system.stream_attributes (spec)
+ system.stream_attributes (body)
+ system.finalization_implementation (spec)
+ system.finalization_implementation (body)
+ ada.finalization (spec)
+ ada.finalization (body)
+ ada.finalization.list_controller (spec)
+ ada.finalization.list_controller (body)
+ system.file_control_block (spec)
+ system.file_io (spec)
+ system.file_io (body)
+ system.val_uns (spec)
+ system.val_util (spec)
+ system.val_util (body)
+ system.val_uns (body)
+ system.wch_con (spec)
+ system.wch_con (body)
+ system.wch_cnv (spec)
+ system.wch_jis (spec)
+ system.wch_jis (body)
+ system.wch_cnv (body)
+ system.wch_stw (spec)
+ system.wch_stw (body)
+ ada.tags (body)
+ ada.exceptions (body)
+ ada.text_io (spec)
+ ada.text_io (body)
+ text_io (spec)
+ gdbstr (body)
diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
index 9cbdb15..de348e9 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
@@ -3972,7 +3972,7 @@ execution of this erroneous program:
::
- $ gnatmem [ switches ] user_program
+ $ gnatmem [ switches ] [ DEPTH ] user_program
The program must have been linked with the instrumented version of the
allocation and deallocation routines. This is done by linking with the
@@ -4062,15 +4062,16 @@ execution of this erroneous program:
memory leaks. Omits statistical information.
- .. index:: N switch (gnatmem)
+ .. index:: DEPTH switch (gnatmem)
- :samp:`{N}`
- ``N`` is an integer literal (usually between 1 and 10) which controls the
- depth of the backtraces defining allocation root. The default value for
- N is 1. The deeper the backtrace, the more precise the localization of
+ :samp:`{DEPTH}`
+ ``DEPTH`` is an integer literal (usually between 1 and 10) which controls
+ the depth of the backtraces defining allocation root. The default value for
+ DEPTH is 1. The deeper the backtrace, the more precise the localization of
the root. Note that the total number of roots can depend on this
- parameter. This parameter must be specified *before* the name of the
- executable to be analyzed, to avoid ambiguity.
+ parameter, in other words there may be more roots when the requested
+ backtrace depth is higher. This parameter must be specified *before* the
+ name of the executable to be analyzed, to avoid ambiguity.
.. index:: -b (gnatmem)
diff --git a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
index 53904b1..fc39214 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
@@ -1214,7 +1214,7 @@ The following switches are available:
:samp:`f`
By default, gnathtml will generate html links only for global entities
- ('with'ed units, global variables and types,...). If you specify
+ ('with'ed units, global variables and types,...). If you specify
:switch:`-f` on the command line, then links will be generated for local
entities too.
@@ -1310,7 +1310,7 @@ Alternatively, you may run the script using the following command line:
``gnat2xml`` is a project-aware tool
(see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches). The project file package that can specify
+ the project-related switches). The project file package that can specify
``gnat2xml`` switches is named ``gnat2xml``.
.. _Switches_for_``gnat2xml``:
@@ -1780,7 +1780,7 @@ Alternatively, you may run the script using the following command line:
``gnatcheck`` is a project-aware tool
(see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches). The project file package that can specify
+ the project-related switches). The project file package that can specify
``gnatcheck`` switches is named ``Check``.
For full details, plese refer to :title:`GNATcheck Reference Manual`.
@@ -1804,11 +1804,11 @@ Alternatively, you may run the script using the following command line:
for computing various program metrics.
It takes an Ada source file as input and generates a file containing the
metrics data as output. Various switches control which
- metrics are computed and output.
+ metrics are reported.
``gnatmetric`` is a project-aware tool
(see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches). The project file package that can specify
+ the project-related switches). The project file package that can specify
``gnatmetric`` switches is named ``Metrics``.
The ``gnatmetric`` command has the form
@@ -1921,9 +1921,9 @@ Alternatively, you may run the script using the following command line:
.. index:: --short-file-names (gnatmetric)
:switch:`--short-file-names`
- Use 'short' source file names in the output. (The ``gnatmetric``
+ Use 'short' source file names in the output. (The ``gnatmetric``
output includes the name(s) of the Ada source file(s) from which the
- metrics are computed. By default each name includes the absolute
+ metrics are computed. By default each name includes the absolute
path. The :switch:`--short-file-names` switch causes ``gnatmetric``
to exclude all directory information from the file names that are
output.)
@@ -1980,12 +1980,11 @@ Alternatively, you may run the script using the following command line:
Specifying a set of metrics to compute
--------------------------------------
- By default all the metrics are computed and reported. The switches
- described in this subsection allow you to control, on an individual
- basis, whether metrics are computed and reported. If at least one
- positive metric switch is specified (that is, a switch that defines
- that a given metric or set of metrics is to be computed), then only
- explicitly specified metrics are reported.
+ By default all the metrics are reported. The switches described in this
+ subsection allow you to control, on an individual basis, whether metrics are
+ reported. If at least one positive metric switch is specified (that is, a
+ switch that defines that a given metric or set of metrics is to be computed),
+ then only explicitly specified metrics are reported.
.. _Line_Metrics_Control:
@@ -2023,7 +2022,7 @@ Alternatively, you may run the script using the following command line:
code lines in bodies.
You can use the following switches to select the specific line metrics
- to be computed and reported.
+ to be reported.
.. index:: --lines (gnatmetric)
@@ -2089,10 +2088,9 @@ Alternatively, you may run the script using the following command line:
:switch:`--lines-average`
- Report the average number of code lines in subprogram bodies, task
- bodies, entry bodies and statement sequences in package bodies. The
- metric is computed and reported for the whole set of processed Ada
- sources only.
+ Report the average number of code lines in subprogram bodies, task bodies,
+ entry bodies and statement sequences in package bodies. The metric is
+ reported for the whole set of processed Ada sources only.
:switch:`--no-lines-average`
@@ -2173,7 +2171,7 @@ Alternatively, you may run the script using the following command line:
declarations. It is the total number of types that can be
referenced from outside this compilation unit, plus the number of
types from all the visible parts of all the visible generic
- packages. Generic formal types are not counted. Only types, not
+ packages. Generic formal types are not counted. Only types, not
subtypes, are included.
Along with the total number of public types, the following
@@ -2193,14 +2191,14 @@ Alternatively, you may run the script using the following command line:
* *All types*
This metric is computed for any compilation unit. It is equal to
the total number of the declarations of different types given in
- the compilation unit. The private and the corresponding full type
+ the compilation unit. The private and the corresponding full type
declaration are counted as one type declaration. Incomplete type
declarations and generic formal types are not counted.
No distinction is made among different kinds of types (abstract,
- private etc.); the total number of types is computed and reported.
+ private etc.); the total number of types is reported.
- By default, all the syntax metrics are computed and reported. You can
- use the following switches to select specific syntax metrics.
+ By default, all the syntax metrics are reported. You can use the following
+ switches to select specific syntax metrics.
.. index:: --syntax (gnatmetric)
@@ -2311,7 +2309,7 @@ Alternatively, you may run the script using the following command line:
According to McCabe, both control statements and short-circuit control
forms should be taken into account when computing cyclomatic
- complexity. For Ada 2012 we have also take into account conditional
+ complexity. For Ada 2012 we have also take into account conditional
expressions and quantified expressions. For each body, we compute
three metric values:
@@ -2364,9 +2362,8 @@ Alternatively, you may run the script using the following command line:
code of assertions and predicates (that is, subprogram preconditions and
postconditions, subtype predicates and type invariants) is also skipped.
- By default, all the complexity metrics are computed and reported.
- For more fine-grained control you can use
- the following switches:
+ By default, all the complexity metrics are reported. For more fine-grained
+ control you can use the following switches:
.. index:: --complexity (gnatmetric)
@@ -2408,8 +2405,7 @@ Alternatively, you may run the script using the following command line:
:switch:`--complexity-average`
Report the average McCabe Cyclomatic Complexity for all the subprogram bodies,
task bodies, entry bodies and statement sequences in package bodies.
- The metric is computed and reported for whole set of processed Ada sources
- only.
+ The metric is reported for whole set of processed Ada sources only.
:switch:`--no-complexity-average`
@@ -2623,8 +2619,8 @@ Alternatively, you may run the script using the following command line:
by invoking ``gnatmetric`` with the corresponding project file
and with the :switch:`-U` option.
- By default, all the coupling metrics are disabled. You can use the following
- switches to specify the coupling metrics to be computed and reported:
+ By default, all the coupling metrics are reported. You can use the following
+ switches to select specific syntax metrics.
.. index:: --tagged-coupling (gnatmetric)
.. index:: --hierarchy-coupling (gnatmetric)
@@ -2854,14 +2850,14 @@ Alternatively, you may run the script using the following command line:
of ``gnatpp``, which replaces the ASIS-based version.
The ``gnatpp`` tool is a utility for source reformatting / pretty
- printing. It takes an Ada source file as input and generates a
- reformatted version as output. You can specify various style
+ printing. It takes an Ada source file as input and generates a
+ reformatted version as output. You can specify various style
directives via switches; e.g., identifier case conventions, rules of
indentation, and comment layout.
``gnatpp`` is a project-aware tool
(see :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches). The project file package that can specify
+ the project-related switches). The project file package that can specify
``gnatpp`` switches is named ``Pretty_Printer``.
``gnatpp`` cannot process sources that contain preprocessing
@@ -3019,7 +3015,7 @@ Alternatively, you may run the script using the following command line:
.. index:: --enum-upper-case (gnatpp)
:switch:`--enum-upper-case`
- Enumeration literals are in upper case. Overrides -n casing
+ Enumeration literals are in upper case. Overrides -n casing
setting.
.. index:: --enum-lower-case (gnatpp)
@@ -3133,7 +3129,7 @@ Alternatively, you may run the script using the following command line:
compatible.
This group of ``gnatpp`` switches controls the layout of comments and
- complex syntactic constructs. See :ref:`Formatting_Comments` for details
+ complex syntactic constructs. See :ref:`Formatting_Comments` for details
on their effect.
@@ -3248,6 +3244,20 @@ Alternatively, you may run the script using the following command line:
:switch:`--preserve-line-breaks`
Preserve line breaks in the input, to the extent possible.
+ By default, line breaks are also inserted at appropriate
+ places.
+
+ .. index:: --source-line-breaks (gnatpp)
+
+ :switch:`--source-line-breaks`
+ Keep the line breaks from the source; do not insert or delete any
+ line breaks.
+
+ .. index:: --spaces-only (gnatpp)
+
+ :switch:`--spaces-only`
+ Disable all formatting except for inserting and removing spaces.
+ This implies --source-line-breaks.
The ``--comments`` switches are compatible with one another, except
that the ``--comments-unchanged`` switch disables all other comment
@@ -3337,12 +3347,6 @@ Alternatively, you may run the script using the following command line:
'(' and ':'. This also turns off alignment.
- .. index:: --ff-after-pragma-page (gnatpp)
-
- :switch:`--ff-after-pragma-page`
- Insert a Form Feed character after a pragma Page.
-
-
.. index:: --call_threshold (gnatpp)
:switch:`--call_threshold={nnn}`
@@ -3742,10 +3746,10 @@ Alternatively, you may run the script using the following command line:
the same line.
A whole-line comment is indented according to the surrounding code,
- with some exceptions. Comments that start in column 1 are kept
- there. If possible, comments are not moved so far to the right that
- the maximum line length is exceeded. The ``--comments-unchanged``
- option turns off comment formatting. Special-form comments such as
+ with some exceptions. Comments that start in column 1 are kept
+ there. If possible, comments are not moved so far to the right that
+ the maximum line length is exceeded. The ``--comments-unchanged``
+ option turns off comment formatting. Special-form comments such as
SPARK-style ``--#...`` are left alone.
For an end-of-line comment, ``gnatpp`` tries to leave the same
@@ -3770,7 +3774,7 @@ Alternatively, you may run the script using the following command line:
are formatted according to the ``--comments-gnat-beginning`` and
``--comments-fill`` switches; other formatting switches are ignored. For
example, ``--comments-only --comments-fill`` means to fill comment
- paragraphs, and do nothing else. Likewise, ``--comments-only
+ paragraphs, and do nothing else. Likewise, ``--comments-only
--comments-gnat-beginning`` ensures comments start with at least two
spaces after ``--``, and ``--comments-only --comments-gnat-beginning
--comments-fill`` does both. If ``--comments-only`` is given without
@@ -3787,11 +3791,11 @@ Alternatively, you may run the script using the following command line:
the same casing as the corresponding defining identifier.
You control the casing for defining occurrences via the ``--name...``
- switches. With ``--name-case-as-declared``, which is the default,
+ switches. With ``--name-case-as-declared``, which is the default,
defining occurrences appear exactly as in the source file where they
- are declared. The other values for this switch --
+ are declared. The other values for this switch --
``--name-upper-case``, ``--name-lower-case``, ``--name-mixed-case``
- -- result in upper, lower, or mixed case, respectively. If
+ -- result in upper, lower, or mixed case, respectively. If
``gnatpp`` changes the casing of a defining occurrence, it
analogously changes the casing of all the usage occurrences of this
name.
@@ -3799,7 +3803,7 @@ Alternatively, you may run the script using the following command line:
If the defining occurrence of a name is not in the source compilation
unit currently being processed by ``gnatpp``, the casing of each
reference to this name is changed according to the switch (subject to
- the dictionary file mechanism described below). Thus ``gnatpp`` acts
+ the dictionary file mechanism described below). Thus ``gnatpp`` acts
as though the switch had affected the casing for the defining
occurrence of the name.
@@ -3836,7 +3840,7 @@ Alternatively, you may run the script using the following command line:
``-n`` switch or explicit dictionary files. For
example, by default the names ``Ada.Text_IO`` and
``GNAT.OS_Lib`` will appear as just shown, even in the presence of
- a ``--name-upper-case`` switch. To ensure that even
+ a ``--name-upper-case`` switch. To ensure that even
such names are rendered in uppercase, additionally supply the
--dictionary=- switch (or else place these names
in upper case in a dictionary file).
@@ -3933,6 +3937,67 @@ Alternatively, you may run the script using the following command line:
Name2_NAME3_Name4 := Name4_NAME3_Name2 > NAME1;
end Test;
+ .. _Preprocessor_directives:
+
+ Preprocessor Directives
+ ^^^^^^^^^^^^^^^^^^^^^^^
+
+ ``gnatpp`` has some support for preprocessor directives.
+ You can use preprocessor symbols, as in ``$symbol``.
+ In addition, you can use conditional compilation,
+ so long as the program text is syntactically legal Ada code
+ after removing all the preprocessor directives (lines starting
+ with ``#``). For example, ``gnatpp`` can format the following:
+
+ .. code-block:: ada
+
+ package P is
+ #IF SOMETHING
+ X : constant Integer := 123;
+ #ELSE
+ X : constant Integer := 456;
+ #END IF;
+ end P;
+
+ which will be formatted as if it were:
+
+ .. code-block:: ada
+
+ package P is
+ X : constant Integer := 123;
+ X : constant Integer := 456;
+ end P;
+
+ except that the ``#`` lines will be preserved.
+ However, ``gnatpp`` cannot format the following:
+
+ .. code-block:: ada
+
+ procedure P is
+ begin
+ #IF SOMETHING
+ if X = 0 then
+ #ELSE
+ if X = 1 then
+ #END IF;
+ null;
+ end if;
+ end P;
+
+ because removing the ``#`` lines gives:
+
+ .. code-block:: ada
+
+ procedure P is
+ begin
+ if X = 0 then
+ if X = 1 then
+ null;
+ end if;
+ end P;
+
+ which is not syntactically legal.
+
Legacy Switches
^^^^^^^^^^^^^^^
@@ -4062,11 +4127,6 @@ Alternatively, you may run the script using the following command line:
:switch:`-cl{nnn}`
:switch:`--indent-continuation={nnn}`
- .. index:: -ff (gnatpp)
-
- :switch:`-ff`
- :switch:`--ff-after-pragma-page`
-
.. index:: -pipe (gnatpp)
:switch:`-pipe`
@@ -4690,7 +4750,7 @@ Alternatively, you may run the script using the following command line:
:switch:`--subdir={dirname}`
Test packages are placed in a subdirectory of the corresponding source
directory, with the name ``dirname``. Thus, each set of unit tests is located
- in a subdirectory of the code under test. If the sources are in separate
+ in a subdirectory of the code under test. If the sources are in separate
directories, each source directory has a test subdirectory named ``dirname``.
diff --git a/gcc/ada/doc/gnat_ugn/platform_specific_information.rst b/gcc/ada/doc/gnat_ugn/platform_specific_information.rst
index eaae612..13993b8 100644
--- a/gcc/ada/doc/gnat_ugn/platform_specific_information.rst
+++ b/gcc/ada/doc/gnat_ugn/platform_specific_information.rst
@@ -260,7 +260,7 @@ This section describes topics that are specific to the Microsoft Windows
platforms.
-.. only:: PRO or GPL
+.. only:: PRO
.. rubric:: Installing from the Command Line
@@ -273,32 +273,15 @@ platforms.
line you should pass parameter :switch:`/S` (and, optionally,
:switch:`/D=<directory>`) as command-line arguments.
-.. only:: PRO
-
- For example, for an unattended installation of
- GNAT 7.0.2 into the default directory
- ``C:\\GNATPRO\\7.0.2`` you would run:
-
- ::
-
- gnatpro-7.0.2-i686-pc-mingw32-bin.exe /S
-
- To install into a custom directory, say, ``C:\\TOOLS\\GNATPRO\\7.0.2``:
-
- ::
-
- gnatpro-7.0.2-i686-pc-mingw32-bin /S /D=C:\TOOLS\GNATPRO\7.0.2
-
-.. only:: GPL
-
For example, for an unattended installation of
- GNAT 2012 into ``C:\\GNAT\\2012``:
+ GNAT 19.2 into the default directory :file:`C:\\GNATPRO\\19.2` you
+ would run::
- ::
+ gnatpro-19.2-x86-windows-bin /S
- gnat-gpl-2012-i686-pc-mingw32-bin /S /D=C:\GNAT\2012
+ To install into a custom directory, say, :file:`C:\\TOOLS\\GNATPRO\\19.2`::
-.. only:: PRO or GPL
+ gnatpro-19.2-x86-windows-bin /S /D=C:\TOOLS\GNATPRO\19.2
You can use the same syntax for all installers.
@@ -306,7 +289,6 @@ platforms.
associations, so such activities need to be done by hand.
-
.. _Using_GNAT_on_Windows:
Using GNAT on Windows
@@ -488,6 +470,49 @@ and::
Ada.Command_Line.Argument (1) -> "'*.txt'"
+Windows Socket Timeouts
+-----------------------
+
+Microsoft Windows desktops older than ``8.0`` and Microsoft Windows Servers
+older than ``2019`` set a socket timeout 500 milliseconds longer than the value
+set by setsockopt with ``SO_RCVTIMEO`` and ``SO_SNDTIMEO`` options. The GNAT
+runtime makes a correction for the difference in the corresponding Windows
+versions. For Windows Server starting with version ``2019``, the user must
+provide a manifest file for the GNAT runtime to be able to recognize that
+the Windows version does not need the timeout correction. The manifest file
+should be located in the same directory as the executable file, and its file
+name must match the executable name suffixed by ``.manifest``. For example,
+if the executable name is :file:`sock_wto.exe`, then the manifest file name
+has to be :file:`sock_wto.exe.manifest`. The manifest file must contain at
+least the following data::
+
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!-- Windows Vista -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!-- Windows 7 -->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!-- Windows 8 -->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!-- Windows 8.1 -->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!-- Windows 10 -->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+ </compatibility>
+ </assembly>
+
+Without the manifest file, the socket timeout is going to be overcorrected on
+these Windows Server versions and the actual time is going to be 500
+milliseconds shorter than what was set with GNAT.Sockets.Set_Socket_Option.
+Note that on Microsoft Windows versions where correction is necessary, there
+is no way to set a socket timeout shorter than 500 ms. If a socket timeout
+shorter than 500 ms is needed on these Windows versions, a call to
+Check_Selector should be added before any socket read or write operations.
+
+
.. _Mixed-Language_Programming_on_Windows:
Mixed-Language Programming on Windows
diff --git a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
index 48fedfe..d7388bb 100644
--- a/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
+++ b/gcc/ada/doc/gnat_ugn/the_gnat_compilation_model.rst
@@ -4531,8 +4531,9 @@ Some of the known limitations include:
* identifiers with identical name (except casing) will generate compilation
errors (e.g. ``shm_get`` vs ``SHM_GET``).
-The code generated is using the Ada 2005 syntax, which makes it
-easier to interface with other languages than previous versions of Ada.
+The code is generated using Ada 2012 syntax, which makes it easier to interface
+with other languages. In most cases you can still use the generated binding
+even if your code is compiled using earlier versions of Ada (e.g. ``-gnat95``).
.. _Running_the_binding_generator:
@@ -4547,7 +4548,7 @@ header files needed by these files transitively. For example:
.. code-block:: sh
$ g++ -c -fdump-ada-spec -C /usr/include/time.h
- $ gcc -c -gnat05 *.ads
+ $ gcc -c *.ads
will generate, under GNU/Linux, the following files: :file:`time_h.ads`,
:file:`bits_time_h.ads`, :file:`stddef_h.ads`, :file:`bits_types_h.ads` which
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index b9a9a8d..8ff9ec6 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -421,7 +421,6 @@ package body Einfo is
-- Never_Set_In_Source Flag115
-- Is_Visible_Lib_Unit Flag116
-- Is_Unchecked_Union Flag117
- -- Is_For_Access_Subtype Flag118
-- Has_Convention_Pragma Flag119
-- Has_Primitive_Operations Flag120
@@ -2303,12 +2302,6 @@ package body Einfo is
return Flag70 (Id);
end Is_First_Subtype;
- function Is_For_Access_Subtype (Id : E) return B is
- begin
- pragma Assert (Ekind_In (Id, E_Record_Subtype, E_Private_Subtype));
- return Flag118 (Id);
- end Is_For_Access_Subtype;
-
function Is_Formal_Subprogram (Id : E) return B is
begin
return Flag111 (Id);
@@ -5526,12 +5519,6 @@ package body Einfo is
Set_Flag70 (Id, V);
end Set_Is_First_Subtype;
- procedure Set_Is_For_Access_Subtype (Id : E; V : B := True) is
- begin
- pragma Assert (Ekind_In (Id, E_Record_Subtype, E_Private_Subtype));
- Set_Flag118 (Id, V);
- end Set_Is_For_Access_Subtype;
-
procedure Set_Is_Formal_Subprogram (Id : E; V : B := True) is
begin
Set_Flag111 (Id, V);
@@ -8127,7 +8114,7 @@ package body Einfo is
function Is_Elaboration_Target (Id : Entity_Id) return Boolean is
begin
return
- Ekind_In (Id, E_Constant, E_Variable)
+ Ekind_In (Id, E_Constant, E_Package, E_Variable)
or else Is_Entry (Id)
or else Is_Generic_Unit (Id)
or else Is_Subprogram (Id)
@@ -9826,7 +9813,6 @@ package body Einfo is
W ("Is_Exported", Flag99 (Id));
W ("Is_Finalized_Transient", Flag252 (Id));
W ("Is_First_Subtype", Flag70 (Id));
- W ("Is_For_Access_Subtype", Flag118 (Id));
W ("Is_Formal_Subprogram", Flag111 (Id));
W ("Is_Frozen", Flag4 (Id));
W ("Is_Generic_Actual_Subprogram", Flag274 (Id));
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 9dc6cc2..78208a1 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -320,7 +320,7 @@ package Einfo is
-- an attempt to set the attribute on a subtype will raise an assert error.
-- Other attributes are noted as applying to the [implementation base type
--- only]. These are representation attributes which must always apply to a
+-- only]. These are representation attributes which must always apply to a
-- full non-private type, and where the attributes are always on the full
-- type. The attribute can be referenced on a subtype (and automatically
-- retrieves the value from the implementation base type). However, it is an
@@ -2608,12 +2608,6 @@ package Einfo is
-- Is_Formal_Subprogram (Flag111)
-- Defined in all entities. Set for generic formal subprograms.
--- Is_For_Access_Subtype (Flag118)
--- Defined in E_Private_Subtype and E_Record_Subtype entities. Means the
--- sole purpose of the type is to be designated by an Access_Subtype and
--- hence should not be expanded into components because the type may not
--- have been found or frozen yet.
-
-- Is_Frozen (Flag4)
-- Defined in all type and subtype entities. Set if type or subtype has
-- been frozen.
@@ -4133,7 +4127,7 @@ package Einfo is
-- Defined in generic subprograms, generic packages, and their
-- instances. Also defined in the instances of the corresponding
-- bodies. Denotes the renaming map (generic entities => instance
--- entities) used to construct the instance by givin an index into
+-- entities) used to construct the instance by giving an index into
-- the tables used to represent these maps. See Sem_Ch12 for further
-- details. The maps for package instances are also used when the
-- instance is the actual corresponding to a formal package.
@@ -4490,7 +4484,7 @@ package Einfo is
-- Suppress_Initialization (Flag105)
-- Defined in all variable, type and subtype entities. If set for a base
-- type, then the generation of initialization procedures is suppressed
--- for the type. Any other implicit initialiation (e.g. from the use of
+-- for the type. Any other implicit initialization (e.g. from the use of
-- pragma Initialize_Scalars) is also suppressed if this flag is set for
-- either the subtype in question, or for the base type. For variables,
-- this flag suppresses all implicit initialization for the object, even
@@ -6458,7 +6452,6 @@ package Einfo is
-- Stored_Constraint (Elist23)
-- Has_Completion (Flag26)
-- Is_Controlled_Active (Flag42) (base type only)
- -- Is_For_Access_Subtype (Flag118) (subtype only)
-- (plus type attributes)
-- E_Procedure
@@ -7311,7 +7304,6 @@ package Einfo is
function Is_Exported (Id : E) return B;
function Is_Finalized_Transient (Id : E) return B;
function Is_First_Subtype (Id : E) return B;
- function Is_For_Access_Subtype (Id : E) return B;
function Is_Frozen (Id : E) return B;
function Is_Generic_Instance (Id : E) return B;
function Is_Hidden (Id : E) return B;
@@ -8012,7 +8004,6 @@ package Einfo is
procedure Set_Is_Exported (Id : E; V : B := True);
procedure Set_Is_Finalized_Transient (Id : E; V : B := True);
procedure Set_Is_First_Subtype (Id : E; V : B := True);
- procedure Set_Is_For_Access_Subtype (Id : E; V : B := True);
procedure Set_Is_Formal_Subprogram (Id : E; V : B := True);
procedure Set_Is_Frozen (Id : E; V : B := True);
procedure Set_Is_Generic_Actual_Subprogram (Id : E; V : B := True);
@@ -8859,7 +8850,6 @@ package Einfo is
pragma Inline (Is_First_Subtype);
pragma Inline (Is_Fixed_Point_Type);
pragma Inline (Is_Floating_Point_Type);
- pragma Inline (Is_For_Access_Subtype);
pragma Inline (Is_Formal);
pragma Inline (Is_Formal_Object);
pragma Inline (Is_Formal_Subprogram);
@@ -9376,7 +9366,6 @@ package Einfo is
pragma Inline (Set_Is_Exported);
pragma Inline (Set_Is_Finalized_Transient);
pragma Inline (Set_Is_First_Subtype);
- pragma Inline (Set_Is_For_Access_Subtype);
pragma Inline (Set_Is_Formal_Subprogram);
pragma Inline (Set_Is_Frozen);
pragma Inline (Set_Is_Generic_Actual_Subprogram);
diff --git a/gcc/ada/env.c b/gcc/ada/env.c
index cf839f5..698b177 100644
--- a/gcc/ada/env.c
+++ b/gcc/ada/env.c
@@ -30,15 +30,11 @@
****************************************************************************/
#ifdef IN_RTS
-# include "tconfig.h"
-# include "tsystem.h"
+# include "runtime.h"
+# include <stdio.h>
+# include <stdlib.h>
+# include <string.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-# include <time.h>
-# ifdef VMS
-# include <unixio.h>
-# endif
/* We don't have libiberty, so use malloc. */
# define xmalloc(S) malloc (S)
#else /* IN_RTS */
@@ -60,6 +56,9 @@
#endif
#if defined (__vxworks)
+ #include <vxWorks.h>
+ #include <version.h>
+
#if defined (__RTP__)
/* On VxWorks 6 Real-Time process mode, environ is defined in unistd.h. */
#include <unistd.h>
@@ -69,14 +68,18 @@
envLib.h on VxWorks MILS and VxWorks 653. */
#include <vThreadsData.h>
#include <envLib.h>
- #else
- /* This should work for kernel mode on both VxWorks 5 and VxWorks 6. */
+ #elif (_WRS_VXWORKS_MAJOR <= 6)
#include <envLib.h>
-
- /* In that mode environ is a macro which reference the following symbol.
- As the symbol is not defined in any VxWorks include files we declare
- it as extern. */
+ /* In that mode the following symbol is not defined in any VxWorks
+ include files, prior to vxWorks 7, so we declare it as extern. */
extern char** ppGlobalEnviron;
+ #elif (_WRS_VXWORKS_MAJOR >= 7)
+ /* This should work for kernel mode on VxWorks 7.x. In 7.2 the tcb
+ is made private, so accessor functions must be used, in 7.0 it
+ is optional but there is no way to distinguish between 7.2
+ and 7.0 since the version.h header file was never updated. */
+ #include <envLib.h>
+ #include <taskLibCommon.h>
#endif
#endif
@@ -102,89 +105,10 @@ __gnat_getenv (char *name, int *len, char **value)
return;
}
-/* VMS specific declarations for set_env_value. */
-
-#ifdef VMS
-
-typedef struct _ile3
-{
- unsigned short len, code;
- __char_ptr32 adr;
- __char_ptr32 retlen_adr;
-} ile_s;
-
-#endif
-
void
__gnat_setenv (char *name, char *value)
{
-#if defined (VMS)
- struct dsc$descriptor_s name_desc;
- $DESCRIPTOR (table_desc, "LNM$PROCESS");
- char *host_pathspec = value;
- char *copy_pathspec;
- int num_dirs_in_pathspec = 1;
- char *ptr;
- long status;
-
- name_desc.dsc$w_length = strlen (name);
- name_desc.dsc$b_dtype = DSC$K_DTYPE_T;
- name_desc.dsc$b_class = DSC$K_CLASS_S;
- name_desc.dsc$a_pointer = name; /* ??? Danger, not 64bit safe. */
-
- if (*host_pathspec == 0)
- /* deassign */
- {
- status = LIB$DELETE_LOGICAL (&name_desc, &table_desc);
- /* no need to check status; if the logical name is not
- defined, that's fine. */
- return;
- }
-
- ptr = host_pathspec;
- while (*ptr++)
- if (*ptr == ',')
- num_dirs_in_pathspec++;
-
- {
- int i, status;
- /* Alloca is guaranteed to be 32bit. */
- ile_s *ile_array = alloca (sizeof (ile_s) * (num_dirs_in_pathspec + 1));
- char *copy_pathspec = alloca (strlen (host_pathspec) + 1);
- char *curr, *next;
-
- strcpy (copy_pathspec, host_pathspec);
- curr = copy_pathspec;
- for (i = 0; i < num_dirs_in_pathspec; i++)
- {
- next = strchr (curr, ',');
- if (next == 0)
- next = strchr (curr, 0);
-
- *next = 0;
- ile_array[i].len = strlen (curr);
-
- /* Code 2 from lnmdef.h means it's a string. */
- ile_array[i].code = 2;
- ile_array[i].adr = curr;
-
- /* retlen_adr is ignored. */
- ile_array[i].retlen_adr = 0;
- curr = next + 1;
- }
-
- /* Terminating item must be zero. */
- ile_array[i].len = 0;
- ile_array[i].code = 0;
- ile_array[i].adr = 0;
- ile_array[i].retlen_adr = 0;
-
- status = LIB$SET_LOGICAL (&name_desc, 0, &table_desc, 0, ile_array);
- if ((status & 1) != 1)
- LIB$SIGNAL (status);
- }
-
-#elif (defined (__vxworks) && defined (__RTP__)) || defined (__APPLE__)
+#if (defined (__vxworks) && defined (__RTP__)) || defined (__APPLE__)
setenv (name, value, 1);
#else
@@ -206,10 +130,7 @@ __gnat_setenv (char *name, char *value)
char **
__gnat_environ (void)
{
-#if defined (VMS) || defined (RTX)
- /* Not implemented */
- return NULL;
-#elif defined (__MINGW32__)
+#if defined (__MINGW32__)
return _environ;
#elif defined (__sun__)
extern char **_environ;
@@ -223,16 +144,24 @@ __gnat_environ (void)
extern char **environ;
return environ;
#else
- return environ;
+ #if defined (__RTP__) || defined (VTHREADS) || (_WRS_VXWORKS_MAJOR <= 6)
+ return environ;
+ #elif (_WRS_VXWORKS_MAJOR >= 7)
+ char **task_environ;
+
+ task_environ = envGet (taskIdSelf ());
+
+ if (task_environ == NULL)
+ return ppGlobalEnviron;
+ else
+ return task_environ;
+ #endif
#endif
}
void __gnat_unsetenv (char *name)
{
-#if defined (VMS)
- /* Not implemented */
- return;
-#elif defined (__hpux__) || defined (__sun__) \
+#if defined (__hpux__) || defined (__sun__) \
|| (defined (__vxworks) && ! defined (__RTP__)) \
|| defined (_AIX) || defined (__Lynx__)
@@ -288,10 +217,7 @@ void __gnat_unsetenv (char *name)
void __gnat_clearenv (void)
{
-#if defined (VMS)
- /* not implemented */
- return;
-#elif defined (__sun__) \
+#if defined (__sun__) \
|| (defined (__vxworks) && ! defined (__RTP__)) || defined (__Lynx__) \
|| defined (__PikeOS__)
/* On Solaris, VxWorks (not RTPs), and Lynx there is no system
diff --git a/gcc/ada/errno.c b/gcc/ada/errno.c
index a64ae87..18f14ea 100644
--- a/gcc/ada/errno.c
+++ b/gcc/ada/errno.c
@@ -35,21 +35,10 @@
as it may be defined using a macro.
*/
-
+#ifndef _REENTRANT
#define _REENTRANT
-#define _THREAD_SAFE
-
-#ifdef MaRTE
-
-/* MaRTE OS provides its own implementation of errno related functionality. We
- want to ensure the use of the MaRTE version for tasking programs (the MaRTE
- library will not be linked if no tasking constructs are used), so we use the
- weak symbols mechanism to use the MaRTE version whenever is available. */
-
-#pragma weak __get_errno
-#pragma weak __set_errno
-
#endif
+#define _THREAD_SAFE
#include <errno.h>
int
diff --git a/gcc/ada/erroutc.adb b/gcc/ada/erroutc.adb
index 0c8ef5d..81e2910 100644
--- a/gcc/ada/erroutc.adb
+++ b/gcc/ada/erroutc.adb
@@ -53,7 +53,7 @@ package body Erroutc is
function Matches (S : String; P : String) return Boolean;
-- Returns true if the String S patches the pattern P, which can contain
- -- wild card chars (*). The entire pattern must match the entire string.
+ -- wildcard chars (*). The entire pattern must match the entire string.
-- Case is ignored in the comparison (so X matches x).
function Sloc_In_Range (Loc, Start, Stop : Source_Ptr) return Boolean;
@@ -1606,6 +1606,7 @@ package body Erroutc is
if Start <= Cur_Loc and then Cur_Loc <= Stop then
return True;
end if;
+
Cur_Loc := Instantiation_Location (Cur_Loc);
end loop;
diff --git a/gcc/ada/exit.c b/gcc/ada/exit.c
index 3ac3596..3f6ef21 100644
--- a/gcc/ada/exit.c
+++ b/gcc/ada/exit.c
@@ -29,21 +29,6 @@
* *
****************************************************************************/
-#ifdef __alpha_vxworks
-#include "vxWorks.h"
-#endif
-
-#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
-#include <sys/stat.h>
-#else
-#include "config.h"
-#include "system.h"
-#endif
-
-#include "adaint.h"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index b5bd222..c944db6 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -192,7 +192,7 @@ package body Exp_Aggr is
procedure Convert_To_Assignments (N : Node_Id; Typ : Entity_Id);
-- Transform a record aggregate into a sequence of assignments performed
- -- component by component. N is an N_Aggregate or N_Extension_Aggregate.
+ -- component by component. N is an N_Aggregate or N_Extension_Aggregate.
-- Typ is the type of the record aggregate.
procedure Expand_Record_Aggregate
@@ -217,6 +217,11 @@ package body Exp_Aggr is
-- defaults. An aggregate for a type with mutable components must be
-- expanded into individual assignments.
+ function In_Place_Assign_OK (N : Node_Id) return Boolean;
+ -- Predicate to determine whether an aggregate assignment can be done in
+ -- place, because none of the new values can depend on the components of
+ -- the target of the assignment.
+
procedure Initialize_Discriminants (N : Node_Id; Typ : Entity_Id);
-- If the type of the aggregate is a type extension with renamed discrimi-
-- nants, we must initialize the hidden discriminants of the parent.
@@ -646,24 +651,8 @@ package body Exp_Aggr is
-- Checks 11: The C code generator cannot handle aggregates that are
-- not part of an object declaration.
- if Modify_Tree_For_C then
- declare
- Par : Node_Id := Parent (N);
-
- begin
- -- Skip enclosing nested aggregates and their qualified
- -- expressions.
-
- while Nkind (Par) = N_Aggregate
- or else Nkind (Par) = N_Qualified_Expression
- loop
- Par := Parent (Par);
- end loop;
-
- if Nkind (Par) /= N_Object_Declaration then
- return False;
- end if;
- end;
+ if Modify_Tree_For_C and then not Is_CCG_Supported_Aggregate (N) then
+ return False;
end if;
-- Checks on components
@@ -1354,11 +1343,11 @@ package body Exp_Aggr is
-- transient scope, which leads to premature finalization.
-- This in-place expansion is not performed for limited transient
- -- objects because the initialization is already done in-place.
+ -- objects, because the initialization is already done in place.
if In_Place_Expansion then
- -- Suppress the removal of side effects by general analysis
+ -- Suppress the removal of side effects by general analysis,
-- because this behavior is emulated here. This avoids the
-- generation of a transient scope, which leads to out-of-order
-- adjustment and finalization.
@@ -4134,6 +4123,252 @@ package body Exp_Aggr is
Insert_Actions_After (Decl, Aggr_Code);
end Convert_Array_Aggr_In_Allocator;
+ ------------------------
+ -- In_Place_Assign_OK --
+ ------------------------
+
+ function In_Place_Assign_OK (N : Node_Id) return Boolean is
+ Is_Array : constant Boolean := Is_Array_Type (Etype (N));
+
+ Aggr_In : Node_Id;
+ Aggr_Lo : Node_Id;
+ Aggr_Hi : Node_Id;
+ Obj_In : Node_Id;
+ Obj_Lo : Node_Id;
+ Obj_Hi : Node_Id;
+
+ function Safe_Aggregate (Aggr : Node_Id) return Boolean;
+ -- Check recursively that each component of a (sub)aggregate does not
+ -- depend on the variable being assigned to.
+
+ function Safe_Component (Expr : Node_Id) return Boolean;
+ -- Verify that an expression cannot depend on the variable being
+ -- assigned to. Room for improvement here (but less than before).
+
+ --------------------
+ -- Safe_Aggregate --
+ --------------------
+
+ function Safe_Aggregate (Aggr : Node_Id) return Boolean is
+ Expr : Node_Id;
+
+ begin
+ if Nkind (Parent (Aggr)) = N_Iterated_Component_Association then
+ return False;
+ end if;
+
+ if Present (Expressions (Aggr)) then
+ Expr := First (Expressions (Aggr));
+ while Present (Expr) loop
+ if Nkind (Expr) = N_Aggregate then
+ if not Safe_Aggregate (Expr) then
+ return False;
+ end if;
+
+ elsif not Safe_Component (Expr) then
+ return False;
+ end if;
+
+ Next (Expr);
+ end loop;
+ end if;
+
+ if Present (Component_Associations (Aggr)) then
+ Expr := First (Component_Associations (Aggr));
+ while Present (Expr) loop
+ if Nkind (Expression (Expr)) = N_Aggregate then
+ if not Safe_Aggregate (Expression (Expr)) then
+ return False;
+ end if;
+
+ -- If association has a box, no way to determine yet whether
+ -- default can be assigned in place.
+
+ elsif Box_Present (Expr) then
+ return False;
+
+ elsif not Safe_Component (Expression (Expr)) then
+ return False;
+ end if;
+
+ Next (Expr);
+ end loop;
+ end if;
+
+ return True;
+ end Safe_Aggregate;
+
+ --------------------
+ -- Safe_Component --
+ --------------------
+
+ function Safe_Component (Expr : Node_Id) return Boolean is
+ Comp : Node_Id := Expr;
+
+ function Check_Component (Comp : Node_Id) return Boolean;
+ -- Do the recursive traversal, after copy
+
+ ---------------------
+ -- Check_Component --
+ ---------------------
+
+ function Check_Component (Comp : Node_Id) return Boolean is
+ begin
+ if Is_Overloaded (Comp) then
+ return False;
+ end if;
+
+ return Compile_Time_Known_Value (Comp)
+
+ or else (Is_Entity_Name (Comp)
+ and then Present (Entity (Comp))
+ and then Ekind (Entity (Comp)) not in Type_Kind
+ and then No (Renamed_Object (Entity (Comp))))
+
+ or else (Nkind (Comp) = N_Attribute_Reference
+ and then Check_Component (Prefix (Comp)))
+
+ or else (Nkind (Comp) in N_Binary_Op
+ and then Check_Component (Left_Opnd (Comp))
+ and then Check_Component (Right_Opnd (Comp)))
+
+ or else (Nkind (Comp) in N_Unary_Op
+ and then Check_Component (Right_Opnd (Comp)))
+
+ or else (Nkind (Comp) = N_Selected_Component
+ and then Is_Array
+ and then Check_Component (Prefix (Comp)))
+
+ or else (Nkind_In (Comp, N_Type_Conversion,
+ N_Unchecked_Type_Conversion)
+ and then Check_Component (Expression (Comp)));
+ end Check_Component;
+
+ -- Start of processing for Safe_Component
+
+ begin
+ -- If the component appears in an association that may correspond
+ -- to more than one element, it is not analyzed before expansion
+ -- into assignments, to avoid side effects. We analyze, but do not
+ -- resolve the copy, to obtain sufficient entity information for
+ -- the checks that follow. If component is overloaded we assume
+ -- an unsafe function call.
+
+ if not Analyzed (Comp) then
+ if Is_Overloaded (Expr) then
+ return False;
+
+ elsif Nkind (Expr) = N_Aggregate
+ and then not Is_Others_Aggregate (Expr)
+ then
+ return False;
+
+ elsif Nkind (Expr) = N_Allocator then
+
+ -- For now, too complex to analyze
+
+ return False;
+
+ elsif Nkind (Parent (Expr)) = N_Iterated_Component_Association then
+
+ -- Ditto for iterated component associations, which in general
+ -- require an enclosing loop and involve nonstatic expressions.
+
+ return False;
+ end if;
+
+ Comp := New_Copy_Tree (Expr);
+ Set_Parent (Comp, Parent (Expr));
+ Analyze (Comp);
+ end if;
+
+ if Nkind (Comp) = N_Aggregate then
+ return Safe_Aggregate (Comp);
+ else
+ return Check_Component (Comp);
+ end if;
+ end Safe_Component;
+
+ -- Start of processing for In_Place_Assign_OK
+
+ begin
+ -- By-copy semantic cannot be guaranteed for controlled objects or
+ -- objects with discriminants.
+
+ if Needs_Finalization (Etype (N))
+ or else Has_Discriminants (Etype (N))
+ then
+ return False;
+
+ elsif Is_Array and then Present (Component_Associations (N)) then
+
+ -- On assignment, sliding can take place, so we cannot do the
+ -- assignment in place unless the bounds of the aggregate are
+ -- statically equal to those of the target.
+
+ -- If the aggregate is given by an others choice, the bounds are
+ -- derived from the left-hand side, and the assignment is safe if
+ -- the expression is.
+
+ if Is_Others_Aggregate (N) then
+ return
+ Safe_Component
+ (Expression (First (Component_Associations (N))));
+ end if;
+
+ Aggr_In := First_Index (Etype (N));
+
+ if Nkind (Parent (N)) = N_Assignment_Statement then
+ Obj_In := First_Index (Etype (Name (Parent (N))));
+
+ else
+ -- Context is an allocator. Check bounds of aggregate against
+ -- given type in qualified expression.
+
+ pragma Assert (Nkind (Parent (Parent (N))) = N_Allocator);
+ Obj_In := First_Index (Etype (Entity (Subtype_Mark (Parent (N)))));
+ end if;
+
+ while Present (Aggr_In) loop
+ Get_Index_Bounds (Aggr_In, Aggr_Lo, Aggr_Hi);
+ Get_Index_Bounds (Obj_In, Obj_Lo, Obj_Hi);
+
+ if not Compile_Time_Known_Value (Aggr_Lo)
+ or else not Compile_Time_Known_Value (Obj_Lo)
+ or else not Compile_Time_Known_Value (Obj_Hi)
+ or else Expr_Value (Aggr_Lo) /= Expr_Value (Obj_Lo)
+ then
+ return False;
+
+ -- For an assignment statement we require static matching of
+ -- bounds. Ditto for an allocator whose qualified expression
+ -- is a constrained type. If the expression in the allocator
+ -- is an unconstrained array, we accept an upper bound that
+ -- is not static, to allow for nonstatic expressions of the
+ -- base type. Clearly there are further possibilities (with
+ -- diminishing returns) for safely building arrays in place
+ -- here.
+
+ elsif Nkind (Parent (N)) = N_Assignment_Statement
+ or else Is_Constrained (Etype (Parent (N)))
+ then
+ if not Compile_Time_Known_Value (Aggr_Hi)
+ or else Expr_Value (Aggr_Hi) /= Expr_Value (Obj_Hi)
+ then
+ return False;
+ end if;
+ end if;
+
+ Next_Index (Aggr_In);
+ Next_Index (Obj_In);
+ end loop;
+ end if;
+
+ -- Now check the component values themselves
+
+ return Safe_Aggregate (N);
+ end In_Place_Assign_OK;
+
----------------------------
-- Convert_To_Assignments --
----------------------------
@@ -4232,10 +4467,11 @@ package body Exp_Aggr is
Establish_Transient_Scope (N, Manage_Sec_Stack => False);
end if;
- -- If the aggregate is nonlimited, create a temporary. If it is limited
- -- and context is an assignment, this is a subaggregate for an enclosing
- -- aggregate being expanded. It must be built in place, so use target of
- -- the current assignment.
+ -- If the aggregate is nonlimited, create a temporary, since aggregates
+ -- have "by copy" semantics. If it is limited and context is an
+ -- assignment, this is a subaggregate for an enclosing aggregate being
+ -- expanded. It must be built in place, so use target of the current
+ -- assignment.
if Is_Limited_Type (Typ)
and then Nkind (Parent (N)) = N_Assignment_Statement
@@ -4245,16 +4481,14 @@ package body Exp_Aggr is
Build_Record_Aggr_Code (N, Typ, Target_Expr));
Rewrite (Parent (N), Make_Null_Statement (Loc));
- -- Generating C, do not declare a temporary to initialize an aggregate
- -- assigned to Out or In_Out parameters whose type has no discriminants.
- -- This avoids stack overflow errors at run time.
+ -- Do not declare a temporary to initialize an aggregate assigned to an
+ -- identifier when in-place assignment is possible, preserving the
+ -- by-copy semantic of aggregates. This avoids large stack usage and
+ -- generates more efficient code.
- elsif Modify_Tree_For_C
- and then Nkind (Parent (N)) = N_Assignment_Statement
+ elsif Nkind (Parent (N)) = N_Assignment_Statement
and then Nkind (Name (Parent (N))) = N_Identifier
- and then Ekind_In (Entity (Name (Parent (N))), E_Out_Parameter,
- E_In_Out_Parameter)
- and then not Has_Discriminants (Etype (Entity (Name (Parent (N)))))
+ and then In_Place_Assign_OK (N)
then
Target_Expr := New_Copy_Tree (Name (Parent (N)));
Insert_Actions (Parent (N),
@@ -4886,7 +5120,7 @@ package body Exp_Aggr is
-- case pass it as is to Gigi. Note that a necessary condition for
-- static processing is that the aggregate be fully positional.
- -- 5. If in place aggregate expansion is possible (i.e. no need to create
+ -- 5. If in-place aggregate expansion is possible (i.e. no need to create
-- a temporary) then mark the aggregate as such and return. Otherwise
-- create a new temporary and generate the appropriate initialization
-- code.
@@ -4910,7 +5144,7 @@ package body Exp_Aggr is
-- The type of each index
In_Place_Assign_OK_For_Declaration : Boolean := False;
- -- True if we are to generate an in place assignment for a declaration
+ -- True if we are to generate an in-place assignment for a declaration
Maybe_In_Place_OK : Boolean;
-- If the type is neither controlled nor packed and the aggregate
@@ -4945,11 +5179,6 @@ package body Exp_Aggr is
-- subaggregate we start the computation from. Dim is the dimension
-- corresponding to the subaggregate.
- function In_Place_Assign_OK return Boolean;
- -- Simple predicate to determine whether an aggregate assignment can
- -- be done in place, because none of the new values can depend on the
- -- components of the target of the assignment.
-
procedure Others_Check (Sub_Aggr : Node_Id; Dim : Pos);
-- Checks that if an others choice is present in any subaggregate, no
-- aggregate index is outside the bounds of the index constraint.
@@ -5437,242 +5666,6 @@ package body Exp_Aggr is
end if;
end Compute_Others_Present;
- ------------------------
- -- In_Place_Assign_OK --
- ------------------------
-
- function In_Place_Assign_OK return Boolean is
- Aggr_In : Node_Id;
- Aggr_Lo : Node_Id;
- Aggr_Hi : Node_Id;
- Obj_In : Node_Id;
- Obj_Lo : Node_Id;
- Obj_Hi : Node_Id;
-
- function Safe_Aggregate (Aggr : Node_Id) return Boolean;
- -- Check recursively that each component of a (sub)aggregate does not
- -- depend on the variable being assigned to.
-
- function Safe_Component (Expr : Node_Id) return Boolean;
- -- Verify that an expression cannot depend on the variable being
- -- assigned to. Room for improvement here (but less than before).
-
- --------------------
- -- Safe_Aggregate --
- --------------------
-
- function Safe_Aggregate (Aggr : Node_Id) return Boolean is
- Expr : Node_Id;
-
- begin
- if Nkind (Parent (Aggr)) = N_Iterated_Component_Association then
- return False;
- end if;
-
- if Present (Expressions (Aggr)) then
- Expr := First (Expressions (Aggr));
- while Present (Expr) loop
- if Nkind (Expr) = N_Aggregate then
- if not Safe_Aggregate (Expr) then
- return False;
- end if;
-
- elsif not Safe_Component (Expr) then
- return False;
- end if;
-
- Next (Expr);
- end loop;
- end if;
-
- if Present (Component_Associations (Aggr)) then
- Expr := First (Component_Associations (Aggr));
- while Present (Expr) loop
- if Nkind (Expression (Expr)) = N_Aggregate then
- if not Safe_Aggregate (Expression (Expr)) then
- return False;
- end if;
-
- -- If association has a box, no way to determine yet
- -- whether default can be assigned in place.
-
- elsif Box_Present (Expr) then
- return False;
-
- elsif not Safe_Component (Expression (Expr)) then
- return False;
- end if;
-
- Next (Expr);
- end loop;
- end if;
-
- return True;
- end Safe_Aggregate;
-
- --------------------
- -- Safe_Component --
- --------------------
-
- function Safe_Component (Expr : Node_Id) return Boolean is
- Comp : Node_Id := Expr;
-
- function Check_Component (Comp : Node_Id) return Boolean;
- -- Do the recursive traversal, after copy
-
- ---------------------
- -- Check_Component --
- ---------------------
-
- function Check_Component (Comp : Node_Id) return Boolean is
- begin
- if Is_Overloaded (Comp) then
- return False;
- end if;
-
- return Compile_Time_Known_Value (Comp)
-
- or else (Is_Entity_Name (Comp)
- and then Present (Entity (Comp))
- and then No (Renamed_Object (Entity (Comp))))
-
- or else (Nkind (Comp) = N_Attribute_Reference
- and then Check_Component (Prefix (Comp)))
-
- or else (Nkind (Comp) in N_Binary_Op
- and then Check_Component (Left_Opnd (Comp))
- and then Check_Component (Right_Opnd (Comp)))
-
- or else (Nkind (Comp) in N_Unary_Op
- and then Check_Component (Right_Opnd (Comp)))
-
- or else (Nkind (Comp) = N_Selected_Component
- and then Check_Component (Prefix (Comp)))
-
- or else (Nkind (Comp) = N_Unchecked_Type_Conversion
- and then Check_Component (Expression (Comp)));
- end Check_Component;
-
- -- Start of processing for Safe_Component
-
- begin
- -- If the component appears in an association that may correspond
- -- to more than one element, it is not analyzed before expansion
- -- into assignments, to avoid side effects. We analyze, but do not
- -- resolve the copy, to obtain sufficient entity information for
- -- the checks that follow. If component is overloaded we assume
- -- an unsafe function call.
-
- if not Analyzed (Comp) then
- if Is_Overloaded (Expr) then
- return False;
-
- elsif Nkind (Expr) = N_Aggregate
- and then not Is_Others_Aggregate (Expr)
- then
- return False;
-
- elsif Nkind (Expr) = N_Allocator then
-
- -- For now, too complex to analyze
-
- return False;
-
- elsif Nkind (Parent (Expr)) =
- N_Iterated_Component_Association
- then
- -- Ditto for iterated component associations, which in
- -- general require an enclosing loop and involve nonstatic
- -- expressions.
-
- return False;
- end if;
-
- Comp := New_Copy_Tree (Expr);
- Set_Parent (Comp, Parent (Expr));
- Analyze (Comp);
- end if;
-
- if Nkind (Comp) = N_Aggregate then
- return Safe_Aggregate (Comp);
- else
- return Check_Component (Comp);
- end if;
- end Safe_Component;
-
- -- Start of processing for In_Place_Assign_OK
-
- begin
- if Present (Component_Associations (N)) then
-
- -- On assignment, sliding can take place, so we cannot do the
- -- assignment in place unless the bounds of the aggregate are
- -- statically equal to those of the target.
-
- -- If the aggregate is given by an others choice, the bounds are
- -- derived from the left-hand side, and the assignment is safe if
- -- the expression is.
-
- if Is_Others_Aggregate (N) then
- return
- Safe_Component
- (Expression (First (Component_Associations (N))));
- end if;
-
- Aggr_In := First_Index (Etype (N));
-
- if Nkind (Parent (N)) = N_Assignment_Statement then
- Obj_In := First_Index (Etype (Name (Parent (N))));
-
- else
- -- Context is an allocator. Check bounds of aggregate against
- -- given type in qualified expression.
-
- pragma Assert (Nkind (Parent (Parent (N))) = N_Allocator);
- Obj_In :=
- First_Index (Etype (Entity (Subtype_Mark (Parent (N)))));
- end if;
-
- while Present (Aggr_In) loop
- Get_Index_Bounds (Aggr_In, Aggr_Lo, Aggr_Hi);
- Get_Index_Bounds (Obj_In, Obj_Lo, Obj_Hi);
-
- if not Compile_Time_Known_Value (Aggr_Lo)
- or else not Compile_Time_Known_Value (Obj_Lo)
- or else not Compile_Time_Known_Value (Obj_Hi)
- or else Expr_Value (Aggr_Lo) /= Expr_Value (Obj_Lo)
- then
- return False;
-
- -- For an assignment statement we require static matching of
- -- bounds. Ditto for an allocator whose qualified expression
- -- is a constrained type. If the expression in the allocator
- -- is an unconstrained array, we accept an upper bound that
- -- is not static, to allow for nonstatic expressions of the
- -- base type. Clearly there are further possibilities (with
- -- diminishing returns) for safely building arrays in place
- -- here.
-
- elsif Nkind (Parent (N)) = N_Assignment_Statement
- or else Is_Constrained (Etype (Parent (N)))
- then
- if not Compile_Time_Known_Value (Aggr_Hi)
- or else Expr_Value (Aggr_Hi) /= Expr_Value (Obj_Hi)
- then
- return False;
- end if;
- end if;
-
- Next_Index (Aggr_In);
- Next_Index (Obj_In);
- end loop;
- end if;
-
- -- Now check the component values themselves
-
- return Safe_Aggregate (N);
- end In_Place_Assign_OK;
-
------------------
-- Others_Check --
------------------
@@ -6219,7 +6212,7 @@ package body Exp_Aggr is
-- STEP 4
- -- Look if in place aggregate expansion is possible
+ -- Check whether in-place aggregate expansion is possible
-- For object declarations we build the aggregate in place, unless
-- the array is bit-packed.
@@ -6255,11 +6248,11 @@ package body Exp_Aggr is
else
Maybe_In_Place_OK :=
(Nkind (Parent (N)) = N_Assignment_Statement
- and then In_Place_Assign_OK)
+ and then In_Place_Assign_OK (N))
or else
(Nkind (Parent (Parent (N))) = N_Allocator
- and then In_Place_Assign_OK);
+ and then In_Place_Assign_OK (N));
end if;
-- If this is an array of tasks, it will be expanded into build-in-place
@@ -6371,7 +6364,7 @@ package body Exp_Aggr is
-- Step 5
- -- In place aggregate expansion is not possible
+ -- In-place aggregate expansion is not possible
else
Maybe_In_Place_OK := False;
@@ -6423,11 +6416,11 @@ package body Exp_Aggr is
Target := New_Copy (Tmp);
end if;
- -- If we are to generate an in place assignment for a declaration or
+ -- If we are to generate an in-place assignment for a declaration or
-- an assignment statement, and the assignment can be done directly
-- by the back end, then do not expand further.
- -- ??? We can also do that if in place expansion is not possible but
+ -- ??? We can also do that if in-place expansion is not possible but
-- then we could go into an infinite recursion.
if (In_Place_Assign_OK_For_Declaration or else Maybe_In_Place_OK)
@@ -7685,30 +7678,31 @@ package body Exp_Aggr is
function Is_CCG_Supported_Aggregate
(N : Node_Id) return Boolean
is
- In_Obj_Decl : Boolean := False;
- P : Node_Id := Parent (N);
+ P : Node_Id := Parent (N);
begin
- while Present (P) loop
- if Nkind (P) = N_Object_Declaration then
- In_Obj_Decl := True;
- end if;
+ -- Aggregates are not supported for nonstandard rep clauses, since they
+ -- may lead to extra padding fields in CCG.
+
+ if Ekind (Etype (N)) in Record_Kind
+ and then Has_Non_Standard_Rep (Etype (N))
+ then
+ return False;
+ end if;
+ while Present (P) and then Nkind (P) = N_Aggregate loop
P := Parent (P);
end loop;
-- Cases where aggregates are supported by the CCG backend
- if In_Obj_Decl then
- if Nkind (Parent (N)) = N_Object_Declaration then
- return True;
+ if Nkind (P) = N_Object_Declaration then
+ return True;
- elsif Nkind (Parent (N)) = N_Qualified_Expression
- and then Nkind_In (Parent (Parent (N)), N_Allocator,
- N_Object_Declaration)
- then
- return True;
- end if;
+ elsif Nkind (P) = N_Qualified_Expression
+ and then Nkind_In (Parent (P), N_Allocator, N_Object_Declaration)
+ then
+ return True;
end if;
return False;
@@ -8757,7 +8751,7 @@ package body Exp_Aggr is
Val := 0;
Packed_Num := 0;
- -- Account for endianness. See corresponding comment in
+ -- Account for endianness. See corresponding comment in
-- Packed_Array_Aggregate_Handled concerning the following.
if Bytes_Big_Endian
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 1e1b2f9..9d6da33 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -39,6 +39,7 @@ with Exp_Pakd; use Exp_Pakd;
with Exp_Strm; use Exp_Strm;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
+with Expander; use Expander;
with Freeze; use Freeze;
with Gnatvsn; use Gnatvsn;
with Itypes; use Itypes;
@@ -1384,12 +1385,15 @@ package body Exp_Attr is
Stmts : List_Id;
begin
+ Func_Id := Make_Temporary (Loc, 'F');
+
-- Wrap the condition of the while loop in a Boolean function.
-- This avoids the duplication of the same code which may lead
-- to gigi issues with respect to multiple declaration of the
-- same entity in the presence of side effects or checks. Note
- -- that the condition actions must also be relocated to the
- -- wrapping function.
+ -- that the condition actions must also be relocated into the
+ -- wrapping function because they may contain itypes, e.g. in
+ -- the case of a comparison involving slices.
-- Generate:
-- <condition actions>
@@ -1403,7 +1407,9 @@ package body Exp_Attr is
Append_To (Stmts,
Make_Simple_Return_Statement (Loc,
- Expression => Relocate_Node (Condition (Scheme))));
+ Expression =>
+ New_Copy_Tree (Condition (Scheme),
+ New_Scope => Func_Id)));
-- Generate:
-- function Fnn return Boolean is
@@ -1411,7 +1417,6 @@ package body Exp_Attr is
-- <Stmts>
-- end Fnn;
- Func_Id := Make_Temporary (Loc, 'F');
Func_Decl :=
Make_Subprogram_Body (Loc,
Specification =>
@@ -3279,6 +3284,13 @@ package body Exp_Attr is
Expr := Unchecked_Convert_To (Ptyp, First (Exprs));
+ -- Ensure that the expression is not truncated since the "bad" bits
+ -- are desired.
+
+ if Nkind (Expr) = N_Unchecked_Type_Conversion then
+ Set_No_Truncation (Expr);
+ end if;
+
Insert_Action (N,
Make_Raise_Constraint_Error (Loc,
Condition =>
@@ -3529,7 +3541,7 @@ package body Exp_Attr is
-- We transform
-- fixtype'Fixed_Value (integer-value)
- -- inttype'Fixed_Value (fixed-value)
+ -- inttype'Integer_Value (fixed-value)
-- into
@@ -3538,75 +3550,30 @@ package body Exp_Attr is
-- respectively.
- -- We do all the required analysis of the conversion here, because we do
- -- not want this to go through the fixed-point conversion circuits. Note
- -- that the back end always treats fixed-point as equivalent to the
- -- corresponding integer type anyway.
- -- However, in order to remove the handling of Do_Range_Check from the
- -- backend, we force the generation of a check on the result by
- -- setting the result type appropriately. Apply_Conversion_Checks
- -- will generate the required expansion.
+ -- We set Conversion_OK on the conversion because we do not want it
+ -- to go through the fixed-point conversion circuits.
when Attribute_Fixed_Value
| Attribute_Integer_Value
=>
- Rewrite (N,
- Make_Type_Conversion (Loc,
- Subtype_Mark => New_Occurrence_Of (Entity (Pref), Loc),
- Expression => Relocate_Node (First (Exprs))));
-
- -- Indicate that the result of the conversion may require a
- -- range check (see below);
+ Rewrite (N, OK_Convert_To (Entity (Pref), First (Exprs)));
- Set_Etype (N, Base_Type (Entity (Pref)));
- Set_Analyzed (N);
-
- -- Note: it might appear that a properly analyzed unchecked
+ -- Note that it might appear that a properly analyzed unchecked
-- conversion would be just fine here, but that's not the case,
- -- since the full range checks performed by the following code
+ -- since the full range checks performed by the following calls
-- are critical.
- -- Given that Fixed-point conversions are not further expanded
- -- to prevent the involvement of real type operations we have to
- -- construct two checks explicitly: one on the operand, and one
- -- on the result. This used to be done in part in the back-end,
- -- but for other targets (E.g. LLVM) it is preferable to create
- -- the tests in full in the front-end.
-
- if Is_Fixed_Point_Type (Etype (N)) then
- declare
- Loc : constant Source_Ptr := Sloc (N);
- Equiv_T : constant Entity_Id := Make_Temporary (Loc, 'T', N);
- Expr : constant Node_Id := Expression (N);
- Fst : constant Entity_Id := Root_Type (Etype (N));
- Decl : Node_Id;
-
- begin
- Decl :=
- Make_Full_Type_Declaration (Sloc (N),
- Defining_Identifier => Equiv_T,
- Type_Definition =>
- Make_Signed_Integer_Type_Definition (Loc,
- Low_Bound =>
- Make_Integer_Literal (Loc,
- Intval =>
- Corresponding_Integer_Value
- (Type_Low_Bound (Fst))),
- High_Bound =>
- Make_Integer_Literal (Loc,
- Intval =>
- Corresponding_Integer_Value
- (Type_High_Bound (Fst)))));
- Insert_Action (N, Decl);
- -- Verify that the conversion is possible
+ Apply_Type_Conversion_Checks (N);
- Generate_Range_Check (Expr, Equiv_T, CE_Overflow_Check_Failed);
+ -- Note that Apply_Type_Conversion_Checks only deals with the
+ -- overflow checks on conversions involving fixed-point types
+ -- so we must apply range checks manually on them and expand.
- -- and verify that the result is in range
+ Apply_Scalar_Range_Check
+ (Expression (N), Etype (N), Fixed_Int => True);
- Generate_Range_Check (N, Etype (N), CE_Range_Check_Failed);
- end;
- end if;
+ Set_Analyzed (N);
+ Expand (N);
-----------
-- Floor --
@@ -3997,11 +3964,14 @@ package body Exp_Attr is
declare
Rtyp : constant Entity_Id := Root_Type (P_Type);
- Expr : Node_Id;
+
+ Expr : Node_Id; -- call to Descendant_Tag
+ Get_Tag : Node_Id; -- expression to read the 'Tag
begin
-- Read the internal tag (RM 13.13.2(34)) and use it to
- -- initialize a dummy tag value. We used to generate:
+ -- initialize a dummy tag value. We used to unconditionally
+ -- generate:
--
-- Descendant_Tag (String'Input (Strm), P_Type);
--
@@ -4012,6 +3982,11 @@ package body Exp_Attr is
-- String_Input_Blk_IO, except that if the String is
-- absurdly long, it raises an exception.
--
+ -- However, if the No_Stream_Optimizations restriction
+ -- is active, we disable this unnecessary attempt at
+ -- robustness; we really need to read the string
+ -- character-by-character.
+ --
-- This value is used only to provide a controlling
-- argument for the eventual _Input call. Descendant_Tag is
-- called rather than Internal_Tag to ensure that we have a
@@ -4026,18 +4001,30 @@ package body Exp_Attr is
-- this constant in Cntrl, but this caused a secondary stack
-- leak.
+ if Restriction_Active (No_Stream_Optimizations) then
+ Get_Tag :=
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ New_Occurrence_Of (Standard_String, Loc),
+ Attribute_Name => Name_Input,
+ Expressions => New_List (
+ Relocate_Node (Duplicate_Subexpr (Strm))));
+ else
+ Get_Tag :=
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of
+ (RTE (RE_String_Input_Tag), Loc),
+ Parameter_Associations => New_List (
+ Relocate_Node (Duplicate_Subexpr (Strm))));
+ end if;
+
Expr :=
Make_Function_Call (Loc,
Name =>
New_Occurrence_Of (RTE (RE_Descendant_Tag), Loc),
Parameter_Associations => New_List (
- Make_Function_Call (Loc,
- Name =>
- New_Occurrence_Of
- (RTE (RE_String_Input_Tag), Loc),
- Parameter_Associations => New_List (
- Relocate_Node (Duplicate_Subexpr (Strm)))),
-
+ Get_Tag,
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (P_Type, Loc),
Attribute_Name => Name_Tag)));
diff --git a/gcc/ada/exp_ch11.adb b/gcc/ada/exp_ch11.adb
index 7296e6f..29d8718 100644
--- a/gcc/ada/exp_ch11.adb
+++ b/gcc/ada/exp_ch11.adb
@@ -1308,8 +1308,8 @@ package body Exp_Ch11 is
Append_To (L,
Make_Character_Literal (Loc,
- Chars => Name_uA,
- Char_Literal_Value => UI_From_Int (Character'Pos ('A'))));
+ Chars => Name_uA,
+ Char_Literal_Value => UI_From_Int (Character'Pos ('A'))));
-- Name_Length component: Nam'Length
diff --git a/gcc/ada/exp_ch13.adb b/gcc/ada/exp_ch13.adb
index 6ee7f75..f3c2c01 100644
--- a/gcc/ada/exp_ch13.adb
+++ b/gcc/ada/exp_ch13.adb
@@ -232,7 +232,7 @@ package body Exp_Ch13 is
Convert_To (RTE (RE_Size_Type), Expression (N)));
-- If the clause is not generated by an aspect, insert
- -- the assignment here. Freezing rules ensure that this
+ -- the assignment here. Freezing rules ensure that this
-- is safe, or clause will have been rejected already.
if Is_List_Member (N) then
@@ -724,7 +724,7 @@ package body Exp_Ch13 is
end if;
-- If the record representation clause has no components, then
- -- completely remove it. Note that we also have to remove
+ -- completely remove it. Note that we also have to remove
-- ourself from the Rep Item list.
if Is_Empty_List (Component_Clauses (N)) then
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 753c5fb..834aaa3 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -1555,23 +1555,19 @@ package body Exp_Ch3 is
-- Handle the optionally generated formal *_skip_null_excluding_checks
- if Needs_Conditional_Null_Excluding_Check (Full_Init_Type) then
-
- -- Look at the associated node for the object we are referencing
- -- and verify that we are expanding a call to an Init_Proc for an
- -- internally generated object declaration before passing True and
- -- skipping the relevant checks.
-
- if Nkind (Id_Ref) in N_Has_Entity
- and then Comes_From_Source (Associated_Node (Id_Ref))
- then
- Append_To (Args, New_Occurrence_Of (Standard_True, Loc));
-
- -- Otherwise, we pass False to perform null-excluding checks
-
- else
- Append_To (Args, New_Occurrence_Of (Standard_False, Loc));
- end if;
+ -- Look at the associated node for the object we are referencing and
+ -- verify that we are expanding a call to an Init_Proc for an internally
+ -- generated object declaration before passing True and skipping the
+ -- relevant checks.
+
+ if Needs_Conditional_Null_Excluding_Check (Full_Init_Type)
+ and then Nkind (Id_Ref) in N_Has_Entity
+ and then (Comes_From_Source (Id_Ref)
+ or else (Present (Associated_Node (Id_Ref))
+ and then Comes_From_Source
+ (Associated_Node (Id_Ref))))
+ then
+ Append_To (Args, New_Occurrence_Of (Standard_True, Loc));
end if;
-- Add discriminant values if discriminants are present
@@ -4852,7 +4848,7 @@ package body Exp_Ch3 is
Make_Range (Sloc (Enumeration_Rep_Expr (Ent)),
Low_Bound =>
Make_Integer_Literal (Loc,
- Intval => Enumeration_Rep (Ent)),
+ Intval => Enumeration_Rep (Ent)),
High_Bound =>
Make_Integer_Literal (Loc, Intval => Last_Repval))),
@@ -8695,6 +8691,7 @@ package body Exp_Ch3 is
Make_Defining_Identifier (Loc,
New_External_Name (Chars
(Component_Type (Typ)), "_skip_null_excluding_check")),
+ Expression => New_Occurrence_Of (Standard_False, Loc),
In_Present => True,
Parameter_Type =>
New_Occurrence_Of (Standard_Boolean, Loc)));
@@ -9480,14 +9477,22 @@ package body Exp_Ch3 is
-- or a null statement if the list L is empty
+ -- Equality may be user-defined for a given component type, in which case
+ -- a function call is constructed instead of an operator node. This is an
+ -- Ada 2012 change in the composability of equality for untagged composite
+ -- types.
+
function Make_Eq_If
(E : Entity_Id;
L : List_Id) return Node_Id
is
- Loc : constant Source_Ptr := Sloc (E);
+ Loc : constant Source_Ptr := Sloc (E);
+
C : Node_Id;
- Field_Name : Name_Id;
Cond : Node_Id;
+ Field_Name : Name_Id;
+ Next_Test : Node_Id;
+ Typ : Entity_Id;
begin
if No (L) then
@@ -9498,6 +9503,7 @@ package body Exp_Ch3 is
C := First_Non_Pragma (L);
while Present (C) loop
+ Typ := Etype (Defining_Identifier (C));
Field_Name := Chars (Defining_Identifier (C));
-- The tags must not be compared: they are not part of the value.
@@ -9510,22 +9516,55 @@ package body Exp_Ch3 is
-- discriminants could be picked up in the private type case.
if Field_Name = Name_uParent
- and then Is_Interface (Etype (Defining_Identifier (C)))
+ and then Is_Interface (Typ)
then
null;
elsif Field_Name /= Name_uTag then
- Evolve_Or_Else (Cond,
- Make_Op_Ne (Loc,
- Left_Opnd =>
- Make_Selected_Component (Loc,
- Prefix => Make_Identifier (Loc, Name_X),
- Selector_Name => Make_Identifier (Loc, Field_Name)),
+ declare
+ Lhs : constant Node_Id :=
+ Make_Selected_Component (Loc,
+ Prefix => Make_Identifier (Loc, Name_X),
+ Selector_Name => Make_Identifier (Loc, Field_Name));
- Right_Opnd =>
- Make_Selected_Component (Loc,
- Prefix => Make_Identifier (Loc, Name_Y),
- Selector_Name => Make_Identifier (Loc, Field_Name))));
+ Rhs : constant Node_Id :=
+ Make_Selected_Component (Loc,
+ Prefix => Make_Identifier (Loc, Name_Y),
+ Selector_Name => Make_Identifier (Loc, Field_Name));
+ Eq_Call : Node_Id;
+
+ begin
+ -- Build equality code with a user-defined operator, if
+ -- available, and with the predefined "=" otherwise. For
+ -- compatibility with older Ada versions, and preserve the
+ -- workings of some ASIS tools, we also use the predefined
+ -- operation if the component-type equality is abstract,
+ -- rather than raising Program_Error.
+
+ if Ada_Version < Ada_2012 then
+ Next_Test := Make_Op_Ne (Loc, Lhs, Rhs);
+
+ else
+ Eq_Call := Build_Eq_Call (Typ, Loc, Lhs, Rhs);
+
+ if No (Eq_Call) then
+ Next_Test := Make_Op_Ne (Loc, Lhs, Rhs);
+
+ -- If a component has a defined abstract equality, its
+ -- application raises Program_Error on that component
+ -- and therefore on the current variant.
+
+ elsif Nkind (Eq_Call) = N_Raise_Program_Error then
+ Set_Etype (Eq_Call, Standard_Boolean);
+ Next_Test := Make_Op_Not (Loc, Eq_Call);
+
+ else
+ Next_Test := Make_Op_Not (Loc, Eq_Call);
+ end if;
+ end if;
+ end;
+
+ Evolve_Or_Else (Cond, Next_Test);
end if;
Next_Non_Pragma (C);
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index b9aa4a5..e4dc06b 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -72,6 +72,7 @@ with Ttypes; use Ttypes;
with Uintp; use Uintp;
with Urealp; use Urealp;
with Validsw; use Validsw;
+with Warnsw; use Warnsw;
package body Exp_Ch4 is
@@ -415,6 +416,52 @@ package body Exp_Ch4 is
return;
end Build_Boolean_Array_Proc_Call;
+ -----------------------
+ -- Build_Eq_Call --
+ -----------------------
+
+ function Build_Eq_Call
+ (Typ : Entity_Id;
+ Loc : Source_Ptr;
+ Lhs : Node_Id;
+ Rhs : Node_Id) return Node_Id
+ is
+ Prim : Node_Id;
+ Prim_E : Elmt_Id;
+
+ begin
+ Prim_E := First_Elmt (Collect_Primitive_Operations (Typ));
+ while Present (Prim_E) loop
+ Prim := Node (Prim_E);
+
+ -- Locate primitive equality with the right signature
+
+ if Chars (Prim) = Name_Op_Eq
+ and then Etype (First_Formal (Prim)) =
+ Etype (Next_Formal (First_Formal (Prim)))
+ and then Etype (Prim) = Standard_Boolean
+ then
+ if Is_Abstract_Subprogram (Prim) then
+ return
+ Make_Raise_Program_Error (Loc,
+ Reason => PE_Explicit_Raise);
+
+ else
+ return
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Prim, Loc),
+ Parameter_Associations => New_List (Lhs, Rhs));
+ end if;
+ end if;
+
+ Next_Elmt (Prim_E);
+ end loop;
+
+ -- If not found, predefined operation will be used
+
+ return Empty;
+ end Build_Eq_Call;
+
--------------------------------
-- Displace_Allocator_Pointer --
--------------------------------
@@ -1938,7 +1985,7 @@ package body Exp_Ch4 is
Parameter_Specifications => Formals,
Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)),
- Declarations => Decls,
+ Declarations => Decls,
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
@@ -2338,52 +2385,6 @@ package body Exp_Ch4 is
Full_Type : Entity_Id;
Eq_Op : Entity_Id;
- function Find_Primitive_Eq return Node_Id;
- -- AI05-0123: Locate primitive equality for type if it exists, and
- -- build the corresponding call. If operation is abstract, replace
- -- call with an explicit raise. Return Empty if there is no primitive.
-
- -----------------------
- -- Find_Primitive_Eq --
- -----------------------
-
- function Find_Primitive_Eq return Node_Id is
- Prim_E : Elmt_Id;
- Prim : Node_Id;
-
- begin
- Prim_E := First_Elmt (Collect_Primitive_Operations (Typ));
- while Present (Prim_E) loop
- Prim := Node (Prim_E);
-
- -- Locate primitive equality with the right signature
-
- if Chars (Prim) = Name_Op_Eq
- and then Etype (First_Formal (Prim)) =
- Etype (Next_Formal (First_Formal (Prim)))
- and then Etype (Prim) = Standard_Boolean
- then
- if Is_Abstract_Subprogram (Prim) then
- return
- Make_Raise_Program_Error (Loc,
- Reason => PE_Explicit_Raise);
-
- else
- return
- Make_Function_Call (Loc,
- Name => New_Occurrence_Of (Prim, Loc),
- Parameter_Associations => New_List (Lhs, Rhs));
- end if;
- end if;
-
- Next_Elmt (Prim_E);
- end loop;
-
- -- If not found, predefined operation will be used
-
- return Empty;
- end Find_Primitive_Eq;
-
-- Start of processing for Expand_Composite_Equality
begin
@@ -2654,7 +2655,7 @@ package body Exp_Ch4 is
-- a primitive equality declared for it.
declare
- Op : constant Node_Id := Find_Primitive_Eq;
+ Op : constant Node_Id := Build_Eq_Call (Typ, Loc, Lhs, Rhs);
begin
-- Use user-defined primitive if it exists, otherwise use
@@ -4248,9 +4249,12 @@ package body Exp_Ch4 is
function Size_In_Storage_Elements (E : Entity_Id) return Node_Id;
-- Given a constrained array type E, returns a node representing the
- -- code to compute the size in storage elements for the given type.
- -- This is done without using the attribute (which malfunctions for
- -- large sizes ???)
+ -- code to compute a close approximation of the size in storage elements
+ -- for the given type; for indexes that are modular types we compute
+ -- 'Last - First (instead of 'Length) because for large arrays computing
+ -- 'Last -'First + 1 causes overflow. This is done without using the
+ -- attribute 'Size_In_Storage_Elements (which malfunctions for large
+ -- sizes ???)
-------------------------
-- Rewrite_Coextension --
@@ -4309,17 +4313,77 @@ package body Exp_Ch4 is
-- just a fraction of a storage element???
declare
+ Idx : Node_Id := First_Index (E);
Len : Node_Id;
Res : Node_Id;
pragma Warnings (Off, Res);
begin
for J in 1 .. Number_Dimensions (E) loop
- Len :=
- Make_Attribute_Reference (Loc,
- Prefix => New_Occurrence_Of (E, Loc),
- Attribute_Name => Name_Length,
- Expressions => New_List (Make_Integer_Literal (Loc, J)));
+
+ if not Is_Modular_Integer_Type (Etype (Idx)) then
+ Len :=
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (E, Loc),
+ Attribute_Name => Name_Length,
+ Expressions => New_List
+ (Make_Integer_Literal (Loc, J)));
+
+ -- For indexes that are modular types we cannot generate code
+ -- to compute 'Length since for large arrays 'Last -'First + 1
+ -- causes overflow; therefore we compute 'Last - 'First (which
+ -- is not the exact number of components but it is valid for
+ -- the purpose of this runtime check on 32-bit targets)
+
+ else
+ declare
+ Len_Minus_1_Expr : Node_Id;
+ Test_Gt : Node_Id;
+
+ begin
+ Test_Gt :=
+ Make_Op_Gt (Loc,
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (E, Loc),
+ Attribute_Name => Name_Last,
+ Expressions =>
+ New_List (Make_Integer_Literal (Loc, J))),
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (E, Loc),
+ Attribute_Name => Name_First,
+ Expressions =>
+ New_List (Make_Integer_Literal (Loc, J))));
+
+ Len_Minus_1_Expr :=
+ Convert_To (Standard_Unsigned,
+ Make_Op_Subtract (Loc,
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (E, Loc),
+ Attribute_Name => Name_Last,
+ Expressions =>
+ New_List
+ (Make_Integer_Literal (Loc, J))),
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (E, Loc),
+ Attribute_Name => Name_First,
+ Expressions =>
+ New_List
+ (Make_Integer_Literal (Loc, J)))));
+
+ -- Handle superflat arrays, i.e. arrays with such bounds
+ -- as 4 .. 2, to insure that the result is correct.
+
+ -- Generate:
+ -- (if X'Last > X'First then X'Last - X'First else 0)
+
+ Len :=
+ Make_If_Expression (Loc,
+ Expressions => New_List (
+ Test_Gt,
+ Len_Minus_1_Expr,
+ Make_Integer_Literal (Loc, Uint_0)));
+ end;
+ end if;
if J = 1 then
Res := Len;
@@ -4330,6 +4394,8 @@ package body Exp_Ch4 is
Left_Opnd => Res,
Right_Opnd => Len);
end if;
+
+ Next_Index (Idx);
end loop;
return
@@ -4354,6 +4420,15 @@ package body Exp_Ch4 is
-- Start of processing for Expand_N_Allocator
begin
+ -- Warn on the presence of an allocator of an anonymous access type when
+ -- enabled.
+
+ if Warn_On_Anonymous_Allocators
+ and then Ekind (PtrT) = E_Anonymous_Access_Type
+ then
+ Error_Msg_N ("?use of an anonymous access type allocator", N);
+ end if;
+
-- RM E.2.3(22). We enforce that the expected type of an allocator
-- shall not be a remote access-to-class-wide-limited-private type
@@ -4563,15 +4638,83 @@ package body Exp_Ch4 is
-- apply the check for constrained arrays, and manually compute the
-- value of the attribute ???
- if Is_Array_Type (Etyp) and then Is_Constrained (Etyp) then
- Insert_Action (N,
- Make_Raise_Storage_Error (Loc,
- Condition =>
- Make_Op_Gt (Loc,
- Left_Opnd => Size_In_Storage_Elements (Etyp),
- Right_Opnd =>
- Make_Integer_Literal (Loc, Uint_7 * (Uint_2 ** 29))),
- Reason => SE_Object_Too_Large));
+ -- The check on No_Initialization is used here to prevent generating
+ -- this runtime check twice when the allocator is locally replaced by
+ -- the expander by another one.
+
+ if Is_Array_Type (Etyp) and then not No_Initialization (N) then
+ declare
+ Cond : Node_Id;
+ Ins_Nod : Node_Id := N;
+ Siz_Typ : Entity_Id := Etyp;
+ Expr : Node_Id;
+
+ begin
+ -- For unconstrained array types initialized with a qualified
+ -- expression we use its type to perform this check
+
+ if not Is_Constrained (Etyp)
+ and then not No_Initialization (N)
+ and then Nkind (Expression (N)) = N_Qualified_Expression
+ then
+ Expr := Expression (Expression (N));
+ Siz_Typ := Etype (Expression (Expression (N)));
+
+ -- If the qualified expression has been moved to an internal
+ -- temporary (to remove side effects) then we must insert
+ -- the runtime check before its declaration to ensure that
+ -- the check is performed before the execution of the code
+ -- computing the qualified expression.
+
+ if Nkind (Expr) = N_Identifier
+ and then Is_Internal_Name (Chars (Expr))
+ and then
+ Nkind (Parent (Entity (Expr))) = N_Object_Declaration
+ then
+ Ins_Nod := Parent (Entity (Expr));
+ else
+ Ins_Nod := Expr;
+ end if;
+ end if;
+
+ if Is_Constrained (Siz_Typ)
+ and then Ekind (Siz_Typ) /= E_String_Literal_Subtype
+ then
+ -- For CCG targets the largest array may have up to 2**31-1
+ -- components (i.e. 2 Gigabytes if each array component is
+ -- 1-byte). This insures that fat pointer fields do not
+ -- overflow, since they are 32-bit integer types, and also
+ -- insures that 'Length can be computed at run time.
+
+ if Modify_Tree_For_C then
+ Cond :=
+ Make_Op_Gt (Loc,
+ Left_Opnd => Size_In_Storage_Elements (Siz_Typ),
+ Right_Opnd => Make_Integer_Literal (Loc,
+ Uint_2 ** 31 - Uint_1));
+
+ -- For native targets the largest object is 3.5 gigabytes
+
+ else
+ Cond :=
+ Make_Op_Gt (Loc,
+ Left_Opnd => Size_In_Storage_Elements (Siz_Typ),
+ Right_Opnd => Make_Integer_Literal (Loc,
+ Uint_7 * (Uint_2 ** 29)));
+ end if;
+
+ Insert_Action (Ins_Nod,
+ Make_Raise_Storage_Error (Loc,
+ Condition => Cond,
+ Reason => SE_Object_Too_Large));
+
+ if Entity (Cond) = Standard_True then
+ Error_Msg_N
+ ("object too large: Storage_Error will be raised at "
+ & "run time??", N);
+ end if;
+ end if;
+ end;
end if;
end if;
@@ -4751,6 +4894,9 @@ package body Exp_Ch4 is
-- Case of initialization procedure present, must be called
+ -- NOTE: There is a *huge* amount of code duplication here from
+ -- Build_Initialization_Call. We should probably refactor???
+
else
Check_Restriction (No_Default_Initialization, N);
@@ -5074,7 +5220,6 @@ package body Exp_Ch4 is
------------------------------
procedure Expand_N_Case_Expression (N : Node_Id) is
-
function Is_Copy_Type (Typ : Entity_Id) return Boolean;
-- Return True if we can copy objects of this type when expanding a case
-- expression.
@@ -5093,7 +5238,7 @@ package body Exp_Ch4 is
or else
(Minimize_Expression_With_Actions
and then Is_Constrained (Underlying_Type (Typ))
- and then not Is_Limited_View (Underlying_Type (Typ)));
+ and then not Is_Limited_Type (Underlying_Type (Typ)));
end Is_Copy_Type;
-- Local variables
@@ -5270,6 +5415,7 @@ package body Exp_Ch4 is
declare
Alt_Expr : Node_Id := Expression (Alt);
Alt_Loc : constant Source_Ptr := Sloc (Alt_Expr);
+ LHS : Node_Id;
Stmts : List_Id;
begin
@@ -5299,9 +5445,12 @@ package body Exp_Ch4 is
-- Target := AX['Unrestricted_Access];
else
+ LHS := New_Occurrence_Of (Target, Loc);
+ Set_Assignment_OK (LHS);
+
Stmts := New_List (
Make_Assignment_Statement (Alt_Loc,
- Name => New_Occurrence_Of (Target, Loc),
+ Name => LHS,
Expression => Alt_Expr));
end if;
@@ -6123,6 +6272,10 @@ package body Exp_Ch4 is
-- Similarly, do not rewrite membership as a validity check if
-- within the predicate function for the type.
+ -- Finally, if the original bounds are type conversions, even
+ -- if they have been folded into constants, there are different
+ -- types involved and 'Valid is not appropriate.
+
then
if In_Instance
or else (Ekind (Current_Scope) = E_Function
@@ -6130,6 +6283,11 @@ package body Exp_Ch4 is
then
null;
+ elsif Nkind (Lo_Orig) = N_Type_Conversion
+ or else Nkind (Hi_Orig) = N_Type_Conversion
+ then
+ null;
+
else
Substitute_Valid_Check;
goto Leave;
@@ -6759,7 +6917,7 @@ package body Exp_Ch4 is
-- Renaming objects in renaming associations
-- This case is handled when a use of the renamed variable occurs
- -- Actual parameters for a procedure call
+ -- Actual parameters for a subprogram call
-- This case is handled in Exp_Ch6.Expand_Actuals
-- The second expression in a 'Read attribute reference
@@ -6780,11 +6938,12 @@ package body Exp_Ch4 is
if Nkind (Parnt) = N_Unchecked_Expression then
null;
- elsif Nkind_In (Parnt, N_Object_Renaming_Declaration,
- N_Procedure_Call_Statement)
+ elsif Nkind (Parnt) = N_Object_Renaming_Declaration then
+ return;
+
+ elsif Nkind (Parnt) in N_Subprogram_Call
or else (Nkind (Parnt) = N_Parameter_Association
- and then
- Nkind (Parent (Parnt)) = N_Procedure_Call_Statement)
+ and then Nkind (Parent (Parnt)) in N_Subprogram_Call)
then
return;
@@ -7400,7 +7559,7 @@ package body Exp_Ch4 is
-- Obj1 : Enclosing_Non_UU_Type;
-- Obj2 : Enclosing_Non_UU_Type (1);
- -- ... Obj1 = Obj2 ...
+ -- ... Obj1 = Obj2 ...
-- Generated code:
@@ -10124,7 +10283,6 @@ package body Exp_Ch4 is
Apply_Constraint_Check (Operand, Target_Type, No_Sliding => True);
if Do_Range_Check (Operand) then
- Set_Do_Range_Check (Operand, False);
Generate_Range_Check (Operand, Target_Type, CE_Range_Check_Failed);
end if;
end Expand_N_Qualified_Expression;
@@ -10313,12 +10471,6 @@ package body Exp_Ch4 is
Insert_Explicit_Dereference (P);
Analyze_And_Resolve (P, Designated_Type (Ptyp));
- if Ekind (Etype (P)) = E_Private_Subtype
- and then Is_For_Access_Subtype (Etype (P))
- then
- Set_Etype (P, Base_Type (Etype (P)));
- end if;
-
Ptyp := Etype (P);
end if;
@@ -10785,9 +10937,12 @@ package body Exp_Ch4 is
procedure Expand_N_Type_Conversion (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Operand : constant Node_Id := Expression (N);
- Target_Type : constant Entity_Id := Etype (N);
+ Target_Type : Entity_Id := Etype (N);
Operand_Type : Entity_Id := Etype (Operand);
+ procedure Discrete_Range_Check;
+ -- Handles generation of range check for discrete target value
+
procedure Handle_Changed_Representation;
-- This is called in the case of record and array type conversions to
-- see if there is a change of representation to be handled. Change of
@@ -10810,6 +10965,49 @@ package body Exp_Ch4 is
-- True iff Present (Effective_Extra_Accessibility (Id)) successfully
-- evaluates to True.
+ --------------------------
+ -- Discrete_Range_Check --
+ --------------------------
+
+ -- Case of conversions to a discrete type
+
+ procedure Discrete_Range_Check is
+ Expr : Node_Id;
+ Ityp : Entity_Id;
+
+ begin
+ -- Nothing to do if conversion was rewritten
+
+ if Nkind (N) /= N_Type_Conversion then
+ return;
+ end if;
+
+ Expr := Expression (N);
+
+ -- Before we do a range check, we have to deal with treating
+ -- a fixed-point operand as an integer. The way we do this
+ -- is simply to do an unchecked conversion to an appropriate
+ -- integer type large enough to hold the result.
+
+ if Is_Fixed_Point_Type (Etype (Expr)) then
+ if Esize (Base_Type (Etype (Expr))) > Esize (Standard_Integer) then
+ Ityp := Standard_Long_Long_Integer;
+ else
+ Ityp := Standard_Integer;
+ end if;
+
+ Set_Do_Range_Check (Expr, False);
+ Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
+ end if;
+
+ -- Reset overflow flag, since the range check will include
+ -- dealing with possible overflow, and generate the check.
+
+ Set_Do_Overflow_Check (N, False);
+
+ Generate_Range_Check (Expr, Target_Type, CE_Range_Check_Failed);
+ end Discrete_Range_Check;
+
-----------------------------------
-- Handle_Changed_Representation --
-----------------------------------
@@ -11025,7 +11223,6 @@ package body Exp_Ch4 is
Btyp : constant Entity_Id := Base_Type (Target_Type);
Lo : constant Node_Id := Type_Low_Bound (Target_Type);
Hi : constant Node_Id := Type_High_Bound (Target_Type);
- Xtyp : constant Entity_Id := Etype (Operand);
Conv : Node_Id;
Hi_Arg : Node_Id;
@@ -11049,6 +11246,12 @@ package body Exp_Ch4 is
and then
Hi = Type_High_Bound (Btyp))
then
+ -- Unset the range check flag on the current value of
+ -- Expression (N), since the captured Operand may have
+ -- been rewritten (such as for the case of a conversion
+ -- to a fixed-point type).
+
+ Set_Do_Range_Check (Expression (N), False);
return;
end if;
@@ -11058,6 +11261,7 @@ package body Exp_Ch4 is
if Is_Entity_Name (Operand)
and then Range_Checks_Suppressed (Entity (Operand))
then
+ Set_Do_Range_Check (Expression (N), False);
return;
end if;
@@ -11067,12 +11271,12 @@ package body Exp_Ch4 is
-- not trust it to be in range (might be infinite)
declare
- S_Lo : constant Node_Id := Type_Low_Bound (Xtyp);
- S_Hi : constant Node_Id := Type_High_Bound (Xtyp);
+ S_Lo : constant Node_Id := Type_Low_Bound (Operand_Type);
+ S_Hi : constant Node_Id := Type_High_Bound (Operand_Type);
begin
- if (not Is_Floating_Point_Type (Xtyp)
- or else Is_Constrained (Xtyp))
+ if (not Is_Floating_Point_Type (Operand_Type)
+ or else Is_Constrained (Operand_Type))
and then Compile_Time_Known_Value (S_Lo)
and then Compile_Time_Known_Value (S_Hi)
and then Compile_Time_Known_Value (Hi)
@@ -11085,7 +11289,7 @@ package body Exp_Ch4 is
S_Hiv : Ureal;
begin
- if Is_Real_Type (Xtyp) then
+ if Is_Real_Type (Operand_Type) then
S_Lov := Expr_Value_R (S_Lo);
S_Hiv := Expr_Value_R (S_Hi);
else
@@ -11097,30 +11301,17 @@ package body Exp_Ch4 is
and then S_Lov >= D_Lov
and then S_Hiv <= D_Hiv
then
- -- Unset the range check flag on the current value of
- -- Expression (N), since the captured Operand may have
- -- been rewritten (such as for the case of a conversion
- -- to a fixed-point type).
-
Set_Do_Range_Check (Expression (N), False);
-
return;
end if;
end;
end if;
end;
- -- For float to float conversions, we are done
-
- if Is_Floating_Point_Type (Xtyp)
- and then
- Is_Floating_Point_Type (Btyp)
- then
- return;
- end if;
-
-- Otherwise rewrite the conversion as described above
+ Set_Do_Range_Check (Expression (N), False);
+
Conv := Relocate_Node (N);
Rewrite (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
Set_Etype (Conv, Btyp);
@@ -11129,7 +11320,7 @@ package body Exp_Ch4 is
-- where it is never required, since we can never have overflow in
-- this case.
- if not Is_Integer_Type (Etype (Operand)) then
+ if not Is_Integer_Type (Operand_Type) then
Enable_Overflow_Check (Conv);
end if;
@@ -11468,6 +11659,7 @@ package body Exp_Ch4 is
then
if not Comes_From_Source (N)
and then Nkind_In (Parent (N), N_Function_Call,
+ N_Parameter_Association,
N_Procedure_Call_Statement)
and then Is_Interface (Designated_Type (Target_Type))
and then Is_Class_Wide_Type (Designated_Type (Target_Type))
@@ -11750,31 +11942,21 @@ package body Exp_Ch4 is
then
Set_Rounded_Result (N);
Set_Etype (N, Etype (Parent (N)));
+ Target_Type := Etype (N);
end if;
- -- Otherwise do correct fixed-conversion, but skip these if the
- -- Conversion_OK flag is set, because from a semantic point of view
- -- these are simple integer conversions needing no further processing
- -- (the backend will simply treat them as integers).
-
- if not Conversion_OK (N) then
- if Is_Fixed_Point_Type (Etype (N)) then
- Expand_Convert_Fixed_To_Fixed (N);
- Real_Range_Check;
-
- elsif Is_Integer_Type (Etype (N)) then
- Expand_Convert_Fixed_To_Integer (N);
-
- -- The result of the conversion might need a range check, so do
- -- not assume that the result is in bounds.
+ if Is_Fixed_Point_Type (Target_Type) then
+ Expand_Convert_Fixed_To_Fixed (N);
+ Real_Range_Check;
- Set_Etype (N, Base_Type (Target_Type));
+ elsif Is_Integer_Type (Target_Type) then
+ Expand_Convert_Fixed_To_Integer (N);
+ Discrete_Range_Check;
- else
- pragma Assert (Is_Floating_Point_Type (Etype (N)));
- Expand_Convert_Fixed_To_Float (N);
- Real_Range_Check;
- end if;
+ else
+ pragma Assert (Is_Floating_Point_Type (Target_Type));
+ Expand_Convert_Fixed_To_Float (N);
+ Real_Range_Check;
end if;
-- Case of conversions to a fixed-point type
@@ -11796,42 +11978,6 @@ package body Exp_Ch4 is
Real_Range_Check;
end if;
- -- Case of float-to-integer conversions
-
- -- We also handle float-to-fixed conversions with Conversion_OK set
- -- since semantically the fixed-point target is treated as though it
- -- were an integer in such cases.
-
- elsif Is_Floating_Point_Type (Operand_Type)
- and then
- (Is_Integer_Type (Target_Type)
- or else
- (Is_Fixed_Point_Type (Target_Type) and then Conversion_OK (N)))
- then
- -- One more check here, gcc is still not able to do conversions of
- -- this type with proper overflow checking, and so gigi is doing an
- -- approximation of what is required by doing floating-point compares
- -- with the end-point. But that can lose precision in some cases, and
- -- give a wrong result. Converting the operand to Universal_Real is
- -- helpful, but still does not catch all cases with 64-bit integers
- -- on targets with only 64-bit floats.
-
- -- The above comment seems obsoleted by Apply_Float_Conversion_Check
- -- Can this code be removed ???
-
- if Do_Range_Check (Operand) then
- Rewrite (Operand,
- Make_Type_Conversion (Loc,
- Subtype_Mark =>
- New_Occurrence_Of (Universal_Real, Loc),
- Expression =>
- Relocate_Node (Operand)));
-
- Set_Etype (Operand, Universal_Real);
- Enable_Range_Check (Operand);
- Set_Do_Range_Check (Expression (Operand), False);
- end if;
-
-- Case of array conversions
-- Expansion of array conversions, add required length/range checks but
@@ -11914,11 +12060,6 @@ package body Exp_Ch4 is
Analyze_And_Resolve (N, Target_Type);
end if;
-
- -- Case of conversions to floating-point
-
- elsif Is_Floating_Point_Type (Target_Type) then
- Real_Range_Check;
end if;
-- At this stage, either the conversion node has been transformed into
@@ -11936,80 +12077,54 @@ package body Exp_Ch4 is
-- Check: are these rules stated in sinfo??? if so, why restate here???
-- The only remaining step is to generate a range check if we still have
- -- a type conversion at this stage and Do_Range_Check is set. For now we
- -- do this only for conversions of discrete types and for float-to-float
- -- conversions.
-
- if Nkind (N) = N_Type_Conversion then
+ -- a type conversion at this stage and Do_Range_Check is set. Note that
+ -- we need to deal with at most 8 out of the 9 possible cases of numeric
+ -- conversions here, because the float-to-integer case is entirely dealt
+ -- with by Apply_Float_Conversion_Check.
- -- For now we only support floating-point cases where both source
- -- and target are floating-point types. Conversions where the source
- -- and target involve integer or fixed-point types are still TBD,
- -- though not clear whether those can even happen at this point, due
- -- to transformations above. ???
+ if Nkind (N) = N_Type_Conversion
+ and then Do_Range_Check (Expression (N))
+ then
+ -- Float-to-float conversions
- if Is_Floating_Point_Type (Etype (N))
+ if Is_Floating_Point_Type (Target_Type)
and then Is_Floating_Point_Type (Etype (Expression (N)))
then
- if Do_Range_Check (Expression (N))
- and then Is_Floating_Point_Type (Target_Type)
- then
- Generate_Range_Check
- (Expression (N), Target_Type, CE_Range_Check_Failed);
- end if;
+ -- Reset overflow flag, since the range check will include
+ -- dealing with possible overflow, and generate the check.
- -- Discrete-to-discrete conversions
+ Set_Do_Overflow_Check (N, False);
- elsif Is_Discrete_Type (Etype (N)) then
- declare
- Expr : constant Node_Id := Expression (N);
- Ftyp : Entity_Id;
- Ityp : Entity_Id;
+ Generate_Range_Check
+ (Expression (N), Target_Type, CE_Range_Check_Failed);
- begin
- if Do_Range_Check (Expr)
- and then Is_Discrete_Type (Etype (Expr))
- then
- Set_Do_Range_Check (Expr, False);
+ -- Discrete-to-discrete conversions or fixed-point-to-discrete
+ -- conversions when Conversion_OK is set.
- -- Before we do a range check, we have to deal with treating
- -- a fixed-point operand as an integer. The way we do this
- -- is simply to do an unchecked conversion to an appropriate
- -- integer type large enough to hold the result.
-
- -- This code is not active yet, because we are only dealing
- -- with discrete types so far ???
-
- if Nkind (Expr) in N_Has_Treat_Fixed_As_Integer
- and then Treat_Fixed_As_Integer (Expr)
- then
- Ftyp := Base_Type (Etype (Expr));
-
- if Esize (Ftyp) >= Esize (Standard_Integer) then
- Ityp := Standard_Long_Long_Integer;
- else
- Ityp := Standard_Integer;
- end if;
-
- Rewrite (Expr, Unchecked_Convert_To (Ityp, Expr));
- end if;
+ elsif Is_Discrete_Type (Target_Type)
+ and then (Is_Discrete_Type (Etype (Expression (N)))
+ or else (Is_Fixed_Point_Type (Etype (Expression (N)))
+ and then Conversion_OK (N)))
+ then
+ -- If Address is either a source type or target type,
+ -- suppress range check to avoid typing anomalies when
+ -- it is a visible integer type.
- -- Reset overflow flag, since the range check will include
- -- dealing with possible overflow, and generate the check.
- -- If Address is either a source type or target type,
- -- suppress range check to avoid typing anomalies when
- -- it is a visible integer type.
+ if Is_Descendant_Of_Address (Etype (Expression (N)))
+ or else Is_Descendant_Of_Address (Target_Type)
+ then
+ Set_Do_Range_Check (Expression (N), False);
+ else
+ Discrete_Range_Check;
+ end if;
- Set_Do_Overflow_Check (N, False);
+ -- Conversions to floating- or fixed-point when Conversion_OK is set
- if not Is_Descendant_Of_Address (Etype (Expr))
- and then not Is_Descendant_Of_Address (Target_Type)
- then
- Generate_Range_Check
- (Expr, Target_Type, CE_Range_Check_Failed);
- end if;
- end if;
- end;
+ elsif Is_Floating_Point_Type (Target_Type)
+ or else (Is_Fixed_Point_Type (Target_Type)
+ and then Conversion_OK (N))
+ then
+ Real_Range_Check;
end if;
end if;
@@ -12032,10 +12147,13 @@ package body Exp_Ch4 is
begin
-- Avoid infinite recursion on the subsequent expansion of
- -- of the copy of the original type conversion.
+ -- of the copy of the original type conversion. When needed,
+ -- a range check has already been applied to the expression.
Set_Comes_From_Source (New_Expr, False);
- Insert_Action (N, Make_Predicate_Check (Target_Type, New_Expr));
+ Insert_Action (N,
+ Make_Predicate_Check (Target_Type, New_Expr),
+ Suppress => Range_Check);
end;
end if;
end Expand_N_Type_Conversion;
@@ -12391,6 +12509,10 @@ package body Exp_Ch4 is
-- For Opnd a boolean expression, return a Boolean expression equivalent
-- to Opnd /= Shortcut_Value.
+ function Useful (Actions : List_Id) return Boolean;
+ -- Return True if Actions is not empty and contains useful nodes to
+ -- process.
+
--------------------
-- Make_Test_Expr --
--------------------
@@ -12404,6 +12526,31 @@ package body Exp_Ch4 is
end if;
end Make_Test_Expr;
+ ------------
+ -- Useful --
+ ------------
+
+ function Useful (Actions : List_Id) return Boolean is
+ L : Node_Id;
+ begin
+ if Present (Actions) then
+ L := First (Actions);
+
+ -- For now "useful" means not N_Variable_Reference_Marker.
+ -- Consider stripping other nodes in the future.
+
+ while Present (L) loop
+ if Nkind (L) /= N_Variable_Reference_Marker then
+ return True;
+ end if;
+
+ Next (L);
+ end loop;
+ end if;
+
+ return False;
+ end Useful;
+
-- Local variables
Op_Var : Entity_Id;
@@ -12463,7 +12610,7 @@ package body Exp_Ch4 is
-- must only be executed if the right operand of the short circuit is
-- executed and not otherwise.
- if Present (Actions (N)) then
+ if Useful (Actions (N)) then
Actlist := Actions (N);
-- The old approach is to expand:
@@ -12567,7 +12714,7 @@ package body Exp_Ch4 is
Adjust_Result_Type (N, Typ);
end Expand_Short_Circuit_Operator;
- -------------------------------------
+ ------------------------------------
-- Fixup_Universal_Fixed_Operation --
-------------------------------------
@@ -12587,13 +12734,13 @@ package body Exp_Ch4 is
if Nkind (Parent (Conv)) = N_Attribute_Reference
and then Attribute_Name (Parent (Conv)) = Name_Round
then
- Set_Etype (N, Etype (Parent (Conv)));
+ Set_Etype (N, Base_Type (Etype (Parent (Conv))));
Set_Rounded_Result (N);
-- Normal case where type comes from conversion above us
else
- Set_Etype (N, Etype (Conv));
+ Set_Etype (N, Base_Type (Etype (Conv)));
end if;
end Fixup_Universal_Fixed_Operation;
@@ -14122,7 +14269,8 @@ package body Exp_Ch4 is
-- Obj1 in DT'Class; -- Compile time error
-- Obj1 in Iface'Class; -- Compile time error
- if not Is_Class_Wide_Type (Left_Type)
+ if not Is_Interface (Left_Type)
+ and then not Is_Class_Wide_Type (Left_Type)
and then (Is_Ancestor (Etype (Right_Type), Left_Type,
Use_Full_View => True)
or else (Is_Interface (Etype (Right_Type))
diff --git a/gcc/ada/exp_ch4.ads b/gcc/ada/exp_ch4.ads
index 5ff9fc4..44872fd 100644
--- a/gcc/ada/exp_ch4.ads
+++ b/gcc/ada/exp_ch4.ads
@@ -74,13 +74,26 @@ package Exp_Ch4 is
procedure Expand_N_Unchecked_Expression (N : Node_Id);
procedure Expand_N_Unchecked_Type_Conversion (N : Node_Id);
+ function Build_Eq_Call
+ (Typ : Entity_Id;
+ Loc : Source_Ptr;
+ Lhs : Node_Id;
+ Rhs : Node_Id) return Node_Id;
+ -- AI05-0123: Locate primitive equality for type if it exists, and build
+ -- the corresponding call. If operation is abstract, replace call with
+ -- an explicit raise. Return Empty if there is no primitive.
+ -- Used in the construction of record-equality routines for records here
+ -- and for variant records in exp_ch3.adb. These two paths are distinct
+ -- for historical but also technical reasons: for variant records the
+ -- constructed function includes a case statement with nested returns,
+ -- while for records without variants only a simple expression is needed.
+
function Expand_Record_Equality
(Nod : Node_Id;
Typ : Entity_Id;
Lhs : Node_Id;
Rhs : Node_Id;
- Bodies : List_Id)
- return Node_Id;
+ Bodies : List_Id) return Node_Id;
-- Expand a record equality into an expression that compares the fields
-- individually to yield the required Boolean result. Loc is the
-- location for the generated nodes. Typ is the type of the record, and
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index b1b0f55..682c855 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -2021,15 +2021,21 @@ package body Exp_Ch5 is
if not Suppress_Assignment_Checks (N) then
- -- First deal with generation of range check if required
+ -- First deal with generation of range check if required,
+ -- and then predicate checks if the type carries a predicate.
+ -- If the Rhs is an expression these tests may have been applied
+ -- already. This is the case if the RHS is a type conversion.
+ -- Other such redundant checks could be removed ???
+
+ if Nkind (Rhs) /= N_Type_Conversion
+ or else Entity (Subtype_Mark (Rhs)) /= Typ
+ then
+ if Do_Range_Check (Rhs) then
+ Generate_Range_Check (Rhs, Typ, CE_Range_Check_Failed);
+ end if;
- if Do_Range_Check (Rhs) then
- Generate_Range_Check (Rhs, Typ, CE_Range_Check_Failed);
+ Apply_Predicate_Check (Rhs, Typ);
end if;
-
- -- Then generate predicate check if required
-
- Apply_Predicate_Check (Rhs, Typ);
end if;
-- Check for a special case where a high level transformation is
@@ -2850,13 +2856,14 @@ package body Exp_Ch5 is
-----------------------------
procedure Expand_N_Case_Statement (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- Expr : constant Node_Id := Expression (N);
- Alt : Node_Id;
- Len : Nat;
- Cond : Node_Id;
- Choice : Node_Id;
- Chlist : List_Id;
+ Loc : constant Source_Ptr := Sloc (N);
+ Expr : constant Node_Id := Expression (N);
+ From_Cond_Expr : constant Boolean := From_Conditional_Expression (N);
+ Alt : Node_Id;
+ Len : Nat;
+ Cond : Node_Id;
+ Choice : Node_Id;
+ Chlist : List_Id;
begin
-- Check for the situation where we know at compile time which branch
@@ -3067,7 +3074,15 @@ package body Exp_Ch5 is
Condition => Cond,
Then_Statements => Then_Stms,
Else_Statements => Else_Stms));
+
+ -- The rewritten if statement needs to inherit whether the
+ -- case statement was expanded from a conditional expression,
+ -- for proper handling of nested controlled objects.
+
+ Set_From_Conditional_Expression (N, From_Cond_Expr);
+
Analyze (N);
+
return;
end if;
end if;
@@ -3304,7 +3319,7 @@ package body Exp_Ch5 is
Declarations => New_List (Elmt_Decl),
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
- Statements => Stats))));
+ Statements => Stats))));
else
Elmt_Ref :=
@@ -3330,7 +3345,7 @@ package body Exp_Ch5 is
Declarations => New_List (Elmt_Decl),
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (New_Loop)));
+ Statements => New_List (New_Loop)));
end if;
-- The element is only modified in expanded code, so it appears as
@@ -3919,7 +3934,7 @@ package body Exp_Ch5 is
-- -- Default_Iterator aspect of Vector. This increments Lock,
-- -- disallowing tampering with cursors. Unfortunately, it does not
-- -- increment Busy. The result of Iterate is Limited_Controlled;
- -- -- finalization will decrement Lock. This is a build-in-place
+ -- -- finalization will decrement Lock. This is a build-in-place
-- -- dispatching call to Iterate.
-- Cur : Cursor := First (Iter); -- or Last
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index bd7ae2c..f38dd67 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -2319,6 +2319,13 @@ package body Exp_Ch6 is
-- Adds invariant checks for every intermediate type between the range
-- of a view converted argument to its ancestor (from parent to child).
+ function Can_Fold_Predicate_Call (P : Entity_Id) return Boolean;
+ -- Try to constant-fold a predicate check, which often enough is a
+ -- simple arithmetic expression that can be computed statically if
+ -- its argument is static. This cleans up the output of CCG, even
+ -- though useless predicate checks will be generally removed by
+ -- back-end optimizations.
+
function Inherited_From_Formal (S : Entity_Id) return Entity_Id;
-- Within an instance, a type derived from an untagged formal derived
-- type inherits from the original parent, not from the actual. The
@@ -2331,6 +2338,10 @@ package body Exp_Ch6 is
function In_Unfrozen_Instance (E : Entity_Id) return Boolean;
-- Return true if E comes from an instance that is not yet frozen
+ function Is_Class_Wide_Interface_Type (E : Entity_Id) return Boolean;
+ -- Return True when E is a class-wide interface type or an access to
+ -- a class-wide interface type.
+
function Is_Direct_Deep_Call (Subp : Entity_Id) return Boolean;
-- Determine if Subp denotes a non-dispatching call to a Deep routine
@@ -2463,6 +2474,113 @@ package body Exp_Ch6 is
end if;
end Add_View_Conversion_Invariants;
+ -----------------------------
+ -- Can_Fold_Predicate_Call --
+ -----------------------------
+
+ function Can_Fold_Predicate_Call (P : Entity_Id) return Boolean is
+ Actual : Node_Id;
+
+ function May_Fold (N : Node_Id) return Traverse_Result;
+ -- The predicate expression is foldable if it only contains operators
+ -- and literals. During this check, we also replace occurrences of
+ -- the formal of the constructed predicate function with the static
+ -- value of the actual. This is done on a copy of the analyzed
+ -- expression for the predicate.
+
+ --------------
+ -- May_Fold --
+ --------------
+
+ function May_Fold (N : Node_Id) return Traverse_Result is
+ begin
+ case Nkind (N) is
+ when N_Binary_Op
+ | N_Unary_Op
+ =>
+ return OK;
+
+ when N_Expanded_Name
+ | N_Identifier
+ =>
+ if Ekind (Entity (N)) = E_In_Parameter
+ and then Entity (N) = First_Entity (P)
+ then
+ Rewrite (N, New_Copy (Actual));
+ Set_Is_Static_Expression (N);
+ return OK;
+
+ elsif Ekind (Entity (N)) = E_Enumeration_Literal then
+ return OK;
+
+ else
+ return Abandon;
+ end if;
+
+ when N_Case_Expression
+ | N_If_Expression
+ =>
+ return OK;
+
+ when N_Integer_Literal =>
+ return OK;
+
+ when others =>
+ return Abandon;
+ end case;
+ end May_Fold;
+
+ function Try_Fold is new Traverse_Func (May_Fold);
+
+ -- Other lLocal variables
+
+ Subt : constant Entity_Id := Etype (First_Entity (P));
+ Aspect : Node_Id;
+ Pred : Node_Id;
+
+ -- Start of processing for Can_Fold_Predicate_Call
+
+ begin
+ -- Folding is only interesting if the actual is static and its type
+ -- has a Dynamic_Predicate aspect. For CodePeer we preserve the
+ -- function call.
+
+ Actual := First (Parameter_Associations (Call_Node));
+ Aspect := Find_Aspect (Subt, Aspect_Dynamic_Predicate);
+
+ -- If actual is a declared constant, retrieve its value
+
+ if Is_Entity_Name (Actual)
+ and then Ekind (Entity (Actual)) = E_Constant
+ then
+ Actual := Constant_Value (Entity (Actual));
+ end if;
+
+ if No (Actual)
+ or else Nkind (Actual) /= N_Integer_Literal
+ or else not Has_Dynamic_Predicate_Aspect (Subt)
+ or else No (Aspect)
+ or else CodePeer_Mode
+ then
+ return False;
+ end if;
+
+ -- Retrieve the analyzed expression for the predicate
+
+ Pred := New_Copy_Tree (Expression (Aspect));
+
+ if Try_Fold (Pred) = OK then
+ Rewrite (Call_Node, Pred);
+ Analyze_And_Resolve (Call_Node, Standard_Boolean);
+ return True;
+
+ -- Otherwise continue the expansion of the function call
+
+ else
+ return False;
+ end if;
+ end Can_Fold_Predicate_Call;
+
---------------------------
-- Inherited_From_Formal --
---------------------------
@@ -2585,6 +2703,32 @@ package body Exp_Ch6 is
return False;
end In_Unfrozen_Instance;
+ ----------------------------------
+ -- Is_Class_Wide_Interface_Type --
+ ----------------------------------
+
+ function Is_Class_Wide_Interface_Type (E : Entity_Id) return Boolean is
+ DDT : Entity_Id;
+ Typ : Entity_Id := E;
+
+ begin
+ if Has_Non_Limited_View (Typ) then
+ Typ := Non_Limited_View (Typ);
+ end if;
+
+ if Ekind (Typ) = E_Anonymous_Access_Type then
+ DDT := Directly_Designated_Type (Typ);
+
+ if Has_Non_Limited_View (DDT) then
+ DDT := Non_Limited_View (DDT);
+ end if;
+
+ return Is_Class_Wide_Type (DDT) and then Is_Interface (DDT);
+ else
+ return Is_Class_Wide_Type (Typ) and then Is_Interface (Typ);
+ end if;
+ end Is_Class_Wide_Interface_Type;
+
-------------------------
-- Is_Direct_Deep_Call --
-------------------------
@@ -2785,6 +2929,17 @@ package body Exp_Ch6 is
end;
end if;
+ -- if this is a call to a predicate function, try to constant
+ -- fold it.
+
+ if Nkind (Call_Node) = N_Function_Call
+ and then Is_Entity_Name (Name (Call_Node))
+ and then Is_Predicate_Function (Subp)
+ and then Can_Fold_Predicate_Call (Subp)
+ then
+ return;
+ end if;
+
if Modify_Tree_For_C
and then Nkind (Call_Node) = N_Function_Call
and then Is_Entity_Name (Name (Call_Node))
@@ -2919,15 +3074,7 @@ package body Exp_Ch6 is
CW_Interface_Formals_Present :=
CW_Interface_Formals_Present
- or else
- (Is_Class_Wide_Type (Etype (Formal))
- and then Is_Interface (Etype (Etype (Formal))))
- or else
- (Ekind (Etype (Formal)) = E_Anonymous_Access_Type
- and then Is_Class_Wide_Type (Directly_Designated_Type
- (Etype (Etype (Formal))))
- and then Is_Interface (Directly_Designated_Type
- (Etype (Etype (Formal)))));
+ or else Is_Class_Wide_Interface_Type (Etype (Formal));
-- Create possible extra actual for constrained case. Usually, the
-- extra actual is of the form actual'constrained, but since this
@@ -3203,7 +3350,7 @@ package body Exp_Ch6 is
-- ???
-- A further case that requires special handling
- -- is the common idiom E.all'access. If E is a
+ -- is the common idiom E.all'access. If E is a
-- formal of the enclosing subprogram, the
-- accessibility of the expression is that of E.
@@ -3271,7 +3418,10 @@ package body Exp_Ch6 is
-- For allocators we pass the level of the execution of the
-- called subprogram, which is one greater than the current
- -- scope level.
+ -- scope level. However, according to RM 3.10.2(14/3) this
+ -- is wrong since for an anonymous allocator defining the
+ -- value of an access parameter, the accessibility level is
+ -- that of the innermost master of the call???
when N_Allocator =>
Add_Extra_Actual
@@ -7765,22 +7915,20 @@ package body Exp_Ch6 is
-- For now we test whether E denotes a function or access-to-function
-- type whose result subtype is inherently limited. Later this test
- -- may be revised to allow composite nonlimited types. Functions with
- -- a foreign convention or whose result type has a foreign convention
- -- never qualify.
+ -- may be revised to allow composite nonlimited types.
if Ekind_In (E, E_Function, E_Generic_Function)
or else (Ekind (E) = E_Subprogram_Type
and then Etype (E) /= Standard_Void_Type)
then
- -- Note: If the function has a foreign convention, it cannot build
- -- its result in place, so you're on your own. On the other hand,
- -- if only the return type has a foreign convention, its layout is
- -- intended to be compatible with the other language, but the build-
- -- in place machinery can ensure that the object is not copied.
+ -- If the function is imported from a foreign language, we don't do
+ -- build-in-place. Note that Import (Ada) functions can do
+ -- build-in-place. Note that it is OK for a build-in-place function
+ -- to return a type with a foreign convention; the build-in-place
+ -- machinery will ensure there is no copying.
return Is_Build_In_Place_Result_Type (Etype (E))
- and then not Has_Foreign_Convention (E)
+ and then not (Has_Foreign_Convention (E) and then Is_Imported (E))
and then not Debug_Flag_Dot_L;
else
return False;
@@ -8524,7 +8672,7 @@ package body Exp_Ch6 is
-- The presence of an address clause complicates the build-in-place
-- expansion because the indicated address must be processed before
-- the indirect call is generated (including the definition of a
- -- local pointer to the object). The address clause may come from
+ -- local pointer to the object). The address clause may come from
-- an aspect specification or from an explicit attribute
-- specification appearing after the object declaration. These two
-- cases require different processing.
@@ -9235,8 +9383,9 @@ package body Exp_Ch6 is
return False;
end Has_Unconstrained_Access_Discriminant_Component;
- Feature_Disabled : constant Boolean := True;
- -- Temporary
+ Disable_Coextension_Cases : constant Boolean := True;
+ -- Flag used to temporarily disable a "True" result for types with
+ -- access discriminants and related coextension cases.
-- Start of processing for Needs_Result_Accessibility_Level
@@ -9246,9 +9395,6 @@ package body Exp_Ch6 is
if not Present (Func_Typ) then
return False;
- elsif Feature_Disabled then
- return False;
-
-- False if not a function, also handle enum-lit renames case
elsif Func_Typ = Standard_Void_Type
@@ -9273,23 +9419,37 @@ package body Exp_Ch6 is
elsif Ada_Version < Ada_2012 then
return False;
- elsif Ekind (Func_Typ) = E_Anonymous_Access_Type
- or else Is_Tagged_Type (Func_Typ)
- then
- -- In the case of, say, a null tagged record result type, the need
- -- for this extra parameter might not be obvious. This function
- -- returns True for all tagged types for compatibility reasons.
- -- A function with, say, a tagged null controlling result type might
- -- be overridden by a primitive of an extension having an access
- -- discriminant and the overrider and overridden must have compatible
- -- calling conventions (including implicitly declared parameters).
- -- Similarly, values of one access-to-subprogram type might designate
- -- both a primitive subprogram of a given type and a function
- -- which is, for example, not a primitive subprogram of any type.
- -- Again, this requires calling convention compatibility.
- -- It might be possible to solve these issues by introducing
- -- wrappers, but that is not the approach that was chosen.
+ -- Handle the situation where a result is an anonymous access type
+ -- RM 3.10.2 (10.3/3).
+
+ elsif Ekind (Func_Typ) = E_Anonymous_Access_Type then
+ return True;
+
+ -- The following cases are related to coextensions and do not fully
+ -- cover everything mentioned in RM 3.10.2 (12) ???
+
+ -- Temporarily disabled ???
+
+ elsif Disable_Coextension_Cases then
+ return False;
+
+ -- In the case of, say, a null tagged record result type, the need for
+ -- this extra parameter might not be obvious so this function returns
+ -- True for all tagged types for compatibility reasons.
+
+ -- A function with, say, a tagged null controlling result type might
+ -- be overridden by a primitive of an extension having an access
+ -- discriminant and the overrider and overridden must have compatible
+ -- calling conventions (including implicitly declared parameters).
+
+ -- Similarly, values of one access-to-subprogram type might designate
+ -- both a primitive subprogram of a given type and a function which is,
+ -- for example, not a primitive subprogram of any type. Again, this
+ -- requires calling convention compatibility. It might be possible to
+ -- solve these issues by introducing wrappers, but that is not the
+ -- approach that was chosen.
+ elsif Is_Tagged_Type (Func_Typ) then
return True;
elsif Has_Unconstrained_Access_Discriminants (Func_Typ) then
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 4209785..b00fc92 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -393,7 +393,7 @@ package body Exp_Ch7 is
-- name. Before generating the proper call to one of these operations we
-- check whether Typ is known to be controlled at the point of definition.
-- If it is not then we must retrieve the hidden operation of the parent
- -- and use it instead. This is one case that might be solved more cleanly
+ -- and use it instead. This is one case that might be solved more cleanly
-- once Overriding pragmas or declarations are in place.
function Contains_Subprogram (Blk : Entity_Id) return Boolean;
@@ -2035,6 +2035,13 @@ package body Exp_Ch7 is
Analyze (Fin_Body, Suppress => All_Checks);
end if;
+
+ -- Never consider that the finalizer procedure is enabled Ghost, even
+ -- when the corresponding unit is Ghost, as this would lead to an
+ -- an external name with a ___ghost_ prefix that the binder cannot
+ -- generate, as it has no knowledge of the Ghost status of units.
+
+ Set_Is_Checked_Ghost_Entity (Fin_Id, False);
end Create_Finalizer;
--------------------------
@@ -3873,7 +3880,7 @@ package body Exp_Ch7 is
Attribute_Name => Name_Range,
Expressions => New_List (
Make_Integer_Literal (Loc, Dim))))),
- Statements => Free_One_Dimension (Dim + 1)));
+ Statements => Free_One_Dimension (Dim + 1)));
end if;
end Free_One_Dimension;
@@ -3893,11 +3900,12 @@ package body Exp_Ch7 is
Typ : Entity_Id) return List_Id
is
Loc : constant Source_Ptr := Sloc (N);
- Tsk : Node_Id;
- Comp : Entity_Id;
Stmts : constant List_Id := New_List;
U_Typ : constant Entity_Id := Underlying_Type (Typ);
+ Comp : Entity_Id;
+ Tsk : Node_Id;
+
begin
if Has_Discriminants (U_Typ)
and then Nkind (Parent (U_Typ)) = N_Full_Type_Declaration
@@ -3918,7 +3926,7 @@ package body Exp_Ch7 is
return New_List (Make_Null_Statement (Loc));
end if;
- Comp := First_Component (Typ);
+ Comp := First_Component (U_Typ);
while Present (Comp) loop
if Has_Task (Etype (Comp))
or else Has_Simple_Protected_Object (Etype (Comp))
@@ -3937,8 +3945,8 @@ package body Exp_Ch7 is
elsif Is_Record_Type (Etype (Comp)) then
- -- Recurse, by generating the prefix of the argument to
- -- the eventual cleanup call.
+ -- Recurse, by generating the prefix of the argument to the
+ -- eventual cleanup call.
Append_List_To (Stmts, Cleanup_Record (N, Tsk, Etype (Comp)));
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 0f83d57..99bd8d2 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -477,12 +477,11 @@ package body Exp_Ch9 is
-- <actualN> := P.<formalN>;
procedure Reset_Scopes_To (Bod : Node_Id; E : Entity_Id);
- -- Reset the scope of declarations and blocks at the top level of Bod
- -- to be E. Bod is either a block or a subprogram body. Used after
- -- expanding various kinds of entry bodies into their corresponding
- -- constructs. This is needed during unnesting to determine whether a
- -- body generated for an entry or an accept alternative includes uplevel
- -- references.
+ -- Reset the scope of declarations and blocks at the top level of Bod to
+ -- be E. Bod is either a block or a subprogram body. Used after expanding
+ -- various kinds of entry bodies into their corresponding constructs. This
+ -- is needed during unnesting to determine whether a body generated for an
+ -- entry or an accept alternative includes uplevel references.
function Trivial_Accept_OK return Boolean;
-- If there is no DO-END block for an accept, or if the DO-END block has
@@ -869,7 +868,7 @@ package body Exp_Ch9 is
Make_Implicit_Exception_Handler (Loc,
Exception_Choices => New_List (Ohandle),
- Statements => New_List (
+ Statements => New_List (
Make_Procedure_Call_Statement (Sloc (Stats),
Name => New_Occurrence_Of (
RTE (RE_Exceptional_Complete_Rendezvous), Sloc (Stats)),
@@ -3494,6 +3493,8 @@ package body Exp_Ch9 is
procedure Move_Pragmas (From : Node_Id; To : Node_Id);
-- Find all suitable source pragmas at the top of subprogram body From's
-- declarations and insert them after arbitrary node To.
+ --
+ -- Very similar to Move_Pragmas in sem_ch6 ???
---------------------
-- Analyze_Pragmas --
@@ -3545,7 +3546,14 @@ package body Exp_Ch9 is
Next_Decl := Next (Decl);
- if Nkind (Decl) = N_Pragma then
+ -- We add an exception here for Unreferenced pragmas since the
+ -- internally generated spec gets analyzed within
+ -- Build_Private_Protected_Declaration and will lead to spurious
+ -- warnings due to the way references are checked.
+
+ if Nkind (Decl) = N_Pragma
+ and then Pragma_Name_Unmapped (Decl) /= Name_Unreferenced
+ then
Remove (Decl);
Insert_After (Insert_Nod, Decl);
Insert_Nod := Decl;
@@ -3792,7 +3800,7 @@ package body Exp_Ch9 is
Make_Implicit_Exception_Handler (EH_Loc,
Exception_Choices => New_List (Ohandle),
- Statements => New_List (
+ Statements => New_List (
Make_Procedure_Call_Statement (EH_Loc,
Name => Complete,
Parameter_Associations => New_List (
@@ -3887,6 +3895,7 @@ package body Exp_Ch9 is
if Unprotected then
Set_Protected_Formal (Formal, Defining_Identifier (New_Param));
+ Set_Ekind (Defining_Identifier (New_Param), Ekind (Formal));
end if;
Append (New_Param, New_Plist);
@@ -8919,6 +8928,8 @@ package body Exp_Ch9 is
Current_Node : Node_Id := N;
E_Count : Int;
Entries_Aggr : Node_Id;
+ Rec_Decl : Node_Id;
+ Rec_Id : Entity_Id;
procedure Check_Inlining (Subp : Entity_Id);
-- If the original operation has a pragma Inline, propagate the flag
@@ -8940,6 +8951,21 @@ package body Exp_Ch9 is
-- For a protected operation that is an interrupt handler, add the
-- freeze action that will register it as such.
+ procedure Replace_Access_Definition (Comp : Node_Id);
+ -- If a private component of the type is an access to itself, this
+ -- is not a reference to the current instance, but an access type out
+ -- of which one might construct a list. If such a component exists, we
+ -- create an incomplete type for the equivalent record type, and
+ -- a named access type for it, that replaces the access definition
+ -- of the original component. This is similar to what is done for
+ -- records in Check_Anonymous_Access_Components, but simpler, because
+ -- the corresponding record type has no previous declaration.
+ -- This needs to be done only once, even if there are several such
+ -- access components. The following entity stores the constructed
+ -- access type.
+
+ Acc_T : Entity_Id := Empty;
+
--------------------
-- Check_Inlining --
--------------------
@@ -9087,6 +9113,41 @@ package body Exp_Ch9 is
Append_Freeze_Action (Prot_Proc, RTS_Call);
end Register_Handler;
+ -------------------------------
+ -- Replace_Access_Definition --
+ -------------------------------
+
+ procedure Replace_Access_Definition (Comp : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (Comp);
+ Inc_T : Node_Id;
+ Inc_D : Node_Id;
+ Acc_Def : Node_Id;
+ Acc_D : Node_Id;
+
+ begin
+ if No (Acc_T) then
+ Inc_T := Make_Defining_Identifier (Loc, Chars (Rec_Id));
+ Inc_D := Make_Incomplete_Type_Declaration (Loc, Inc_T);
+ Acc_T := Make_Temporary (Loc, 'S');
+ Acc_Def :=
+ Make_Access_To_Object_Definition (Loc,
+ Subtype_Indication => New_Occurrence_Of (Inc_T, Loc));
+ Acc_D :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => Acc_T,
+ Type_Definition => Acc_Def);
+
+ Insert_Before (Rec_Decl, Inc_D);
+ Analyze (Inc_D);
+
+ Insert_Before (Rec_Decl, Acc_D);
+ Analyze (Acc_D);
+ end if;
+
+ Set_Access_Definition (Comp, Empty);
+ Set_Subtype_Indication (Comp, New_Occurrence_Of (Acc_T, Loc));
+ end Replace_Access_Definition;
+
-- Local variables
Body_Arr : Node_Id;
@@ -9098,7 +9159,6 @@ package body Exp_Ch9 is
Obj_Def : Node_Id;
Object_Comp : Node_Id;
Priv : Node_Id;
- Rec_Decl : Node_Id;
Sub : Node_Id;
-- Start of processing for Expand_N_Protected_Type_Declaration
@@ -9108,6 +9168,7 @@ package body Exp_Ch9 is
return;
else
Rec_Decl := Build_Corresponding_Record (N, Prot_Typ, Loc);
+ Rec_Id := Defining_Identifier (Rec_Decl);
end if;
Cdecls := Component_Items (Component_List (Type_Definition (Rec_Decl)));
@@ -9253,6 +9314,15 @@ package body Exp_Ch9 is
Access_Definition =>
New_Copy_Tree
(Access_Definition (Old_Comp), Discr_Map));
+
+ -- A self-reference in the private part becomes a
+ -- self-reference to the corresponding record.
+
+ if Entity (Subtype_Mark (Access_Definition (New_Comp)))
+ = Prot_Typ
+ then
+ Replace_Access_Definition (New_Comp);
+ end if;
end if;
New_Priv :=
@@ -10639,7 +10709,7 @@ package body Exp_Ch9 is
Statements => New_List (
Make_Implicit_If_Statement (N,
- Condition => Cond,
+ Condition => Cond,
Then_Statements => New_List (
Make_Select_Call (
New_Occurrence_Of (RTE (RE_Simple_Mode), Loc)),
@@ -12658,14 +12728,6 @@ package body Exp_Ch9 is
Object_Definition => New_Occurrence_Of (Standard_Integer, Loc),
Expression => D_Disc));
- -- Do the assignment at this stage only because the evaluation of the
- -- expression must not occur earlier (see ACVC C97302A).
-
- Append_To (Stmts,
- Make_Assignment_Statement (Loc,
- Name => New_Occurrence_Of (D, Loc),
- Expression => D_Conv));
-
-- Parameter block processing
-- Manually create the parameter block for dispatching calls. In the
@@ -12674,6 +12736,14 @@ package body Exp_Ch9 is
if Is_Disp_Select then
+ -- Compute the delay at this stage because the evaluation of its
+ -- expression must not occur earlier (see ACVC C97302A).
+
+ Append_To (Stmts,
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (D, Loc),
+ Expression => D_Conv));
+
-- Tagged kind processing, generate:
-- K : Ada.Tags.Tagged_Kind :=
-- Ada.Tags.Get_Tagged_Kind (Ada.Tags.Tag <object>));
@@ -12855,8 +12925,8 @@ package body Exp_Ch9 is
Next (Stmt);
end loop;
- -- Do the assignment at this stage only because the evaluation
- -- of the expression must not occur earlier (see ACVC C97302A).
+ -- Compute the delay at this stage because the evaluation of
+ -- its expression must not occur earlier (see ACVC C97302A).
Insert_Before (Stmt,
Make_Assignment_Statement (Loc,
@@ -12942,10 +13012,9 @@ package body Exp_Ch9 is
Analyze (N);
- -- Some items in Decls used to be in the N_Block in E_Call that
- -- is constructed in Expand_Entry_Call, and are now in the new
- -- Block into which N has been rewritten. Adjust their scopes
- -- to reflect that.
+ -- Some items in Decls used to be in the N_Block in E_Call that is
+ -- constructed in Expand_Entry_Call, and are now in the new Block
+ -- into which N has been rewritten. Adjust their scopes to reflect that.
if Nkind (E_Call) = N_Block_Statement then
Obj := First_Entity (Entity (Identifier (E_Call)));
@@ -14882,7 +14951,8 @@ package body Exp_Ch9 is
-- Ditto for a package declaration or a full type declaration, etc.
- elsif Nkind (N) = N_Package_Declaration
+ elsif (Nkind (N) = N_Package_Declaration
+ and then N /= Specification (N))
or else Nkind (N) in N_Declaration
or else Nkind (N) in N_Renaming_Declaration
then
diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb
index 388d247..f0df5e2 100644
--- a/gcc/ada/exp_dbug.adb
+++ b/gcc/ada/exp_dbug.adb
@@ -914,6 +914,14 @@ package body Exp_Dbug is
-- names produced for Ghost entities, while "__ghost_" can appear in
-- names of entities inside a child/local package called "Ghost".
+ -- The compiler-generated finalizer for an enabled Ghost unit is treated
+ -- specially, as its name must be known to the binder, which has no
+ -- knowledge of Ghost status. In that case, the finalizer is not marked
+ -- as Ghost so that no prefix is added. Note that the special ___ghost_
+ -- prefix is retained when the Ghost unit is ignored, which still allows
+ -- inspecting the final executable for the presence of an ignored Ghost
+ -- finalizer procedure.
+
if Is_Ghost_Entity (E)
and then not Is_Compilation_Unit (E)
and then (Name_Len < 9
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index 1b21234..4fae37c 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -1682,18 +1682,34 @@ package body Exp_Disp is
while Present (Formal) loop
Formal_Typ := Etype (Formal);
+ if Has_Non_Limited_View (Formal_Typ) then
+ Formal_Typ := Non_Limited_View (Formal_Typ);
+ end if;
+
if Ekind (Formal_Typ) = E_Record_Type_With_Private then
Formal_Typ := Full_View (Formal_Typ);
end if;
if Is_Access_Type (Formal_Typ) then
Formal_DDT := Directly_Designated_Type (Formal_Typ);
+
+ if Has_Non_Limited_View (Formal_DDT) then
+ Formal_DDT := Non_Limited_View (Formal_DDT);
+ end if;
end if;
Actual_Typ := Etype (Actual);
+ if Has_Non_Limited_View (Actual_Typ) then
+ Actual_Typ := Non_Limited_View (Actual_Typ);
+ end if;
+
if Is_Access_Type (Actual_Typ) then
Actual_DDT := Directly_Designated_Type (Actual_Typ);
+
+ if Has_Non_Limited_View (Actual_DDT) then
+ Actual_DDT := Non_Limited_View (Actual_DDT);
+ end if;
end if;
if Is_Interface (Formal_Typ)
@@ -7637,7 +7653,7 @@ package body Exp_Disp is
Unchecked_Convert_To (RTE (RE_Prim_Ptr),
Make_Attribute_Reference (Loc,
Prefix =>
- New_Occurrence_Of (Alias (Prim), Loc),
+ New_Occurrence_Of (Ultimate_Alias (Prim), Loc),
Attribute_Name => Name_Unrestricted_Access))));
end if;
diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index 6a8d626..a47de2f 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -69,18 +69,23 @@ package body Exp_Imgv is
------------------------------------
procedure Build_Enumeration_Image_Tables (E : Entity_Id; N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (E);
- Str : String_Id;
+ Loc : constant Source_Ptr := Sloc (E);
+
+ Eind : Entity_Id;
+ Estr : Entity_Id;
Ind : List_Id;
+ Ityp : Node_Id;
+ Len : Nat;
Lit : Entity_Id;
Nlit : Nat;
- Len : Nat;
- Estr : Entity_Id;
- Eind : Entity_Id;
- Ityp : Node_Id;
+ Str : String_Id;
+
+ Saved_SSO : constant Character := Opt.Default_SSO;
+ -- Used to save the current scalar storage order during the generation
+ -- of the literal lookup table.
begin
- -- Nothing to do for other than a root enumeration type
+ -- Nothing to do for types other than a root enumeration type
if E /= Root_Type (E) then
return;
@@ -138,6 +143,15 @@ package body Exp_Imgv is
Set_Lit_Strings (E, Estr);
Set_Lit_Indexes (E, Eind);
+ -- Temporarily set the current scalar storage order to the default
+ -- during the generation of the literals table, since both the Image and
+ -- Value attributes rely on runtime routines for interpreting table
+ -- values.
+
+ Opt.Default_SSO := ' ';
+
+ -- Generate literal table
+
Insert_Actions (N,
New_List (
Make_Object_Declaration (Loc,
@@ -168,6 +182,10 @@ package body Exp_Imgv is
Make_Aggregate (Loc,
Expressions => Ind))),
Suppress => All_Checks);
+
+ -- Reset the scalar storage order to the saved value
+
+ Opt.Default_SSO := Saved_SSO;
end Build_Enumeration_Image_Tables;
----------------------------
@@ -433,13 +451,13 @@ package body Exp_Imgv is
-- Local variables
+ Enum_Case : Boolean;
Imid : RE_Id;
+ Proc_Ent : Entity_Id;
Ptyp : Entity_Id;
Rtyp : Entity_Id;
Tent : Entity_Id := Empty;
Ttyp : Entity_Id;
- Proc_Ent : Entity_Id;
- Enum_Case : Boolean;
Arg_List : List_Id;
-- List of arguments for run-time procedure call
@@ -450,6 +468,8 @@ package body Exp_Imgv is
Snn : constant Entity_Id := Make_Temporary (Loc, 'S');
Pnn : constant Entity_Id := Make_Temporary (Loc, 'P');
+ -- Start of processing for Expand_Image_Attribute
+
begin
if Is_Object_Image (Pref) then
Rewrite_Object_Image (N, Pref, Name_Image, Standard_String);
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index a7d2a0d..2f45a72 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -1022,7 +1022,9 @@ package body Exp_Pakd is
Ass_OK : constant Boolean := Assignment_OK (Lhs);
-- Used to preserve assignment OK status when assignment is rewritten
- Rhs : Node_Id := Expression (N);
+ Expr : Node_Id;
+
+ Rhs : Node_Id := Expression (N);
-- Initially Rhs is the right hand side value, it will be replaced
-- later by an appropriate unchecked conversion for the assignment.
@@ -1125,7 +1127,7 @@ package body Exp_Pakd is
-- If we are building the initialization procedure for a packed array,
-- and Initialize_Scalars is enabled, each component assignment is an
- -- out-of-range value by design. Compile this value without checks,
+ -- out-of-range value by design. Compile this value without checks,
-- because a call to the array init_proc must not raise an exception.
-- Condition is not consistent with description above, Within_Init_Proc
@@ -1140,6 +1142,36 @@ package body Exp_Pakd is
Analyze_And_Resolve (Rhs, Ctyp);
end if;
+ -- If any of the indices has a nonstandard representation, introduce
+ -- the proper Rep_To_Pos conversion, which in turn will generate index
+ -- checks when needed. We do this on a copy of the index expression,
+ -- rather that rewriting the LHS altogether.
+
+ Expr := First (Expressions (Lhs));
+ while Present (Expr) loop
+ declare
+ Expr_Typ : constant Entity_Id := Etype (Expr);
+ Loc : constant Source_Ptr := Sloc (Expr);
+
+ Expr_Copy : Node_Id;
+
+ begin
+ if Is_Enumeration_Type (Expr_Typ)
+ and then Has_Non_Standard_Rep (Expr_Typ)
+ then
+ Expr_Copy :=
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Occurrence_Of (Expr_Typ, Loc),
+ Attribute_Name => Name_Pos,
+ Expressions => New_List (Relocate_Node (Expr)));
+ Set_Parent (Expr_Copy, N);
+ Analyze_And_Resolve (Expr_Copy, Standard_Natural);
+ end if;
+ end;
+
+ Next (Expr);
+ end loop;
+
-- Case of component size 1,2,4 or any component size for the modular
-- case. These are the cases for which we can inline the code.
diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
index b008c79..63f2dad 100644
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -26,6 +26,7 @@
with Atree; use Atree;
with Checks; use Checks;
with Einfo; use Einfo;
+with Exp_Attr;
with Exp_Ch4;
with Exp_Ch5; use Exp_Ch5;
with Exp_Dbug; use Exp_Dbug;
@@ -196,6 +197,12 @@ package body Exp_SPARK is
Parameter_Associations => New_List (Expr)));
Analyze_And_Resolve (N, Typ);
+ -- Whenever possible, replace a prefix which is an enumeration literal
+ -- by the corresponding literal value.
+
+ elsif Attr_Id = Attribute_Enum_Rep then
+ Exp_Attr.Expand_N_Attribute_Reference (N);
+
-- For attributes which return Universal_Integer, introduce a conversion
-- to the expected type with the appropriate check flags set.
@@ -515,12 +522,6 @@ package body Exp_SPARK is
Insert_Explicit_Dereference (Pref);
Analyze_And_Resolve (Pref, Designated_Type (Typ));
-
- if Ekind (Etype (Pref)) = E_Private_Subtype
- and then Is_For_Access_Subtype (Etype (Pref))
- then
- Set_Etype (Pref, Base_Type (Etype (Pref)));
- end if;
end if;
end Expand_SPARK_N_Selected_Component;
diff --git a/gcc/ada/exp_tss.adb b/gcc/ada/exp_tss.adb
index 388be48..8ef05e2 100644
--- a/gcc/ada/exp_tss.adb
+++ b/gcc/ada/exp_tss.adb
@@ -32,6 +32,7 @@ with Lib; use Lib;
with Restrict; use Restrict;
with Rident; use Rident;
with Sem_Aux; use Sem_Aux;
+with Sem_Ch6; use Sem_Ch6;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
@@ -275,8 +276,8 @@ package body Exp_Tss is
then
exit;
- elsif Ekind (Etype (E1)) /= E_Anonymous_Access_Type
- and then Ekind (Etype (E2)) /= E_Anonymous_Access_Type
+ elsif not Is_Anonymous_Access_Type (Etype (E1))
+ and then not Is_Anonymous_Access_Type (Etype (E2))
and then Etype (E1) /= Etype (E2)
then
exit;
@@ -287,6 +288,17 @@ package body Exp_Tss is
/= Directly_Designated_Type (Etype (E2))
then
exit;
+
+ elsif Ekind_In (Etype (E1),
+ E_Anonymous_Access_Subprogram_Type,
+ E_Anonymous_Access_Protected_Subprogram_Type)
+ and then Ekind_In (Etype (E2),
+ E_Anonymous_Access_Subprogram_Type,
+ E_Anonymous_Access_Protected_Subprogram_Type)
+ and then not Conforming_Types
+ (Etype (E1), Etype (E2), Fully_Conformant)
+ then
+ exit;
end if;
E1 := Next_Formal (E1);
diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb
index b81b1b9..f146a6f 100644
--- a/gcc/ada/exp_unst.adb
+++ b/gcc/ada/exp_unst.adb
@@ -598,6 +598,33 @@ package body Exp_Unst is
then
Note_Uplevel_Bound (Prefix (N), Ref);
+ -- Conditional expressions
+
+ elsif Nkind (N) = N_If_Expression then
+ declare
+ Expr : Node_Id;
+
+ begin
+ Expr := First (Expressions (N));
+ while Present (Expr) loop
+ Note_Uplevel_Bound (Expr, Ref);
+ Next (Expr);
+ end loop;
+ end;
+
+ elsif Nkind (N) = N_Case_Expression then
+ declare
+ Alternative : Node_Id;
+
+ begin
+ Note_Uplevel_Bound (Expression (N), Ref);
+
+ Alternative := First (Alternatives (N));
+ while Present (Alternative) loop
+ Note_Uplevel_Bound (Expression (Alternative), Ref);
+ end loop;
+ end;
+
-- Conversion case
elsif Nkind (N) = N_Type_Conversion then
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 4206090..b677a72 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -343,7 +343,7 @@ package body Exp_Util is
return;
end if;
- -- Case of zero/non-zero semantics or non-standard enumeration
+ -- Case of zero/nonzero semantics or nonstandard enumeration
-- representation. In each case, we rewrite the node as:
-- ityp!(N) /= False'Enum_Rep
@@ -4492,7 +4492,7 @@ package body Exp_Util is
begin
-- E is the package or generic package which is externally axiomatized
- if Ekind_In (E, E_Generic_Package, E_Package)
+ if Is_Package_Or_Generic_Package (E)
and then Has_Annotate_Pragma_For_External_Axiomatization (E)
then
return E;
@@ -5067,9 +5067,13 @@ package body Exp_Util is
-- may be constants that depend on the bounds of a string literal, both
-- standard string types and more generally arrays of characters.
- -- In GNATprove mode, these extra subtypes are not needed
+ -- In GNATprove mode, these extra subtypes are not needed, unless Exp is
+ -- a static expression. In that case, the subtype will be constrained
+ -- while the original type might be unconstrained, so expanding the type
+ -- is necessary both for passing legality checks in GNAT and for precise
+ -- analysis in GNATprove.
- if GNATprove_Mode then
+ if GNATprove_Mode and then not Is_Static_Expression (Exp) then
return;
end if;
@@ -5094,7 +5098,7 @@ package body Exp_Util is
-- This subtype indication may be used later for constraint checks
-- we better make sure that if a variable was used as a bound of
- -- of the original slice, its value is frozen.
+ -- the original slice, its value is frozen.
Evaluate_Slice_Bounds (Exp);
end;
@@ -5614,7 +5618,7 @@ package body Exp_Util is
-- We can retrieve primitive operations by name if it is an internal
-- name. For equality we must check that both of its operands have
-- the same type, to avoid confusion with user-defined equalities
- -- than may have a non-symmetric signature.
+ -- than may have a asymmetric signature.
exit when Chars (Op) = Name
and then
@@ -6818,8 +6822,8 @@ package body Exp_Util is
N := Assoc_Node;
P := Parent (Assoc_Node);
- -- Non-subexpression case. Note that N is initially Empty in this case
- -- (N is only guaranteed Non-Empty in the subexpr case).
+ -- Nonsubexpression case. Note that N is initially Empty in this case
+ -- (N is only guaranteed non-Empty in the subexpr case).
else
N := Empty;
@@ -8341,7 +8345,7 @@ package body Exp_Util is
S : Nat;
begin
- -- If component reference is for an array with non-static bounds,
+ -- If component reference is for an array with nonstatic bounds,
-- then it is always aligned: we can only process unaligned arrays
-- with static bounds (more precisely compile time known bounds).
@@ -9063,7 +9067,7 @@ package body Exp_Util is
then
Constr_Root := Root_Typ;
- -- At this point in the expansion, non-limited view of the type
+ -- At this point in the expansion, nonlimited view of the type
-- must be available, otherwise the error will be reported later.
if From_Limited_With (Constr_Root)
@@ -9836,7 +9840,7 @@ package body Exp_Util is
-- in the derivation chain starting from parent type Par_Typ leading to
-- derived type Deriv_Typ. The returned value is one of the following:
--
- -- * An entity which is either a discriminant or a non-discriminant
+ -- * An entity which is either a discriminant or a nondiscriminant
-- name, and renames/constraints Discr.
--
-- * An expression which constraints Discr
@@ -10550,94 +10554,6 @@ package body Exp_Util is
end if;
end Needs_Constant_Address;
- ------------------------
- -- Needs_Finalization --
- ------------------------
-
- function Needs_Finalization (Typ : Entity_Id) return Boolean is
- function Has_Some_Controlled_Component
- (Input_Typ : Entity_Id) return Boolean;
- -- Determine whether type Input_Typ has at least one controlled
- -- component.
-
- -----------------------------------
- -- Has_Some_Controlled_Component --
- -----------------------------------
-
- function Has_Some_Controlled_Component
- (Input_Typ : Entity_Id) return Boolean
- is
- Comp : Entity_Id;
-
- begin
- -- When a type is already frozen and has at least one controlled
- -- component, or is manually decorated, it is sufficient to inspect
- -- flag Has_Controlled_Component.
-
- if Has_Controlled_Component (Input_Typ) then
- return True;
-
- -- Otherwise inspect the internals of the type
-
- elsif not Is_Frozen (Input_Typ) then
- if Is_Array_Type (Input_Typ) then
- return Needs_Finalization (Component_Type (Input_Typ));
-
- elsif Is_Record_Type (Input_Typ) then
- Comp := First_Component (Input_Typ);
- while Present (Comp) loop
- if Needs_Finalization (Etype (Comp)) then
- return True;
- end if;
-
- Next_Component (Comp);
- end loop;
- end if;
- end if;
-
- return False;
- end Has_Some_Controlled_Component;
-
- -- Start of processing for Needs_Finalization
-
- begin
- -- Certain run-time configurations and targets do not provide support
- -- for controlled types.
-
- if Restriction_Active (No_Finalization) then
- return False;
-
- -- C++ types are not considered controlled. It is assumed that the non-
- -- Ada side will handle their clean up.
-
- elsif Convention (Typ) = Convention_CPP then
- return False;
-
- -- Class-wide types are treated as controlled because derivations from
- -- the root type may introduce controlled components.
-
- elsif Is_Class_Wide_Type (Typ) then
- return True;
-
- -- Concurrent types are controlled as long as their corresponding record
- -- is controlled.
-
- elsif Is_Concurrent_Type (Typ)
- and then Present (Corresponding_Record_Type (Typ))
- and then Needs_Finalization (Corresponding_Record_Type (Typ))
- then
- return True;
-
- -- Otherwise the type is controlled when it is either derived from type
- -- [Limited_]Controlled and not subject to aspect Disable_Controlled, or
- -- contains at least one controlled component.
-
- else
- return
- Is_Controlled (Typ) or else Has_Some_Controlled_Component (Typ);
- end if;
- end Needs_Finalization;
-
----------------------------
-- New_Class_Wide_Subtype --
----------------------------
@@ -11329,7 +11245,17 @@ package body Exp_Util is
-- Generate:
-- Rnn : Exp_Type renames Expr;
- if Renaming_Req then
+ -- In GNATprove mode, we prefer to use renamings for intermediate
+ -- variables to definition of constants, due to the implicit move
+ -- operation that such a constant definition causes as part of the
+ -- support in GNATprove for ownership pointers. Hence, we generate
+ -- a renaming for a reference to an object of a nonscalar type.
+
+ if Renaming_Req
+ or else (GNATprove_Mode
+ and then Is_Object_Reference (Exp)
+ and then not Is_Scalar_Type (Exp_Type))
+ then
E :=
Make_Object_Renaming_Declaration (Loc,
Defining_Identifier => Def_Id,
@@ -11451,7 +11377,7 @@ package body Exp_Util is
-- For expressions that denote names, we can use a renaming scheme.
-- This is needed for correctness in the case of a volatile object of
- -- a non-volatile type because the Make_Reference call of the "default"
+ -- a nonvolatile type because the Make_Reference call of the "default"
-- approach would generate an illegal access value (an access value
-- cannot designate such an object - see Analyze_Reference).
@@ -11473,7 +11399,7 @@ package body Exp_Util is
Name => Relocate_Node (Exp)));
-- If this is a packed reference, or a selected component with
- -- a non-standard representation, a reference to the temporary
+ -- a nonstandard representation, a reference to the temporary
-- will be replaced by a copy of the original expression (see
-- Exp_Ch2.Expand_Renaming). Otherwise the temporary must be
-- elaborated by gigi, and is of course not to be replaced in-line
@@ -11687,6 +11613,10 @@ package body Exp_Util is
Set_Assignment_OK (Res, Assignment_OK (Exp));
+ -- Preserve the Do_Range_Check flag in all copies
+
+ Set_Do_Range_Check (Res, Do_Range_Check (Exp));
+
-- Finally rewrite the original expression and we are done
Rewrite (Exp, Res);
@@ -12079,7 +12009,7 @@ package body Exp_Util is
and then Nkind_In (N, N_Package_Body,
N_Package_Specification);
-- N is at the library level if the top-most context is a package and
- -- the path taken to reach N does not inlcude non-package constructs.
+ -- the path taken to reach N does not include nonpackage constructs.
begin
case Nkind (N) is
@@ -12152,9 +12082,7 @@ package body Exp_Util is
Typ : Entity_Id;
begin
- if No (L)
- or else Is_Empty_List (L)
- then
+ if No (L) or else Is_Empty_List (L) then
return False;
end if;
@@ -12766,7 +12694,7 @@ package body Exp_Util is
-- Mark the assignment statement as elaboration code. This allows
-- the early call region mechanism (see Sem_Elab) to properly
- -- ignore such assignments even though they are non-preelaborable
+ -- ignore such assignments even though they are nonpreelaborable
-- code.
Set_Is_Elaboration_Code (Asn);
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 7cb9d2d..c0848c7 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -944,10 +944,6 @@ package Exp_Util is
-- consist of constants, when the object has a nontrivial initialization
-- or is controlled.
- function Needs_Finalization (Typ : Entity_Id) return Boolean;
- -- Determine whether type Typ is controlled and this requires finalization
- -- actions.
-
function Non_Limited_Designated_Type (T : Entity_Id) return Entity_Id;
-- An anonymous access type may designate a limited view. Check whether
-- non-limited view is available during expansion, to examine components
diff --git a/gcc/ada/expander.adb b/gcc/ada/expander.adb
index 11711b9..aac2e7d 100644
--- a/gcc/ada/expander.adb
+++ b/gcc/ada/expander.adb
@@ -112,7 +112,12 @@ package body Expander is
Expand_SPARK (N);
end if;
- Set_Analyzed (N, Full_Analysis);
+ -- Do not reset the Analyzed flag if it has been set on purpose
+ -- during preanalysis.
+
+ if Full_Analysis then
+ Set_Analyzed (N);
+ end if;
-- Regular expansion is normally followed by special handling for
-- transient scopes for unconstrained results, etc. but this is not
diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c
index 76fce78..349af3f 100644
--- a/gcc/ada/expect.c
+++ b/gcc/ada/expect.c
@@ -29,14 +29,11 @@
* *
****************************************************************************/
-#ifdef __alpha_vxworks
-#include "vxWorks.h"
-#endif
-
#ifdef IN_RTS
#define POSIX
-#include "tconfig.h"
-#include "tsystem.h"
+#include "runtime.h"
+#include <unistd.h>
+
#else
#include "config.h"
#include "system.h"
diff --git a/gcc/ada/fname-uf.ads b/gcc/ada/fname-uf.ads
index 90b2ef3..3e62c47 100644
--- a/gcc/ada/fname-uf.ads
+++ b/gcc/ada/fname-uf.ads
@@ -105,7 +105,7 @@ package Fname.UF is
Dot : String_Ptr;
Cas : Casing_Type);
-- This is called to process a Source_File_Name pragma whose first
- -- argument is a file name pattern string. Pat is this pattern string,
+ -- argument is a file name pattern string. Pat is this pattern string,
-- which contains an asterisk to correspond to the unit. Typ is one of
-- 'b'/'s'/'u' for body/spec/subunit, Dot is the separator string
-- for child/subunit names, and Cas is one of Lower/Upper/Mixed
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 5b843f2..00d20e9 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -62,6 +62,7 @@ with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Snames; use Snames;
with Stand; use Stand;
+with Stringt; use Stringt;
with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Ttypes; use Ttypes;
@@ -407,11 +408,14 @@ package body Freeze is
-- calls to the renamed entity. The body must be generated in any case
-- for calls that may appear elsewhere. This is not done in the case
-- where the subprogram is an instantiation because the actual proper
- -- body has not been built yet.
+ -- body has not been built yet. This is also not done in GNATprove mode
+ -- as we need to check other conditions for creating a body to inline
+ -- in that case, which are controlled in Analyze_Subprogram_Body_Helper.
if Ekind_In (Old_S, E_Function, E_Procedure)
and then Nkind (Decl) = N_Subprogram_Declaration
and then not Is_Generic_Instance (Old_S)
+ and then not GNATprove_Mode
then
Set_Body_To_Inline (Decl, Old_S);
end if;
@@ -7999,6 +8003,7 @@ package body Freeze is
Brng : constant Node_Id := Scalar_Range (Btyp);
BLo : constant Node_Id := Low_Bound (Brng);
BHi : constant Node_Id := High_Bound (Brng);
+ Par : constant Entity_Id := First_Subtype (Typ);
Small : constant Ureal := Small_Value (Typ);
Loval : Ureal;
Hival : Ureal;
@@ -8051,6 +8056,16 @@ package body Freeze is
end if;
end if;
+ -- The 'small attribute may have been specified with an aspect,
+ -- in which case it is processed after a subtype declaration, so
+ -- inherit now the specified value.
+
+ if Typ /= Par
+ and then Present (Find_Aspect (Par, Aspect_Small))
+ then
+ Set_Small_Value (Typ, Small_Value (Par));
+ end if;
+
-- Immediate return if the range is already analyzed. This means that
-- the range is already set, and does not need to be computed by this
-- routine.
@@ -8763,6 +8778,20 @@ package body Freeze is
Set_Is_Pure (E, False);
end if;
+ -- For C++ constructors check that their external name has been given
+ -- (either in pragma CPP_Constructor or in a pragma import).
+
+ if Is_Constructor (E)
+ and then
+ (No (Interface_Name (E))
+ or else String_Equal
+ (L => Strval (Interface_Name (E)),
+ R => Strval (Get_Default_External_Name (E))))
+ then
+ Error_Msg_N
+ ("'C++ constructor must have external name or link name", E);
+ end if;
+
-- We also reset the Pure indication on a subprogram with an Address
-- parameter, because the parameter may be used as a pointer and the
-- referenced data may change even if the address value does not.
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index dd90c7b..b6a337a 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -355,6 +355,7 @@ GNAT_ADA_OBJS = \
ada/prep.o \
ada/prepcomp.o \
ada/put_scos.o \
+ ada/repinfo-input.o \
ada/repinfo.o \
ada/restrict.o \
ada/rident.o \
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 32dd132..6cd3759 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -6276,13 +6276,17 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
Node_Id gnat_pragma;
/* Make the decl for the elaboration procedure. Emit debug info for it, so
that users can break into their elaboration code in debuggers. Kludge:
- don't consider it as a definition so that we have a line map for its body,
- but no subprogram description in debug info. */
+ don't consider it as a definition so that we have a line map for its
+ body, but no subprogram description in debug info. In addition, don't
+ qualify it as artificial, even though it is not a user subprogram per se,
+ in particular for specs. Unlike, say, clones created internally by the
+ compiler, this subprogram materializes specific user code and flagging it
+ artificial would take elab code away from gcov's analysis. */
tree gnu_elab_proc_decl
= create_subprog_decl
(create_concat_name (gnat_unit_entity, body_p ? "elabb" : "elabs"),
NULL_TREE, void_ftype, NULL_TREE,
- is_default, true, false, true, true, false, NULL, gnat_unit);
+ is_default, true, false, false, true, false, NULL, gnat_unit);
struct elab_info *info;
vec_safe_push (gnu_elab_proc_stack, gnu_elab_proc_decl);
diff --git a/gcc/ada/get_scos.adb b/gcc/ada/get_scos.adb
index 27cf190..bf6df5e 100644
--- a/gcc/ada/get_scos.adb
+++ b/gcc/ada/get_scos.adb
@@ -179,12 +179,6 @@ procedure Get_SCOs is
Skipc;
C := Nextc;
exit when C /= LF and then C /= CR;
-
- if C = ' ' then
- Skip_Spaces;
- C := Nextc;
- exit when C /= LF and then C /= CR;
- end if;
end loop;
end Skip_EOL;
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index 1f5817a..ecb3ccd 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -51,6 +51,7 @@ with Output; use Output;
with Par_SCO;
with Prepcomp;
with Repinfo;
+with Repinfo.Input;
with Restrict;
with Rident; use Rident;
with Rtsfind;
@@ -61,10 +62,11 @@ with Sem_Ch12;
with Sem_Ch13;
with Sem_Elim;
with Sem_Eval;
-with Sem_SPARK; use Sem_SPARK;
+with Sem_Prag;
with Sem_Type;
with Set_Targ;
with Sinfo; use Sinfo;
+with Sinput; use Sinput;
with Sinput.L; use Sinput.L;
with Snames; use Snames;
with Sprint; use Sprint;
@@ -81,6 +83,7 @@ with Uname; use Uname;
with Urealp;
with Usage;
with Validsw; use Validsw;
+with Warnsw; use Warnsw;
with System.Assertions;
with System.OS_Lib;
@@ -112,6 +115,12 @@ procedure Gnat1drv is
-- the information provided by the back end in back annotation of declared
-- entities (e.g. actual size and alignment values chosen by the back end).
+ procedure Read_JSON_Files_For_Repinfo;
+ -- This procedure exercises the JSON parser of Repinfo by reading back the
+ -- JSON files generated by -gnatRjs in a previous compilation session. It
+ -- is intended to make sure that the JSON generator and the JSON parser are
+ -- kept synchronized when the JSON format evolves.
+
----------------------------
-- Adjust_Global_Switches --
----------------------------
@@ -318,7 +327,12 @@ procedure Gnat1drv is
Elaboration_Check => True,
others => False);
- Dynamic_Elaboration_Checks := False;
+ -- Need to enable dynamic elaboration checks to disable strict
+ -- static checking performed by gnatbind. We are at the same time
+ -- suppressing actual compile time elaboration checks to simplify
+ -- the generated code.
+
+ Dynamic_Elaboration_Checks := True;
-- Set STRICT mode for overflow checks if not set explicitly. This
-- prevents suppressing of overflow checks by default, in code down
@@ -379,8 +393,7 @@ procedure Gnat1drv is
-- enough useful info.
Reset_Validity_Check_Options;
- Validity_Check_Default := True;
- Validity_Check_Copies := True;
+ Set_Validity_Check_Options ("dc");
Check_Validity_Of_Parameters := False;
-- Turn off style check options and ignore any style check pragmas
@@ -403,7 +416,22 @@ procedure Gnat1drv is
Relaxed_RM_Semantics := True;
- if not Generate_CodePeer_Messages then
+ if Generate_CodePeer_Messages then
+
+ -- We do want to emit GNAT warnings when using -gnateC. But,
+ -- in CodePeer mode, warnings about memory representation are not
+ -- meaningful, thus, suppress them.
+
+ Warn_On_Biased_Representation := False; -- -gnatw.b
+ Warn_On_Unrepped_Components := False; -- -gnatw.c
+ Warn_On_Record_Holes := False; -- -gnatw.h
+ Warn_On_Unchecked_Conversion := False; -- -gnatwz
+ Warn_On_Size_Alignment := False; -- -gnatw.z
+ Warn_On_Questionable_Layout := False; -- -gnatw.q
+ Warn_On_Overridden_Size := False; -- -gnatw.s
+ Warn_On_Reverse_Bit_Order := False; -- -gnatw.v
+
+ else
-- Suppress compiler warnings by default when generating SCIL for
-- CodePeer, except when combined with -gnateC where we do want to
@@ -991,7 +1019,7 @@ procedure Gnat1drv is
Atree.Unlock;
Nlists.Unlock;
Sem.Unlock;
- Sem_Ch13.Validate_Compile_Time_Warning_Errors;
+ Sem_Prag.Validate_Compile_Time_Warning_Errors;
Sem.Lock;
Nlists.Lock;
Atree.Lock;
@@ -1016,6 +1044,39 @@ procedure Gnat1drv is
-- end if;
end Post_Compilation_Validation_Checks;
+ -----------------------------------
+ -- Read_JSON_Files_For_Repinfo --
+ -----------------------------------
+
+ procedure Read_JSON_Files_For_Repinfo is
+ begin
+ -- This is the same loop construct as in Repinfo.List_Rep_Info
+
+ for U in Main_Unit .. Last_Unit loop
+ if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
+ declare
+ Nam : constant String :=
+ Get_Name_String
+ (File_Name (Source_Index (U))) & ".json";
+ Namid : constant File_Name_Type := Name_Enter (Nam);
+ Index : constant Source_File_Index := Load_Config_File (Namid);
+
+ begin
+ if Index = No_Source_File then
+ Write_Str ("cannot locate ");
+ Write_Line (Nam);
+ raise Unrecoverable_Error;
+ end if;
+
+ Repinfo.Input.Read_JSON_Stream (Source_Text (Index).all, Nam);
+ exception
+ when Repinfo.Input.Invalid_JSON_Stream =>
+ raise Unrecoverable_Error;
+ end;
+ end if;
+ end loop;
+ end Read_JSON_Files_For_Repinfo;
+
-- Local variables
Back_End_Mode : Back_End.Back_End_Mode_Type;
@@ -1082,7 +1143,6 @@ begin
-- Acquire target parameters from system.ads (package System source)
Targparm_Acquire : declare
- use Sinput;
S : Source_File_Index;
N : File_Name_Type;
@@ -1525,13 +1585,6 @@ begin
if GNATprove_Mode then
- -- Perform the new SPARK checking rules for pointer aliasing. This is
- -- only activated in GNATprove mode and on SPARK code.
-
- if Debug_Flag_FF then
- Check_Safe_Pointers (Main_Unit_Node);
- end if;
-
-- In GNATprove mode we're writing the ALI much earlier than usual
-- as flow analysis needs the file present in order to append its
-- own globals to it.
@@ -1550,6 +1603,12 @@ begin
Par_SCO.SCO_Record_Filtered;
end if;
+ -- If -gnatd_j is specified, exercise the JSON parser of Repinfo
+
+ if Debug_Flag_Underscore_J then
+ Read_JSON_Files_For_Repinfo;
+ end if;
+
-- Back end needs to explicitly unlock tables it needs to touch
Atree.Lock;
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 39a24ab..257c394 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -729,6 +729,7 @@ The GNAT Library
* GNAT.Array_Split (g-arrspl.ads): GNAT Array_Split g-arrspl ads.
* GNAT.AWK (g-awk.ads): GNAT AWK g-awk ads.
* GNAT.Bind_Environment (g-binenv.ads): GNAT Bind_Environment g-binenv ads.
+* GNAT.Branch_Prediction (g-brapre.ads): GNAT Branch_Prediction g-brapre ads.
* GNAT.Bounded_Buffers (g-boubuf.ads): GNAT Bounded_Buffers g-boubuf ads.
* GNAT.Bounded_Mailboxes (g-boumai.ads): GNAT Bounded_Mailboxes g-boumai ads.
* GNAT.Bubble_Sort (g-bubsor.ads): GNAT Bubble_Sort g-bubsor ads.
@@ -2103,7 +2104,7 @@ case, and it is recommended that these two options not be used together.
Syntax:
@example
-pragma Asynch_Readers [ (boolean_EXPRESSION) ];
+pragma Async_Readers [ (boolean_EXPRESSION) ];
@end example
For the semantics of this pragma, see the entry for aspect @code{Async_Readers} in
@@ -2117,7 +2118,7 @@ the SPARK 2014 Reference Manual, section 7.1.2.
Syntax:
@example
-pragma Asynch_Writers [ (boolean_EXPRESSION) ];
+pragma Async_Writers [ (boolean_EXPRESSION) ];
@end example
For the semantics of this pragma, see the entry for aspect @code{Async_Writers} in
@@ -3870,7 +3871,7 @@ then the name will be forced to all lowercase letters. A specification of
taken from the string provided.
@end itemize
-This pragma may appear anywhere that a pragma is valid. In particular, it
+This pragma may appear anywhere that a pragma is valid. In particular, it
can be used as a configuration pragma in the @code{gnat.adc} file, in which
case it applies to all subsequent compilations, or it can be used as a program
unit pragma, in which case it only applies to the current unit, or it can
@@ -4441,58 +4442,102 @@ in the SPARK 2014 Reference Manual, section 7.1.6.
Syntax:
@example
-pragma Initialize_Scalars;
+pragma Initialize_Scalars
+ [ ( TYPE_VALUE_PAIR @{, TYPE_VALUE_PAIR@} ) ];
+
+TYPE_VALUE_PAIR ::=
+ SCALAR_TYPE => static_EXPRESSION
+
+SCALAR_TYPE :=
+ Short_Float
+| Float
+| Long_Float
+| Long_Long_Flat
+| Signed_8
+| Signed_16
+| Signed_32
+| Signed_64
+| Unsigned_8
+| Unsigned_16
+| Unsigned_32
+| Unsigned_64
@end example
-This pragma is similar to @code{Normalize_Scalars} conceptually but has
-two important differences. First, there is no requirement for the pragma
-to be used uniformly in all units of a partition, in particular, it is fine
-to use this just for some or all of the application units of a partition,
-without needing to recompile the run-time library.
-
-In the case where some units are compiled with the pragma, and some without,
-then a declaration of a variable where the type is defined in package
-Standard or is locally declared will always be subject to initialization,
-as will any declaration of a scalar variable. For composite variables,
-whether the variable is initialized may also depend on whether the package
-in which the type of the variable is declared is compiled with the pragma.
-
-The other important difference is that you can control the value used
-for initializing scalar objects. At bind time, you can select several
-options for initialization. You can
-initialize with invalid values (similar to Normalize_Scalars, though for
-Initialize_Scalars it is not always possible to determine the invalid
-values in complex cases like signed component fields with non-standard
-sizes). You can also initialize with high or
-low values, or with a specified bit pattern. See the GNAT
-User's Guide for binder options for specifying these cases.
-
-This means that you can compile a program, and then without having to
-recompile the program, you can run it with different values being used
-for initializing otherwise uninitialized values, to test if your program
-behavior depends on the choice. Of course the behavior should not change,
-and if it does, then most likely you have an incorrect reference to an
-uninitialized value.
-
-It is even possible to change the value at execution time eliminating even
-the need to rebind with a different switch using an environment variable.
-See the GNAT User's Guide for details.
+This pragma is similar to @code{Normalize_Scalars} conceptually but has two
+important differences.
+
+First, there is no requirement for the pragma to be used uniformly in all units
+of a partition. In particular, it is fine to use this just for some or all of
+the application units of a partition, without needing to recompile the run-time
+library. In the case where some units are compiled with the pragma, and some
+without, then a declaration of a variable where the type is defined in package
+Standard or is locally declared will always be subject to initialization, as
+will any declaration of a scalar variable. For composite variables, whether the
+variable is initialized may also depend on whether the package in which the
+type of the variable is declared is compiled with the pragma.
+
+The other important difference is that the programmer can control the value
+used for initializing scalar objects. This effect can be achieved in several
+different ways:
+
+
+@itemize *
+
+@item
+At compile time, the programmer can specify the invalid value for a
+particular family of scalar types using the optional arguments of the pragma.
+
+The compile-time approach is intended to optimize the generated code for the
+pragma, by possibly using fast operations such as @code{memset}.
+
+@item
+At bind time, the programmer has several options:
+
+
+@itemize *
+
+@item
+Initialization with invalid values (similar to Normalize_Scalars, though
+for Initialize_Scalars it is not always possible to determine the invalid
+values in complex cases like signed component fields with nonstandard
+sizes).
+
+@item
+Initialization with high values.
-Note that pragma @code{Initialize_Scalars} is particularly useful in
-conjunction with the enhanced validity checking that is now provided
-in GNAT, which checks for invalid values under more conditions.
-Using this feature (see description of the @emph{-gnatV} flag in the
-GNAT User's Guide) in conjunction with
-pragma @code{Initialize_Scalars}
-provides a powerful new tool to assist in the detection of problems
-caused by uninitialized variables.
-
-Note: the use of @code{Initialize_Scalars} has a fairly extensive
-effect on the generated code. This may cause your code to be
-substantially larger. It may also cause an increase in the amount
-of stack required, so it is probably a good idea to turn on stack
-checking (see description of stack checking in the GNAT
-User's Guide) when using this pragma.
+@item
+Initialization with low values.
+
+@item
+Initialization with a specific bit pattern.
+@end itemize
+
+See the GNAT User's Guide for binder options for specifying these cases.
+
+The bind-time approach is intended to provide fast turnaround for testing
+with different values, without having to recompile the program.
+
+@item
+At execution time, the programmer can speify the invalid values using an
+environment variable. See the GNAT User's Guide for details.
+
+The execution-time approach is intended to provide fast turnaround for
+testing with different values, without having to recompile and rebind the
+program.
+@end itemize
+
+Note that pragma @code{Initialize_Scalars} is particularly useful in conjunction
+with the enhanced validity checking that is now provided in GNAT, which checks
+for invalid values under more conditions. Using this feature (see description
+of the @emph{-gnatV} flag in the GNAT User's Guide) in conjunction with pragma
+@code{Initialize_Scalars} provides a powerful new tool to assist in the detection
+of problems caused by uninitialized variables.
+
+Note: the use of @code{Initialize_Scalars} has a fairly extensive effect on the
+generated code. This may cause your code to be substantially larger. It may
+also cause an increase in the amount of stack required, so it is probably a
+good idea to turn on stack checking (see description of stack checking in the
+GNAT User's Guide) when using this pragma.
@node Pragma Initializes,Pragma Inline_Always,Pragma Initialize_Scalars,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-initializes}@anchor{83}@anchor{gnat_rm/implementation_defined_pragmas id17}@anchor{84}
@@ -8779,11 +8824,10 @@ $ gcc -c -gnatVim ...
@end itemize
The form ALL_CHECKS activates all standard checks (its use is equivalent
-to the use of the @code{gnatva} switch.
+to the use of the @code{gnatVa} switch).
-The forms with @code{Off} and @code{On}
-can be used to temporarily disable validity checks
-as shown in the following example:
+The forms with @code{Off} and @code{On} can be used to temporarily disable
+validity checks as shown in the following example:
@example
pragma Validity_Checks ("c"); -- validity checks for copies
@@ -10669,16 +10713,16 @@ indicates whether or not the corresponding actual type has discriminants.
@geindex Img
-The @code{Img} attribute differs from @code{Image} in that it is applied
-directly to an object, and yields the same result as
-@code{Image} for the subtype of the object. This is convenient for
-debugging:
+The @code{Img} attribute differs from @code{Image} in that, while both can be
+applied directly to an object, @code{Img} cannot be applied to types.
+
+Example usage of the attribute:
@example
Put_Line ("X = " & X'Img);
@end example
-has the same meaning as the more verbose:
+which has the same meaning as the more verbose:
@example
Put_Line ("X = " & T'Image (X));
@@ -11227,8 +11271,8 @@ for Date'Scalar_Storage_Order use System.High_Order_First;
-- the former is used.
@end example
-Other properties are as for standard representation attribute @code{Bit_Order},
-as defined by Ada RM 13.5.3(4). The default is @code{System.Default_Bit_Order}.
+Other properties are as for the standard representation attribute @code{Bit_Order}
+defined by Ada RM 13.5.3(4). The default is @code{System.Default_Bit_Order}.
For a record type @code{T}, if @code{T'Scalar_Storage_Order} is
specified explicitly, it shall be equal to @code{T'Bit_Order}. Note:
@@ -11238,8 +11282,8 @@ specified explicitly and set to the same value.
Derived types inherit an explicitly set scalar storage order from their parent
types. This may be overridden for the derived type by giving an explicit scalar
-storage order for the derived type. For a record extension, the derived type
-must have the same scalar storage order as the parent type.
+storage order for it. However, for a record extension, the derived type must
+have the same scalar storage order as the parent type.
A component of a record type that is itself a record or an array and that does
not start and end on a byte boundary must have have the same scalar storage
@@ -11289,15 +11333,18 @@ inheritance in the case of a derived type), then the default is normally
the native ordering of the target, but this default can be overridden using
pragma @code{Default_Scalar_Storage_Order}.
-Note that if a component of @code{T} is itself of a record or array type,
-the specfied @code{Scalar_Storage_Order} does @emph{not} apply to that nested type:
-an explicit attribute definition clause must be provided for the component
-type as well if desired.
+If a component of @code{T} is itself of a record or array type, the specfied
+@code{Scalar_Storage_Order} does @emph{not} apply to that nested type: an explicit
+attribute definition clause must be provided for the component type as well
+if desired.
Note that the scalar storage order only affects the in-memory data
representation. It has no effect on the representation used by stream
attributes.
+Note that debuggers may be unable to display the correct value of scalar
+components of a type for which the opposite storage order is specified.
+
@node Attribute Simple_Storage_Pool,Attribute Small,Attribute Scalar_Storage_Order,Implementation Defined Attributes
@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{e7}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{19c}
@section Attribute Simple_Storage_Pool
@@ -12464,7 +12511,8 @@ of exceptions when they are declared.
@geindex No_Exceptions
[RM H.4] This restriction ensures at compile time that there are no
-raise statements and no exception handlers.
+raise statements and no exception handlers and also suppresses the
+generation of language-defined run-time checks.
@node No_Finalization,No_Fixed_Point,No_Exceptions,Partition-Wide Restrictions
@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1d2}
@@ -12839,7 +12887,7 @@ user-defined storage pool.
[GNAT] This restriction affects the performance of stream operations on types
@code{String}, @code{Wide_String} and @code{Wide_Wide_String}. By default, the
compiler uses block reads and writes when manipulating @code{String} objects
-due to their supperior performance. When this restriction is in effect, the
+due to their superior performance. When this restriction is in effect, the
compiler performs all IO operations on a per-character basis.
@node No_Streams,No_Task_Allocators,No_Stream_Optimizations,Partition-Wide Restrictions
@@ -22966,6 +23014,7 @@ of GNAT, and will generate a warning message.
* GNAT.Array_Split (g-arrspl.ads): GNAT Array_Split g-arrspl ads.
* GNAT.AWK (g-awk.ads): GNAT AWK g-awk ads.
* GNAT.Bind_Environment (g-binenv.ads): GNAT Bind_Environment g-binenv ads.
+* GNAT.Branch_Prediction (g-brapre.ads): GNAT Branch_Prediction g-brapre ads.
* GNAT.Bounded_Buffers (g-boubuf.ads): GNAT Bounded_Buffers g-boubuf ads.
* GNAT.Bounded_Mailboxes (g-boumai.ads): GNAT Bounded_Mailboxes g-boumai ads.
* GNAT.Bubble_Sort (g-bubsor.ads): GNAT Bubble_Sort g-bubsor ads.
@@ -23772,7 +23821,7 @@ Provides AWK-like parsing functions, with an easy interface for parsing one
or more files containing formatted data. The file is viewed as a database
where each record is a line and a field is a data element in this line.
-@node GNAT Bind_Environment g-binenv ads,GNAT Bounded_Buffers g-boubuf ads,GNAT AWK g-awk ads,The GNAT Library
+@node GNAT Bind_Environment g-binenv ads,GNAT Branch_Prediction g-brapre ads,GNAT AWK g-awk ads,The GNAT Library
@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{326}@anchor{gnat_rm/the_gnat_library id45}@anchor{327}
@section @code{GNAT.Bind_Environment} (@code{g-binenv.ads})
@@ -23785,8 +23834,19 @@ Provides access to key=value associations captured at bind time.
These associations can be specified using the @code{-V} binder command
line switch.
-@node GNAT Bounded_Buffers g-boubuf ads,GNAT Bounded_Mailboxes g-boumai ads,GNAT Bind_Environment g-binenv ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id46}@anchor{328}@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{329}
+@node GNAT Branch_Prediction g-brapre ads,GNAT Bounded_Buffers g-boubuf ads,GNAT Bind_Environment g-binenv ads,The GNAT Library
+@anchor{gnat_rm/the_gnat_library id46}@anchor{328}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{329}
+@section @code{GNAT.Branch_Prediction} (@code{g-brapre.ads})
+
+
+@geindex GNAT.Branch_Prediction (g-brapre.ads)
+
+@geindex Branch Prediction
+
+Provides routines giving hints to the branch predictor of the code generator.
+
+@node GNAT Bounded_Buffers g-boubuf ads,GNAT Bounded_Mailboxes g-boumai ads,GNAT Branch_Prediction g-brapre ads,The GNAT Library
+@anchor{gnat_rm/the_gnat_library id47}@anchor{32a}@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{32b}
@section @code{GNAT.Bounded_Buffers} (@code{g-boubuf.ads})
@@ -23801,7 +23861,7 @@ useful directly or as parts of the implementations of other abstractions,
such as mailboxes.
@node GNAT Bounded_Mailboxes g-boumai ads,GNAT Bubble_Sort g-bubsor ads,GNAT Bounded_Buffers g-boubuf ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id47}@anchor{32a}@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{32b}
+@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{32c}@anchor{gnat_rm/the_gnat_library id48}@anchor{32d}
@section @code{GNAT.Bounded_Mailboxes} (@code{g-boumai.ads})
@@ -23814,7 +23874,7 @@ such as mailboxes.
Provides a thread-safe asynchronous intertask mailbox communication facility.
@node GNAT Bubble_Sort g-bubsor ads,GNAT Bubble_Sort_A g-busora ads,GNAT Bounded_Mailboxes g-boumai ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{32c}@anchor{gnat_rm/the_gnat_library id48}@anchor{32d}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{32e}@anchor{gnat_rm/the_gnat_library id49}@anchor{32f}
@section @code{GNAT.Bubble_Sort} (@code{g-bubsor.ads})
@@ -23829,7 +23889,7 @@ data items. Exchange and comparison procedures are provided by passing
access-to-procedure values.
@node GNAT Bubble_Sort_A g-busora ads,GNAT Bubble_Sort_G g-busorg ads,GNAT Bubble_Sort g-bubsor ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id49}@anchor{32e}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{32f}
+@anchor{gnat_rm/the_gnat_library id50}@anchor{330}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{331}
@section @code{GNAT.Bubble_Sort_A} (@code{g-busora.ads})
@@ -23845,7 +23905,7 @@ access-to-procedure values. This is an older version, retained for
compatibility. Usually @code{GNAT.Bubble_Sort} will be preferable.
@node GNAT Bubble_Sort_G g-busorg ads,GNAT Byte_Order_Mark g-byorma ads,GNAT Bubble_Sort_A g-busora ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{330}@anchor{gnat_rm/the_gnat_library id50}@anchor{331}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id51}@anchor{333}
@section @code{GNAT.Bubble_Sort_G} (@code{g-busorg.ads})
@@ -23861,7 +23921,7 @@ if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
@node GNAT Byte_Order_Mark g-byorma ads,GNAT Byte_Swapping g-bytswa ads,GNAT Bubble_Sort_G g-busorg ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id51}@anchor{333}
+@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{334}@anchor{gnat_rm/the_gnat_library id52}@anchor{335}
@section @code{GNAT.Byte_Order_Mark} (@code{g-byorma.ads})
@@ -23877,7 +23937,7 @@ the encoding of the string. The routine includes detection of special XML
sequences for various UCS input formats.
@node GNAT Byte_Swapping g-bytswa ads,GNAT Calendar g-calend ads,GNAT Byte_Order_Mark g-byorma ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{334}@anchor{gnat_rm/the_gnat_library id52}@anchor{335}
+@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id53}@anchor{337}
@section @code{GNAT.Byte_Swapping} (@code{g-bytswa.ads})
@@ -23891,7 +23951,7 @@ General routines for swapping the bytes in 2-, 4-, and 8-byte quantities.
Machine-specific implementations are available in some cases.
@node GNAT Calendar g-calend ads,GNAT Calendar Time_IO g-catiio ads,GNAT Byte_Swapping g-bytswa ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id53}@anchor{337}
+@anchor{gnat_rm/the_gnat_library id54}@anchor{338}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{339}
@section @code{GNAT.Calendar} (@code{g-calend.ads})
@@ -23905,7 +23965,7 @@ Also provides conversion of @code{Ada.Calendar.Time} values to and from the
C @code{timeval} format.
@node GNAT Calendar Time_IO g-catiio ads,GNAT CRC32 g-crc32 ads,GNAT Calendar g-calend ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id54}@anchor{338}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{339}
+@anchor{gnat_rm/the_gnat_library id55}@anchor{33a}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{33b}
@section @code{GNAT.Calendar.Time_IO} (@code{g-catiio.ads})
@@ -23916,7 +23976,7 @@ C @code{timeval} format.
@geindex GNAT.Calendar.Time_IO (g-catiio.ads)
@node GNAT CRC32 g-crc32 ads,GNAT Case_Util g-casuti ads,GNAT Calendar Time_IO g-catiio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id55}@anchor{33a}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{33b}
+@anchor{gnat_rm/the_gnat_library id56}@anchor{33c}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{33d}
@section @code{GNAT.CRC32} (@code{g-crc32.ads})
@@ -23933,7 +23993,7 @@ of this algorithm see
Aug. 1988. Sarwate, D.V.
@node GNAT Case_Util g-casuti ads,GNAT CGI g-cgi ads,GNAT CRC32 g-crc32 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id56}@anchor{33c}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{33d}
+@anchor{gnat_rm/the_gnat_library id57}@anchor{33e}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{33f}
@section @code{GNAT.Case_Util} (@code{g-casuti.ads})
@@ -23948,7 +24008,7 @@ without the overhead of the full casing tables
in @code{Ada.Characters.Handling}.
@node GNAT CGI g-cgi ads,GNAT CGI Cookie g-cgicoo ads,GNAT Case_Util g-casuti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id57}@anchor{33e}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{33f}
+@anchor{gnat_rm/the_gnat_library id58}@anchor{340}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{341}
@section @code{GNAT.CGI} (@code{g-cgi.ads})
@@ -23963,7 +24023,7 @@ builds a table whose index is the key and provides some services to deal
with this table.
@node GNAT CGI Cookie g-cgicoo ads,GNAT CGI Debug g-cgideb ads,GNAT CGI g-cgi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{340}@anchor{gnat_rm/the_gnat_library id58}@anchor{341}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{342}@anchor{gnat_rm/the_gnat_library id59}@anchor{343}
@section @code{GNAT.CGI.Cookie} (@code{g-cgicoo.ads})
@@ -23978,7 +24038,7 @@ Common Gateway Interface (CGI). It exports services to deal with Web
cookies (piece of information kept in the Web client software).
@node GNAT CGI Debug g-cgideb ads,GNAT Command_Line g-comlin ads,GNAT CGI Cookie g-cgicoo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{342}@anchor{gnat_rm/the_gnat_library id59}@anchor{343}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{344}@anchor{gnat_rm/the_gnat_library id60}@anchor{345}
@section @code{GNAT.CGI.Debug} (@code{g-cgideb.ads})
@@ -23990,7 +24050,7 @@ This is a package to help debugging CGI (Common Gateway Interface)
programs written in Ada.
@node GNAT Command_Line g-comlin ads,GNAT Compiler_Version g-comver ads,GNAT CGI Debug g-cgideb ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id60}@anchor{344}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{345}
+@anchor{gnat_rm/the_gnat_library id61}@anchor{346}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{347}
@section @code{GNAT.Command_Line} (@code{g-comlin.ads})
@@ -24000,10 +24060,10 @@ programs written in Ada.
Provides a high level interface to @code{Ada.Command_Line} facilities,
including the ability to scan for named switches with optional parameters
-and expand file names using wild card notations.
+and expand file names using wildcard notations.
@node GNAT Compiler_Version g-comver ads,GNAT Ctrl_C g-ctrl_c ads,GNAT Command_Line g-comlin ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{346}@anchor{gnat_rm/the_gnat_library id61}@anchor{347}
+@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{348}@anchor{gnat_rm/the_gnat_library id62}@anchor{349}
@section @code{GNAT.Compiler_Version} (@code{g-comver.ads})
@@ -24021,7 +24081,7 @@ of the compiler if a consistent tool set is used to compile all units
of a partition).
@node GNAT Ctrl_C g-ctrl_c ads,GNAT Current_Exception g-curexc ads,GNAT Compiler_Version g-comver ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{348}@anchor{gnat_rm/the_gnat_library id62}@anchor{349}
+@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{34a}@anchor{gnat_rm/the_gnat_library id63}@anchor{34b}
@section @code{GNAT.Ctrl_C} (@code{g-ctrl_c.ads})
@@ -24032,7 +24092,7 @@ of a partition).
Provides a simple interface to handle Ctrl-C keyboard events.
@node GNAT Current_Exception g-curexc ads,GNAT Debug_Pools g-debpoo ads,GNAT Ctrl_C g-ctrl_c ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id63}@anchor{34a}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{34b}
+@anchor{gnat_rm/the_gnat_library id64}@anchor{34c}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{34d}
@section @code{GNAT.Current_Exception} (@code{g-curexc.ads})
@@ -24049,7 +24109,7 @@ This is particularly useful in simulating typical facilities for
obtaining information about exceptions provided by Ada 83 compilers.
@node GNAT Debug_Pools g-debpoo ads,GNAT Debug_Utilities g-debuti ads,GNAT Current_Exception g-curexc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{34c}@anchor{gnat_rm/the_gnat_library id64}@anchor{34d}
+@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{34e}@anchor{gnat_rm/the_gnat_library id65}@anchor{34f}
@section @code{GNAT.Debug_Pools} (@code{g-debpoo.ads})
@@ -24066,7 +24126,7 @@ problems.
See @code{The GNAT Debug_Pool Facility} section in the @cite{GNAT User's Guide}.
@node GNAT Debug_Utilities g-debuti ads,GNAT Decode_String g-decstr ads,GNAT Debug_Pools g-debpoo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id65}@anchor{34e}@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{34f}
+@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{350}@anchor{gnat_rm/the_gnat_library id66}@anchor{351}
@section @code{GNAT.Debug_Utilities} (@code{g-debuti.ads})
@@ -24079,7 +24139,7 @@ to and from string images of address values. Supports both C and Ada formats
for hexadecimal literals.
@node GNAT Decode_String g-decstr ads,GNAT Decode_UTF8_String g-deutst ads,GNAT Debug_Utilities g-debuti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{350}@anchor{gnat_rm/the_gnat_library id66}@anchor{351}
+@anchor{gnat_rm/the_gnat_library id67}@anchor{352}@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{353}
@section @code{GNAT.Decode_String} (@code{g-decstr.ads})
@@ -24103,7 +24163,7 @@ Useful in conjunction with Unicode character coding. Note there is a
preinstantiation for UTF-8. See next entry.
@node GNAT Decode_UTF8_String g-deutst ads,GNAT Directory_Operations g-dirope ads,GNAT Decode_String g-decstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{352}@anchor{gnat_rm/the_gnat_library id67}@anchor{353}
+@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{354}@anchor{gnat_rm/the_gnat_library id68}@anchor{355}
@section @code{GNAT.Decode_UTF8_String} (@code{g-deutst.ads})
@@ -24124,7 +24184,7 @@ preinstantiation for UTF-8. See next entry.
A preinstantiation of GNAT.Decode_Strings for UTF-8 encoding.
@node GNAT Directory_Operations g-dirope ads,GNAT Directory_Operations Iteration g-diopit ads,GNAT Decode_UTF8_String g-deutst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{354}@anchor{gnat_rm/the_gnat_library id68}@anchor{355}
+@anchor{gnat_rm/the_gnat_library id69}@anchor{356}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{357}
@section @code{GNAT.Directory_Operations} (@code{g-dirope.ads})
@@ -24137,7 +24197,7 @@ the current directory, making new directories, and scanning the files in a
directory.
@node GNAT Directory_Operations Iteration g-diopit ads,GNAT Dynamic_HTables g-dynhta ads,GNAT Directory_Operations g-dirope ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id69}@anchor{356}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{357}
+@anchor{gnat_rm/the_gnat_library id70}@anchor{358}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{359}
@section @code{GNAT.Directory_Operations.Iteration} (@code{g-diopit.ads})
@@ -24149,7 +24209,7 @@ A child unit of GNAT.Directory_Operations providing additional operations
for iterating through directories.
@node GNAT Dynamic_HTables g-dynhta ads,GNAT Dynamic_Tables g-dyntab ads,GNAT Directory_Operations Iteration g-diopit ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id70}@anchor{358}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{359}
+@anchor{gnat_rm/the_gnat_library id71}@anchor{35a}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{35b}
@section @code{GNAT.Dynamic_HTables} (@code{g-dynhta.ads})
@@ -24167,7 +24227,7 @@ dynamic instances of the hash table, while an instantiation of
@code{GNAT.HTable} creates a single instance of the hash table.
@node GNAT Dynamic_Tables g-dyntab ads,GNAT Encode_String g-encstr ads,GNAT Dynamic_HTables g-dynhta ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{35a}@anchor{gnat_rm/the_gnat_library id71}@anchor{35b}
+@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{35c}@anchor{gnat_rm/the_gnat_library id72}@anchor{35d}
@section @code{GNAT.Dynamic_Tables} (@code{g-dyntab.ads})
@@ -24187,7 +24247,7 @@ dynamic instances of the table, while an instantiation of
@code{GNAT.Table} creates a single instance of the table type.
@node GNAT Encode_String g-encstr ads,GNAT Encode_UTF8_String g-enutst ads,GNAT Dynamic_Tables g-dyntab ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id72}@anchor{35c}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{35d}
+@anchor{gnat_rm/the_gnat_library id73}@anchor{35e}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{35f}
@section @code{GNAT.Encode_String} (@code{g-encstr.ads})
@@ -24209,7 +24269,7 @@ encoding method. Useful in conjunction with Unicode character coding.
Note there is a preinstantiation for UTF-8. See next entry.
@node GNAT Encode_UTF8_String g-enutst ads,GNAT Exception_Actions g-excact ads,GNAT Encode_String g-encstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{35e}@anchor{gnat_rm/the_gnat_library id73}@anchor{35f}
+@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{360}@anchor{gnat_rm/the_gnat_library id74}@anchor{361}
@section @code{GNAT.Encode_UTF8_String} (@code{g-enutst.ads})
@@ -24230,7 +24290,7 @@ Note there is a preinstantiation for UTF-8. See next entry.
A preinstantiation of GNAT.Encode_Strings for UTF-8 encoding.
@node GNAT Exception_Actions g-excact ads,GNAT Exception_Traces g-exctra ads,GNAT Encode_UTF8_String g-enutst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{360}@anchor{gnat_rm/the_gnat_library id74}@anchor{361}
+@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{362}@anchor{gnat_rm/the_gnat_library id75}@anchor{363}
@section @code{GNAT.Exception_Actions} (@code{g-excact.ads})
@@ -24243,7 +24303,7 @@ for specific exceptions, or when any exception is raised. This
can be used for instance to force a core dump to ease debugging.
@node GNAT Exception_Traces g-exctra ads,GNAT Exceptions g-except ads,GNAT Exception_Actions g-excact ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{362}@anchor{gnat_rm/the_gnat_library id75}@anchor{363}
+@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{364}@anchor{gnat_rm/the_gnat_library id76}@anchor{365}
@section @code{GNAT.Exception_Traces} (@code{g-exctra.ads})
@@ -24257,7 +24317,7 @@ Provides an interface allowing to control automatic output upon exception
occurrences.
@node GNAT Exceptions g-except ads,GNAT Expect g-expect ads,GNAT Exception_Traces g-exctra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id76}@anchor{364}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{365}
+@anchor{gnat_rm/the_gnat_library id77}@anchor{366}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{367}
@section @code{GNAT.Exceptions} (@code{g-except.ads})
@@ -24278,7 +24338,7 @@ predefined exceptions, and for example allow raising
@code{Constraint_Error} with a message from a pure subprogram.
@node GNAT Expect g-expect ads,GNAT Expect TTY g-exptty ads,GNAT Exceptions g-except ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{366}@anchor{gnat_rm/the_gnat_library id77}@anchor{367}
+@anchor{gnat_rm/the_gnat_library id78}@anchor{368}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{369}
@section @code{GNAT.Expect} (@code{g-expect.ads})
@@ -24294,7 +24354,7 @@ It is not implemented for cross ports, and in particular is not
implemented for VxWorks or LynxOS.
@node GNAT Expect TTY g-exptty ads,GNAT Float_Control g-flocon ads,GNAT Expect g-expect ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id78}@anchor{368}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{369}
+@anchor{gnat_rm/the_gnat_library id79}@anchor{36a}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{36b}
@section @code{GNAT.Expect.TTY} (@code{g-exptty.ads})
@@ -24306,7 +24366,7 @@ ports. It is not implemented for cross ports, and
in particular is not implemented for VxWorks or LynxOS.
@node GNAT Float_Control g-flocon ads,GNAT Formatted_String g-forstr ads,GNAT Expect TTY g-exptty ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id79}@anchor{36a}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{36b}
+@anchor{gnat_rm/the_gnat_library id80}@anchor{36c}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{36d}
@section @code{GNAT.Float_Control} (@code{g-flocon.ads})
@@ -24320,7 +24380,7 @@ library calls may cause this mode to be modified, and the Reset procedure
in this package can be used to reestablish the required mode.
@node GNAT Formatted_String g-forstr ads,GNAT Heap_Sort g-heasor ads,GNAT Float_Control g-flocon ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id80}@anchor{36c}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{36d}
+@anchor{gnat_rm/the_gnat_library id81}@anchor{36e}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{36f}
@section @code{GNAT.Formatted_String} (@code{g-forstr.ads})
@@ -24335,7 +24395,7 @@ derived from Integer, Float or enumerations as values for the
formatted string.
@node GNAT Heap_Sort g-heasor ads,GNAT Heap_Sort_A g-hesora ads,GNAT Formatted_String g-forstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{36e}@anchor{gnat_rm/the_gnat_library id81}@anchor{36f}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{370}@anchor{gnat_rm/the_gnat_library id82}@anchor{371}
@section @code{GNAT.Heap_Sort} (@code{g-heasor.ads})
@@ -24349,7 +24409,7 @@ access-to-procedure values. The algorithm used is a modified heap sort
that performs approximately N*log(N) comparisons in the worst case.
@node GNAT Heap_Sort_A g-hesora ads,GNAT Heap_Sort_G g-hesorg ads,GNAT Heap_Sort g-heasor ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id82}@anchor{370}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{371}
+@anchor{gnat_rm/the_gnat_library id83}@anchor{372}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{373}
@section @code{GNAT.Heap_Sort_A} (@code{g-hesora.ads})
@@ -24365,7 +24425,7 @@ This differs from @code{GNAT.Heap_Sort} in having a less convenient
interface, but may be slightly more efficient.
@node GNAT Heap_Sort_G g-hesorg ads,GNAT HTable g-htable ads,GNAT Heap_Sort_A g-hesora ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id83}@anchor{372}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{373}
+@anchor{gnat_rm/the_gnat_library id84}@anchor{374}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{375}
@section @code{GNAT.Heap_Sort_G} (@code{g-hesorg.ads})
@@ -24379,7 +24439,7 @@ if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
@node GNAT HTable g-htable ads,GNAT IO g-io ads,GNAT Heap_Sort_G g-hesorg ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id84}@anchor{374}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{375}
+@anchor{gnat_rm/the_gnat_library id85}@anchor{376}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{377}
@section @code{GNAT.HTable} (@code{g-htable.ads})
@@ -24392,7 +24452,7 @@ data. Provides two approaches, one a simple static approach, and the other
allowing arbitrary dynamic hash tables.
@node GNAT IO g-io ads,GNAT IO_Aux g-io_aux ads,GNAT HTable g-htable ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id85}@anchor{376}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{377}
+@anchor{gnat_rm/the_gnat_library id86}@anchor{378}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{379}
@section @code{GNAT.IO} (@code{g-io.ads})
@@ -24408,7 +24468,7 @@ Standard_Input, and writing characters, strings and integers to either
Standard_Output or Standard_Error.
@node GNAT IO_Aux g-io_aux ads,GNAT Lock_Files g-locfil ads,GNAT IO g-io ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{378}@anchor{gnat_rm/the_gnat_library id86}@anchor{379}
+@anchor{gnat_rm/the_gnat_library id87}@anchor{37a}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{37b}
@section @code{GNAT.IO_Aux} (@code{g-io_aux.ads})
@@ -24422,7 +24482,7 @@ Provides some auxiliary functions for use with Text_IO, including a test
for whether a file exists, and functions for reading a line of text.
@node GNAT Lock_Files g-locfil ads,GNAT MBBS_Discrete_Random g-mbdira ads,GNAT IO_Aux g-io_aux ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id87}@anchor{37a}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{37b}
+@anchor{gnat_rm/the_gnat_library id88}@anchor{37c}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{37d}
@section @code{GNAT.Lock_Files} (@code{g-locfil.ads})
@@ -24436,7 +24496,7 @@ Provides a general interface for using files as locks. Can be used for
providing program level synchronization.
@node GNAT MBBS_Discrete_Random g-mbdira ads,GNAT MBBS_Float_Random g-mbflra ads,GNAT Lock_Files g-locfil ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id88}@anchor{37c}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{37d}
+@anchor{gnat_rm/the_gnat_library id89}@anchor{37e}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{37f}
@section @code{GNAT.MBBS_Discrete_Random} (@code{g-mbdira.ads})
@@ -24448,7 +24508,7 @@ The original implementation of @code{Ada.Numerics.Discrete_Random}. Uses
a modified version of the Blum-Blum-Shub generator.
@node GNAT MBBS_Float_Random g-mbflra ads,GNAT MD5 g-md5 ads,GNAT MBBS_Discrete_Random g-mbdira ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id89}@anchor{37e}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{37f}
+@anchor{gnat_rm/the_gnat_library id90}@anchor{380}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{381}
@section @code{GNAT.MBBS_Float_Random} (@code{g-mbflra.ads})
@@ -24460,7 +24520,7 @@ The original implementation of @code{Ada.Numerics.Float_Random}. Uses
a modified version of the Blum-Blum-Shub generator.
@node GNAT MD5 g-md5 ads,GNAT Memory_Dump g-memdum ads,GNAT MBBS_Float_Random g-mbflra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id90}@anchor{380}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{381}
+@anchor{gnat_rm/the_gnat_library id91}@anchor{382}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{383}
@section @code{GNAT.MD5} (@code{g-md5.ads})
@@ -24473,7 +24533,7 @@ the HMAC-MD5 message authentication function as described in RFC 2104 and
FIPS PUB 198.
@node GNAT Memory_Dump g-memdum ads,GNAT Most_Recent_Exception g-moreex ads,GNAT MD5 g-md5 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id91}@anchor{382}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{383}
+@anchor{gnat_rm/the_gnat_library id92}@anchor{384}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{385}
@section @code{GNAT.Memory_Dump} (@code{g-memdum.ads})
@@ -24486,7 +24546,7 @@ standard output or standard error files. Uses GNAT.IO for actual
output.
@node GNAT Most_Recent_Exception g-moreex ads,GNAT OS_Lib g-os_lib ads,GNAT Memory_Dump g-memdum ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id92}@anchor{384}@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{385}
+@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{386}@anchor{gnat_rm/the_gnat_library id93}@anchor{387}
@section @code{GNAT.Most_Recent_Exception} (@code{g-moreex.ads})
@@ -24500,7 +24560,7 @@ various logging purposes, including duplicating functionality of some
Ada 83 implementation dependent extensions.
@node GNAT OS_Lib g-os_lib ads,GNAT Perfect_Hash_Generators g-pehage ads,GNAT Most_Recent_Exception g-moreex ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{386}@anchor{gnat_rm/the_gnat_library id93}@anchor{387}
+@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{388}@anchor{gnat_rm/the_gnat_library id94}@anchor{389}
@section @code{GNAT.OS_Lib} (@code{g-os_lib.ads})
@@ -24516,7 +24576,7 @@ including a portable spawn procedure, and access to environment variables
and error return codes.
@node GNAT Perfect_Hash_Generators g-pehage ads,GNAT Random_Numbers g-rannum ads,GNAT OS_Lib g-os_lib ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{388}@anchor{gnat_rm/the_gnat_library id94}@anchor{389}
+@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{38a}@anchor{gnat_rm/the_gnat_library id95}@anchor{38b}
@section @code{GNAT.Perfect_Hash_Generators} (@code{g-pehage.ads})
@@ -24534,7 +24594,7 @@ hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.
@node GNAT Random_Numbers g-rannum ads,GNAT Regexp g-regexp ads,GNAT Perfect_Hash_Generators g-pehage ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{38a}@anchor{gnat_rm/the_gnat_library id95}@anchor{38b}
+@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{38c}@anchor{gnat_rm/the_gnat_library id96}@anchor{38d}
@section @code{GNAT.Random_Numbers} (@code{g-rannum.ads})
@@ -24546,7 +24606,7 @@ Provides random number capabilities which extend those available in the
standard Ada library and are more convenient to use.
@node GNAT Regexp g-regexp ads,GNAT Registry g-regist ads,GNAT Random_Numbers g-rannum ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{255}@anchor{gnat_rm/the_gnat_library id96}@anchor{38c}
+@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{255}@anchor{gnat_rm/the_gnat_library id97}@anchor{38e}
@section @code{GNAT.Regexp} (@code{g-regexp.ads})
@@ -24562,7 +24622,7 @@ simplest of the three pattern matching packages provided, and is particularly
suitable for 'file globbing' applications.
@node GNAT Registry g-regist ads,GNAT Regpat g-regpat ads,GNAT Regexp g-regexp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{38d}@anchor{gnat_rm/the_gnat_library id97}@anchor{38e}
+@anchor{gnat_rm/the_gnat_library id98}@anchor{38f}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{390}
@section @code{GNAT.Registry} (@code{g-regist.ads})
@@ -24576,7 +24636,7 @@ registry API, but at a lower level of abstraction, refer to the Win32.Winreg
package provided with the Win32Ada binding
@node GNAT Regpat g-regpat ads,GNAT Rewrite_Data g-rewdat ads,GNAT Registry g-regist ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id98}@anchor{38f}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{390}
+@anchor{gnat_rm/the_gnat_library id99}@anchor{391}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{392}
@section @code{GNAT.Regpat} (@code{g-regpat.ads})
@@ -24591,7 +24651,7 @@ from the original V7 style regular expression library written in C by
Henry Spencer (and binary compatible with this C library).
@node GNAT Rewrite_Data g-rewdat ads,GNAT Secondary_Stack_Info g-sestin ads,GNAT Regpat g-regpat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id99}@anchor{391}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{392}
+@anchor{gnat_rm/the_gnat_library id100}@anchor{393}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{394}
@section @code{GNAT.Rewrite_Data} (@code{g-rewdat.ads})
@@ -24605,7 +24665,7 @@ full content to be processed is not loaded into memory all at once. This makes
this interface usable for large files or socket streams.
@node GNAT Secondary_Stack_Info g-sestin ads,GNAT Semaphores g-semaph ads,GNAT Rewrite_Data g-rewdat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id100}@anchor{393}@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{394}
+@anchor{gnat_rm/the_gnat_library id101}@anchor{395}@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{396}
@section @code{GNAT.Secondary_Stack_Info} (@code{g-sestin.ads})
@@ -24617,7 +24677,7 @@ Provide the capability to query the high water mark of the current task's
secondary stack.
@node GNAT Semaphores g-semaph ads,GNAT Serial_Communications g-sercom ads,GNAT Secondary_Stack_Info g-sestin ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id101}@anchor{395}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{396}
+@anchor{gnat_rm/the_gnat_library id102}@anchor{397}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{398}
@section @code{GNAT.Semaphores} (@code{g-semaph.ads})
@@ -24628,7 +24688,7 @@ secondary stack.
Provides classic counting and binary semaphores using protected types.
@node GNAT Serial_Communications g-sercom ads,GNAT SHA1 g-sha1 ads,GNAT Semaphores g-semaph ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{397}@anchor{gnat_rm/the_gnat_library id102}@anchor{398}
+@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{399}@anchor{gnat_rm/the_gnat_library id103}@anchor{39a}
@section @code{GNAT.Serial_Communications} (@code{g-sercom.ads})
@@ -24640,7 +24700,7 @@ Provides a simple interface to send and receive data over a serial
port. This is only supported on GNU/Linux and Windows.
@node GNAT SHA1 g-sha1 ads,GNAT SHA224 g-sha224 ads,GNAT Serial_Communications g-sercom ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{399}@anchor{gnat_rm/the_gnat_library id103}@anchor{39a}
+@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{39b}@anchor{gnat_rm/the_gnat_library id104}@anchor{39c}
@section @code{GNAT.SHA1} (@code{g-sha1.ads})
@@ -24653,7 +24713,7 @@ and RFC 3174, and the HMAC-SHA1 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA224 g-sha224 ads,GNAT SHA256 g-sha256 ads,GNAT SHA1 g-sha1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{39b}@anchor{gnat_rm/the_gnat_library id104}@anchor{39c}
+@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{39d}@anchor{gnat_rm/the_gnat_library id105}@anchor{39e}
@section @code{GNAT.SHA224} (@code{g-sha224.ads})
@@ -24666,7 +24726,7 @@ and the HMAC-SHA224 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA256 g-sha256 ads,GNAT SHA384 g-sha384 ads,GNAT SHA224 g-sha224 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id105}@anchor{39d}@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{39e}
+@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{39f}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a0}
@section @code{GNAT.SHA256} (@code{g-sha256.ads})
@@ -24679,7 +24739,7 @@ and the HMAC-SHA256 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA384 g-sha384 ads,GNAT SHA512 g-sha512 ads,GNAT SHA256 g-sha256 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{39f}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a0}
+@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a1}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a2}
@section @code{GNAT.SHA384} (@code{g-sha384.ads})
@@ -24692,7 +24752,7 @@ and the HMAC-SHA384 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA512 g-sha512 ads,GNAT Signals g-signal ads,GNAT SHA384 g-sha384 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a1}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a2}
+@anchor{gnat_rm/the_gnat_library id108}@anchor{3a3}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a4}
@section @code{GNAT.SHA512} (@code{g-sha512.ads})
@@ -24705,7 +24765,7 @@ and the HMAC-SHA512 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT Signals g-signal ads,GNAT Sockets g-socket ads,GNAT SHA512 g-sha512 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3a3}@anchor{gnat_rm/the_gnat_library id108}@anchor{3a4}
+@anchor{gnat_rm/the_gnat_library id109}@anchor{3a5}@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3a6}
@section @code{GNAT.Signals} (@code{g-signal.ads})
@@ -24717,7 +24777,7 @@ Provides the ability to manipulate the blocked status of signals on supported
targets.
@node GNAT Sockets g-socket ads,GNAT Source_Info g-souinf ads,GNAT Signals g-signal ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id109}@anchor{3a5}@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3a6}
+@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3a7}@anchor{gnat_rm/the_gnat_library id110}@anchor{3a8}
@section @code{GNAT.Sockets} (@code{g-socket.ads})
@@ -24732,7 +24792,7 @@ on all native GNAT ports and on VxWorks cross prots. It is not implemented for
the LynxOS cross port.
@node GNAT Source_Info g-souinf ads,GNAT Spelling_Checker g-speche ads,GNAT Sockets g-socket ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3a7}@anchor{gnat_rm/the_gnat_library id110}@anchor{3a8}
+@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3a9}@anchor{gnat_rm/the_gnat_library id111}@anchor{3aa}
@section @code{GNAT.Source_Info} (@code{g-souinf.ads})
@@ -24746,7 +24806,7 @@ subprograms yielding the date and time of the current compilation (like the
C macros @code{__DATE__} and @code{__TIME__})
@node GNAT Spelling_Checker g-speche ads,GNAT Spelling_Checker_Generic g-spchge ads,GNAT Source_Info g-souinf ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3a9}@anchor{gnat_rm/the_gnat_library id111}@anchor{3aa}
+@anchor{gnat_rm/the_gnat_library id112}@anchor{3ab}@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3ac}
@section @code{GNAT.Spelling_Checker} (@code{g-speche.ads})
@@ -24758,7 +24818,7 @@ Provides a function for determining whether one string is a plausible
near misspelling of another string.
@node GNAT Spelling_Checker_Generic g-spchge ads,GNAT Spitbol Patterns g-spipat ads,GNAT Spelling_Checker g-speche ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id112}@anchor{3ab}@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3ac}
+@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3ad}@anchor{gnat_rm/the_gnat_library id113}@anchor{3ae}
@section @code{GNAT.Spelling_Checker_Generic} (@code{g-spchge.ads})
@@ -24771,7 +24831,7 @@ determining whether one string is a plausible near misspelling of another
string.
@node GNAT Spitbol Patterns g-spipat ads,GNAT Spitbol g-spitbo ads,GNAT Spelling_Checker_Generic g-spchge ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id113}@anchor{3ad}@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3ae}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3af}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b0}
@section @code{GNAT.Spitbol.Patterns} (@code{g-spipat.ads})
@@ -24787,7 +24847,7 @@ the SNOBOL4 dynamic pattern construction and matching capabilities, using the
efficient algorithm developed by Robert Dewar for the SPITBOL system.
@node GNAT Spitbol g-spitbo ads,GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Patterns g-spipat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3af}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b0}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b2}
@section @code{GNAT.Spitbol} (@code{g-spitbo.ads})
@@ -24802,7 +24862,7 @@ useful for constructing arbitrary mappings from strings in the style of
the SNOBOL4 TABLE function.
@node GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol g-spitbo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b2}
+@anchor{gnat_rm/the_gnat_library id116}@anchor{3b3}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b4}
@section @code{GNAT.Spitbol.Table_Boolean} (@code{g-sptabo.ads})
@@ -24817,7 +24877,7 @@ for type @code{Standard.Boolean}, giving an implementation of sets of
string values.
@node GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol Table_VString g-sptavs ads,GNAT Spitbol Table_Boolean g-sptabo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3b3}@anchor{gnat_rm/the_gnat_library id116}@anchor{3b4}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3b5}@anchor{gnat_rm/the_gnat_library id117}@anchor{3b6}
@section @code{GNAT.Spitbol.Table_Integer} (@code{g-sptain.ads})
@@ -24834,7 +24894,7 @@ for type @code{Standard.Integer}, giving an implementation of maps
from string to integer values.
@node GNAT Spitbol Table_VString g-sptavs ads,GNAT SSE g-sse ads,GNAT Spitbol Table_Integer g-sptain ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id117}@anchor{3b5}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3b6}
+@anchor{gnat_rm/the_gnat_library id118}@anchor{3b7}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3b8}
@section @code{GNAT.Spitbol.Table_VString} (@code{g-sptavs.ads})
@@ -24851,7 +24911,7 @@ a variable length string type, giving an implementation of general
maps from strings to strings.
@node GNAT SSE g-sse ads,GNAT SSE Vector_Types g-ssvety ads,GNAT Spitbol Table_VString g-sptavs ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id118}@anchor{3b7}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3b8}
+@anchor{gnat_rm/the_gnat_library id119}@anchor{3b9}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3ba}
@section @code{GNAT.SSE} (@code{g-sse.ads})
@@ -24863,7 +24923,7 @@ targets. It exposes vector component types together with a general
introduction to the binding contents and use.
@node GNAT SSE Vector_Types g-ssvety ads,GNAT String_Hash g-strhas ads,GNAT SSE g-sse ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3b9}@anchor{gnat_rm/the_gnat_library id119}@anchor{3ba}
+@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3bb}@anchor{gnat_rm/the_gnat_library id120}@anchor{3bc}
@section @code{GNAT.SSE.Vector_Types} (@code{g-ssvety.ads})
@@ -24872,7 +24932,7 @@ introduction to the binding contents and use.
SSE vector types for use with SSE related intrinsics.
@node GNAT String_Hash g-strhas ads,GNAT Strings g-string ads,GNAT SSE Vector_Types g-ssvety ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3bb}@anchor{gnat_rm/the_gnat_library id120}@anchor{3bc}
+@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3bd}@anchor{gnat_rm/the_gnat_library id121}@anchor{3be}
@section @code{GNAT.String_Hash} (@code{g-strhas.ads})
@@ -24884,7 +24944,7 @@ Provides a generic hash function working on arrays of scalars. Both the scalar
type and the hash result type are parameters.
@node GNAT Strings g-string ads,GNAT String_Split g-strspl ads,GNAT String_Hash g-strhas ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3bd}@anchor{gnat_rm/the_gnat_library id121}@anchor{3be}
+@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3bf}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c0}
@section @code{GNAT.Strings} (@code{g-string.ads})
@@ -24894,7 +24954,7 @@ Common String access types and related subprograms. Basically it
defines a string access and an array of string access types.
@node GNAT String_Split g-strspl ads,GNAT Table g-table ads,GNAT Strings g-string ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3bf}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c0}
+@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3c1}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c2}
@section @code{GNAT.String_Split} (@code{g-strspl.ads})
@@ -24908,7 +24968,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node GNAT Table g-table ads,GNAT Task_Lock g-tasloc ads,GNAT String_Split g-strspl ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c1}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c2}
+@anchor{gnat_rm/the_gnat_library id124}@anchor{3c3}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c4}
@section @code{GNAT.Table} (@code{g-table.ads})
@@ -24928,7 +24988,7 @@ while an instantiation of @code{GNAT.Dynamic_Tables} creates a type that can be
used to define dynamic instances of the table.
@node GNAT Task_Lock g-tasloc ads,GNAT Time_Stamp g-timsta ads,GNAT Table g-table ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id124}@anchor{3c3}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3c4}
+@anchor{gnat_rm/the_gnat_library id125}@anchor{3c5}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3c6}
@section @code{GNAT.Task_Lock} (@code{g-tasloc.ads})
@@ -24945,7 +25005,7 @@ single global task lock. Appropriate for use in situations where contention
between tasks is very rarely expected.
@node GNAT Time_Stamp g-timsta ads,GNAT Threads g-thread ads,GNAT Task_Lock g-tasloc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id125}@anchor{3c5}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3c6}
+@anchor{gnat_rm/the_gnat_library id126}@anchor{3c7}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3c8}
@section @code{GNAT.Time_Stamp} (@code{g-timsta.ads})
@@ -24960,7 +25020,7 @@ represents the current date and time in ISO 8601 format. This is a very simple
routine with minimal code and there are no dependencies on any other unit.
@node GNAT Threads g-thread ads,GNAT Traceback g-traceb ads,GNAT Time_Stamp g-timsta ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3c7}@anchor{gnat_rm/the_gnat_library id126}@anchor{3c8}
+@anchor{gnat_rm/the_gnat_library id127}@anchor{3c9}@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3ca}
@section @code{GNAT.Threads} (@code{g-thread.ads})
@@ -24977,7 +25037,7 @@ further details if your program has threads that are created by a non-Ada
environment which then accesses Ada code.
@node GNAT Traceback g-traceb ads,GNAT Traceback Symbolic g-trasym ads,GNAT Threads g-thread ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id127}@anchor{3c9}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3ca}
+@anchor{gnat_rm/the_gnat_library id128}@anchor{3cb}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3cc}
@section @code{GNAT.Traceback} (@code{g-traceb.ads})
@@ -24989,7 +25049,7 @@ Provides a facility for obtaining non-symbolic traceback information, useful
in various debugging situations.
@node GNAT Traceback Symbolic g-trasym ads,GNAT UTF_32 g-table ads,GNAT Traceback g-traceb ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3cb}@anchor{gnat_rm/the_gnat_library id128}@anchor{3cc}
+@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3cd}@anchor{gnat_rm/the_gnat_library id129}@anchor{3ce}
@section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads})
@@ -24998,7 +25058,7 @@ in various debugging situations.
@geindex Trace back facilities
@node GNAT UTF_32 g-table ads,GNAT Wide_Spelling_Checker g-u3spch ads,GNAT Traceback Symbolic g-trasym ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id129}@anchor{3cd}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3ce}
+@anchor{gnat_rm/the_gnat_library id130}@anchor{3cf}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d0}
@section @code{GNAT.UTF_32} (@code{g-table.ads})
@@ -25017,7 +25077,7 @@ lower case to upper case fold routine corresponding to
the Ada 2005 rules for identifier equivalence.
@node GNAT Wide_Spelling_Checker g-u3spch ads,GNAT Wide_Spelling_Checker g-wispch ads,GNAT UTF_32 g-table ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3cf}@anchor{gnat_rm/the_gnat_library id130}@anchor{3d0}
+@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id131}@anchor{3d2}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-u3spch.ads})
@@ -25030,7 +25090,7 @@ near misspelling of another wide wide string, where the strings are represented
using the UTF_32_String type defined in System.Wch_Cnv.
@node GNAT Wide_Spelling_Checker g-wispch ads,GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Spelling_Checker g-u3spch ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id131}@anchor{3d2}
+@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d3}@anchor{gnat_rm/the_gnat_library id132}@anchor{3d4}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-wispch.ads})
@@ -25042,7 +25102,7 @@ Provides a function for determining whether one wide string is a plausible
near misspelling of another wide string.
@node GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Spelling_Checker g-wispch ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id132}@anchor{3d3}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3d4}
+@anchor{gnat_rm/the_gnat_library id133}@anchor{3d5}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3d6}
@section @code{GNAT.Wide_String_Split} (@code{g-wistsp.ads})
@@ -25056,7 +25116,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Wide_String_Split g-zistsp ads,GNAT Wide_String_Split g-wistsp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3d5}@anchor{gnat_rm/the_gnat_library id133}@anchor{3d6}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3d7}@anchor{gnat_rm/the_gnat_library id134}@anchor{3d8}
@section @code{GNAT.Wide_Wide_Spelling_Checker} (@code{g-zspche.ads})
@@ -25068,7 +25128,7 @@ Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string.
@node GNAT Wide_Wide_String_Split g-zistsp ads,Interfaces C Extensions i-cexten ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3d7}@anchor{gnat_rm/the_gnat_library id134}@anchor{3d8}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3d9}@anchor{gnat_rm/the_gnat_library id135}@anchor{3da}
@section @code{GNAT.Wide_Wide_String_Split} (@code{g-zistsp.ads})
@@ -25082,7 +25142,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node Interfaces C Extensions i-cexten ads,Interfaces C Streams i-cstrea ads,GNAT Wide_Wide_String_Split g-zistsp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3d9}@anchor{gnat_rm/the_gnat_library id135}@anchor{3da}
+@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id136}@anchor{3dc}
@section @code{Interfaces.C.Extensions} (@code{i-cexten.ads})
@@ -25093,7 +25153,7 @@ for use with either manually or automatically generated bindings
to C libraries.
@node Interfaces C Streams i-cstrea ads,Interfaces Packed_Decimal i-pacdec ads,Interfaces C Extensions i-cexten ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id136}@anchor{3dc}
+@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3dd}@anchor{gnat_rm/the_gnat_library id137}@anchor{3de}
@section @code{Interfaces.C.Streams} (@code{i-cstrea.ads})
@@ -25106,7 +25166,7 @@ This package is a binding for the most commonly used operations
on C streams.
@node Interfaces Packed_Decimal i-pacdec ads,Interfaces VxWorks i-vxwork ads,Interfaces C Streams i-cstrea ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3dd}@anchor{gnat_rm/the_gnat_library id137}@anchor{3de}
+@anchor{gnat_rm/the_gnat_library id138}@anchor{3df}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3e0}
@section @code{Interfaces.Packed_Decimal} (@code{i-pacdec.ads})
@@ -25121,7 +25181,7 @@ from a packed decimal format compatible with that used on IBM
mainframes.
@node Interfaces VxWorks i-vxwork ads,Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces Packed_Decimal i-pacdec ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id138}@anchor{3df}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e0}
+@anchor{gnat_rm/the_gnat_library id139}@anchor{3e1}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e2}
@section @code{Interfaces.VxWorks} (@code{i-vxwork.ads})
@@ -25137,7 +25197,7 @@ In particular, it interfaces with the
VxWorks hardware interrupt facilities.
@node Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces VxWorks IO i-vxwoio ads,Interfaces VxWorks i-vxwork ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e1}@anchor{gnat_rm/the_gnat_library id139}@anchor{3e2}
+@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e3}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e4}
@section @code{Interfaces.VxWorks.Int_Connection} (@code{i-vxinco.ads})
@@ -25153,7 +25213,7 @@ intConnect() with a custom routine for installing interrupt
handlers.
@node Interfaces VxWorks IO i-vxwoio ads,System Address_Image s-addima ads,Interfaces VxWorks Int_Connection i-vxinco ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3e3}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e4}
+@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3e5}@anchor{gnat_rm/the_gnat_library id141}@anchor{3e6}
@section @code{Interfaces.VxWorks.IO} (@code{i-vxwoio.ads})
@@ -25176,7 +25236,7 @@ function codes. A particular use of this package is
to enable the use of Get_Immediate under VxWorks.
@node System Address_Image s-addima ads,System Assertions s-assert ads,Interfaces VxWorks IO i-vxwoio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id141}@anchor{3e5}@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3e6}
+@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id142}@anchor{3e8}
@section @code{System.Address_Image} (@code{s-addima.ads})
@@ -25192,7 +25252,7 @@ function that gives an (implementation dependent)
string which identifies an address.
@node System Assertions s-assert ads,System Atomic_Counters s-atocou ads,System Address_Image s-addima ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id142}@anchor{3e8}
+@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3e9}@anchor{gnat_rm/the_gnat_library id143}@anchor{3ea}
@section @code{System.Assertions} (@code{s-assert.ads})
@@ -25208,7 +25268,7 @@ by an run-time assertion failure, as well as the routine that
is used internally to raise this assertion.
@node System Atomic_Counters s-atocou ads,System Memory s-memory ads,System Assertions s-assert ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id143}@anchor{3e9}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3ea}
+@anchor{gnat_rm/the_gnat_library id144}@anchor{3eb}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3ec}
@section @code{System.Atomic_Counters} (@code{s-atocou.ads})
@@ -25222,7 +25282,7 @@ on most targets, including all Alpha, ia64, PowerPC, SPARC V9,
x86, and x86_64 platforms.
@node System Memory s-memory ads,System Multiprocessors s-multip ads,System Atomic_Counters s-atocou ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3eb}@anchor{gnat_rm/the_gnat_library id144}@anchor{3ec}
+@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3ed}@anchor{gnat_rm/the_gnat_library id145}@anchor{3ee}
@section @code{System.Memory} (@code{s-memory.ads})
@@ -25240,7 +25300,7 @@ calls to this unit may be made for low level allocation uses (for
example see the body of @code{GNAT.Tables}).
@node System Multiprocessors s-multip ads,System Multiprocessors Dispatching_Domains s-mudido ads,System Memory s-memory ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id145}@anchor{3ed}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3ee}
+@anchor{gnat_rm/the_gnat_library id146}@anchor{3ef}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3f0}
@section @code{System.Multiprocessors} (@code{s-multip.ads})
@@ -25253,7 +25313,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
@node System Multiprocessors Dispatching_Domains s-mudido ads,System Partition_Interface s-parint ads,System Multiprocessors s-multip ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3ef}@anchor{gnat_rm/the_gnat_library id146}@anchor{3f0}
+@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f1}@anchor{gnat_rm/the_gnat_library id147}@anchor{3f2}
@section @code{System.Multiprocessors.Dispatching_Domains} (@code{s-mudido.ads})
@@ -25266,7 +25326,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
@node System Partition_Interface s-parint ads,System Pool_Global s-pooglo ads,System Multiprocessors Dispatching_Domains s-mudido ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id147}@anchor{3f1}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f2}
+@anchor{gnat_rm/the_gnat_library id148}@anchor{3f3}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f4}
@section @code{System.Partition_Interface} (@code{s-parint.ads})
@@ -25279,7 +25339,7 @@ is used primarily in a distribution context when using Annex E
with @code{GLADE}.
@node System Pool_Global s-pooglo ads,System Pool_Local s-pooloc ads,System Partition_Interface s-parint ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id148}@anchor{3f3}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3f4}
+@anchor{gnat_rm/the_gnat_library id149}@anchor{3f5}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3f6}
@section @code{System.Pool_Global} (@code{s-pooglo.ads})
@@ -25296,7 +25356,7 @@ declared. It uses malloc/free to allocate/free and does not attempt to
do any automatic reclamation.
@node System Pool_Local s-pooloc ads,System Restrictions s-restri ads,System Pool_Global s-pooglo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3f5}@anchor{gnat_rm/the_gnat_library id149}@anchor{3f6}
+@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3f7}@anchor{gnat_rm/the_gnat_library id150}@anchor{3f8}
@section @code{System.Pool_Local} (@code{s-pooloc.ads})
@@ -25313,7 +25373,7 @@ a list of allocated blocks, so that all storage allocated for the pool can
be freed automatically when the pool is finalized.
@node System Restrictions s-restri ads,System Rident s-rident ads,System Pool_Local s-pooloc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id150}@anchor{3f7}@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3f8}
+@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3f9}@anchor{gnat_rm/the_gnat_library id151}@anchor{3fa}
@section @code{System.Restrictions} (@code{s-restri.ads})
@@ -25329,7 +25389,7 @@ compiler determined information on which restrictions
are violated by one or more packages in the partition.
@node System Rident s-rident ads,System Strings Stream_Ops s-ststop ads,System Restrictions s-restri ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{3f9}@anchor{gnat_rm/the_gnat_library id151}@anchor{3fa}
+@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{3fb}@anchor{gnat_rm/the_gnat_library id152}@anchor{3fc}
@section @code{System.Rident} (@code{s-rident.ads})
@@ -25345,7 +25405,7 @@ since the necessary instantiation is included in
package System.Restrictions.
@node System Strings Stream_Ops s-ststop ads,System Unsigned_Types s-unstyp ads,System Rident s-rident ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id152}@anchor{3fb}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{3fc}
+@anchor{gnat_rm/the_gnat_library id153}@anchor{3fd}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{3fe}
@section @code{System.Strings.Stream_Ops} (@code{s-ststop.ads})
@@ -25361,7 +25421,7 @@ stream attributes are applied to string types, but the subprograms in this
package can be used directly by application programs.
@node System Unsigned_Types s-unstyp ads,System Wch_Cnv s-wchcnv ads,System Strings Stream_Ops s-ststop ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{3fd}@anchor{gnat_rm/the_gnat_library id153}@anchor{3fe}
+@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{3ff}@anchor{gnat_rm/the_gnat_library id154}@anchor{400}
@section @code{System.Unsigned_Types} (@code{s-unstyp.ads})
@@ -25374,7 +25434,7 @@ also contains some related definitions for other specialized types
used by the compiler in connection with packed array types.
@node System Wch_Cnv s-wchcnv ads,System Wch_Con s-wchcon ads,System Unsigned_Types s-unstyp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{3ff}@anchor{gnat_rm/the_gnat_library id154}@anchor{400}
+@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{401}@anchor{gnat_rm/the_gnat_library id155}@anchor{402}
@section @code{System.Wch_Cnv} (@code{s-wchcnv.ads})
@@ -25395,7 +25455,7 @@ encoding method. It uses definitions in
package @code{System.Wch_Con}.
@node System Wch_Con s-wchcon ads,,System Wch_Cnv s-wchcnv ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{401}@anchor{gnat_rm/the_gnat_library id155}@anchor{402}
+@anchor{gnat_rm/the_gnat_library id156}@anchor{403}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{404}
@section @code{System.Wch_Con} (@code{s-wchcon.ads})
@@ -25407,7 +25467,7 @@ in ordinary strings. These definitions are used by
the package @code{System.Wch_Cnv}.
@node Interfacing to Other Languages,Specialized Needs Annexes,The GNAT Library,Top
-@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{403}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{404}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{405}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{406}
@chapter Interfacing to Other Languages
@@ -25425,7 +25485,7 @@ provided.
@end menu
@node Interfacing to C,Interfacing to C++,,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{405}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{406}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{407}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{408}
@section Interfacing to C
@@ -25565,7 +25625,7 @@ of the length corresponding to the @code{type'Size} value in Ada.
@end itemize
@node Interfacing to C++,Interfacing to COBOL,Interfacing to C,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{407}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{49}
+@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{409}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{49}
@section Interfacing to C++
@@ -25622,7 +25682,7 @@ The @code{External_Name} is the name of the C++ RTTI symbol. You can then
cover a specific C++ exception in an exception handler.
@node Interfacing to COBOL,Interfacing to Fortran,Interfacing to C++,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{408}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{409}
+@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{40a}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{40b}
@section Interfacing to COBOL
@@ -25630,7 +25690,7 @@ Interfacing to COBOL is achieved as described in section B.4 of
the Ada Reference Manual.
@node Interfacing to Fortran,Interfacing to non-GNAT Ada code,Interfacing to COBOL,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{40a}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{40b}
+@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{40c}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{40d}
@section Interfacing to Fortran
@@ -25640,7 +25700,7 @@ multi-dimensional array causes the array to be stored in column-major
order as required for convenient interface to Fortran.
@node Interfacing to non-GNAT Ada code,,Interfacing to Fortran,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{40c}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{40d}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{40e}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{40f}
@section Interfacing to non-GNAT Ada code
@@ -25664,7 +25724,7 @@ values or simple record types without variants, or simple array
types with fixed bounds.
@node Specialized Needs Annexes,Implementation of Specific Ada Features,Interfacing to Other Languages,Top
-@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{40e}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{40f}
+@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{410}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{411}
@chapter Specialized Needs Annexes
@@ -25705,7 +25765,7 @@ in Ada 2005) is fully implemented.
@end table
@node Implementation of Specific Ada Features,Implementation of Ada 2012 Features,Specialized Needs Annexes,Top
-@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{410}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{411}
+@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{412}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{413}
@chapter Implementation of Specific Ada Features
@@ -25723,7 +25783,7 @@ facilities.
@end menu
@node Machine Code Insertions,GNAT Implementation of Tasking,,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{168}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{412}
+@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{168}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{414}
@section Machine Code Insertions
@@ -25891,7 +25951,7 @@ according to normal visibility rules. In particular if there is no
qualification is required.
@node GNAT Implementation of Tasking,GNAT Implementation of Shared Passive Packages,Machine Code Insertions,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{413}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{414}
+@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{415}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{416}
@section GNAT Implementation of Tasking
@@ -25907,7 +25967,7 @@ to compliance with the Real-Time Systems Annex.
@end menu
@node Mapping Ada Tasks onto the Underlying Kernel Threads,Ensuring Compliance with the Real-Time Annex,,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{415}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{416}
+@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{417}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{418}
@subsection Mapping Ada Tasks onto the Underlying Kernel Threads
@@ -25976,7 +26036,7 @@ support this functionality when the parent contains more than one task.
@geindex Forking a new process
@node Ensuring Compliance with the Real-Time Annex,Support for Locking Policies,Mapping Ada Tasks onto the Underlying Kernel Threads,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{417}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{418}
+@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{419}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{41a}
@subsection Ensuring Compliance with the Real-Time Annex
@@ -26027,7 +26087,7 @@ placed at the end.
@c Support_for_Locking_Policies
@node Support for Locking Policies,,Ensuring Compliance with the Real-Time Annex,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{419}
+@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{41b}
@subsection Support for Locking Policies
@@ -26061,7 +26121,7 @@ then ceiling locking is used.
Otherwise, the @code{Ceiling_Locking} policy is ignored.
@node GNAT Implementation of Shared Passive Packages,Code Generation for Array Aggregates,GNAT Implementation of Tasking,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{41a}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{41b}
+@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{41c}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{41d}
@section GNAT Implementation of Shared Passive Packages
@@ -26162,7 +26222,7 @@ GNAT supports shared passive packages on all platforms
except for OpenVMS.
@node Code Generation for Array Aggregates,The Size of Discriminated Records with Default Discriminants,GNAT Implementation of Shared Passive Packages,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{41c}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{41d}
+@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{41e}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{41f}
@section Code Generation for Array Aggregates
@@ -26193,7 +26253,7 @@ component values and static subtypes also lead to simpler code.
@end menu
@node Static constant aggregates with static bounds,Constant aggregates with unconstrained nominal types,,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{41e}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{41f}
+@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{420}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{421}
@subsection Static constant aggregates with static bounds
@@ -26240,7 +26300,7 @@ Zero2: constant two_dim := (others => (others => 0));
@end example
@node Constant aggregates with unconstrained nominal types,Aggregates with static bounds,Static constant aggregates with static bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{420}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{421}
+@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{422}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{423}
@subsection Constant aggregates with unconstrained nominal types
@@ -26255,7 +26315,7 @@ Cr_Unc : constant One_Unc := (12,24,36);
@end example
@node Aggregates with static bounds,Aggregates with nonstatic bounds,Constant aggregates with unconstrained nominal types,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{422}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{423}
+@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{424}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{425}
@subsection Aggregates with static bounds
@@ -26283,7 +26343,7 @@ end loop;
@end example
@node Aggregates with nonstatic bounds,Aggregates in assignment statements,Aggregates with static bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{424}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{425}
+@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{426}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{427}
@subsection Aggregates with nonstatic bounds
@@ -26294,7 +26354,7 @@ have to be applied to sub-arrays individually, if they do not have statically
compatible subtypes.
@node Aggregates in assignment statements,,Aggregates with nonstatic bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{426}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{427}
+@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{428}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{429}
@subsection Aggregates in assignment statements
@@ -26336,7 +26396,7 @@ a temporary (created either by the front-end or the code generator) and then
that temporary will be copied onto the target.
@node The Size of Discriminated Records with Default Discriminants,Strict Conformance to the Ada Reference Manual,Code Generation for Array Aggregates,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{428}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{429}
+@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{42a}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{42b}
@section The Size of Discriminated Records with Default Discriminants
@@ -26416,7 +26476,7 @@ say) must be consistent, so it is imperative that the object, once created,
remain invariant.
@node Strict Conformance to the Ada Reference Manual,,The Size of Discriminated Records with Default Discriminants,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{42a}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{42b}
+@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{42c}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{42d}
@section Strict Conformance to the Ada Reference Manual
@@ -26443,7 +26503,7 @@ behavior (although at the cost of a significant performance penalty), so
infinite and NaN values are properly generated.
@node Implementation of Ada 2012 Features,Obsolescent Features,Implementation of Specific Ada Features,Top
-@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{42c}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{42d}
+@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{42e}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{42f}
@chapter Implementation of Ada 2012 Features
@@ -28609,7 +28669,7 @@ RM References: H.04 (8/1)
@end itemize
@node Obsolescent Features,Compatibility and Porting Guide,Implementation of Ada 2012 Features,Top
-@anchor{gnat_rm/obsolescent_features id1}@anchor{42e}@anchor{gnat_rm/obsolescent_features doc}@anchor{42f}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
+@anchor{gnat_rm/obsolescent_features id1}@anchor{430}@anchor{gnat_rm/obsolescent_features doc}@anchor{431}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
@chapter Obsolescent Features
@@ -28628,7 +28688,7 @@ compatibility purposes.
@end menu
@node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id2}@anchor{430}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{431}
+@anchor{gnat_rm/obsolescent_features id2}@anchor{432}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{433}
@section pragma No_Run_Time
@@ -28641,7 +28701,7 @@ preferred usage is to use an appropriately configured run-time that
includes just those features that are to be made accessible.
@node pragma Ravenscar,pragma Restricted_Run_Time,pragma No_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id3}@anchor{432}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{433}
+@anchor{gnat_rm/obsolescent_features id3}@anchor{434}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{435}
@section pragma Ravenscar
@@ -28650,7 +28710,7 @@ The pragma @code{Ravenscar} has exactly the same effect as pragma
is part of the new Ada 2005 standard.
@node pragma Restricted_Run_Time,pragma Task_Info,pragma Ravenscar,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{434}@anchor{gnat_rm/obsolescent_features id4}@anchor{435}
+@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{436}@anchor{gnat_rm/obsolescent_features id4}@anchor{437}
@section pragma Restricted_Run_Time
@@ -28660,7 +28720,7 @@ preferred since the Ada 2005 pragma @code{Profile} is intended for
this kind of implementation dependent addition.
@node pragma Task_Info,package System Task_Info s-tasinf ads,pragma Restricted_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{436}@anchor{gnat_rm/obsolescent_features id5}@anchor{437}
+@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{438}@anchor{gnat_rm/obsolescent_features id5}@anchor{439}
@section pragma Task_Info
@@ -28686,7 +28746,7 @@ in the spec of package System.Task_Info in the runtime
library.
@node package System Task_Info s-tasinf ads,,pragma Task_Info,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{438}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{439}
+@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{43a}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{43b}
@section package System.Task_Info (@code{s-tasinf.ads})
@@ -28696,7 +28756,7 @@ to support the @code{Task_Info} pragma. The predefined Ada package
standard replacement for GNAT's @code{Task_Info} functionality.
@node Compatibility and Porting Guide,GNU Free Documentation License,Obsolescent Features,Top
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{43a}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{43b}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{43c}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{43d}
@chapter Compatibility and Porting Guide
@@ -28718,7 +28778,7 @@ applications developed in other Ada environments.
@end menu
@node Writing Portable Fixed-Point Declarations,Compatibility with Ada 83,,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{43c}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{43d}
+@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{43e}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{43f}
@section Writing Portable Fixed-Point Declarations
@@ -28840,7 +28900,7 @@ If you follow this scheme you will be guaranteed that your fixed-point
types will be portable.
@node Compatibility with Ada 83,Compatibility between Ada 95 and Ada 2005,Writing Portable Fixed-Point Declarations,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{43e}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{43f}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{440}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{441}
@section Compatibility with Ada 83
@@ -28868,7 +28928,7 @@ following subsections treat the most likely issues to be encountered.
@end menu
@node Legal Ada 83 programs that are illegal in Ada 95,More deterministic semantics,,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{440}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{441}
+@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{442}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{443}
@subsection Legal Ada 83 programs that are illegal in Ada 95
@@ -28968,7 +29028,7 @@ the fix is usually simply to add the @code{(<>)} to the generic declaration.
@end itemize
@node More deterministic semantics,Changed semantics,Legal Ada 83 programs that are illegal in Ada 95,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{442}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{443}
+@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{444}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{445}
@subsection More deterministic semantics
@@ -28996,7 +29056,7 @@ which open select branches are executed.
@end itemize
@node Changed semantics,Other language compatibility issues,More deterministic semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{444}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{445}
+@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{446}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{447}
@subsection Changed semantics
@@ -29038,7 +29098,7 @@ covers only the restricted range.
@end itemize
@node Other language compatibility issues,,Changed semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{446}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{447}
+@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{448}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{449}
@subsection Other language compatibility issues
@@ -29071,7 +29131,7 @@ include @code{pragma Interface} and the floating point type attributes
@end itemize
@node Compatibility between Ada 95 and Ada 2005,Implementation-dependent characteristics,Compatibility with Ada 83,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{448}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{449}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{44a}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{44b}
@section Compatibility between Ada 95 and Ada 2005
@@ -29143,7 +29203,7 @@ can declare a function returning a value from an anonymous access type.
@end itemize
@node Implementation-dependent characteristics,Compatibility with Other Ada Systems,Compatibility between Ada 95 and Ada 2005,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{44a}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{44b}
+@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{44c}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{44d}
@section Implementation-dependent characteristics
@@ -29166,7 +29226,7 @@ transition from certain Ada 83 compilers.
@end menu
@node Implementation-defined pragmas,Implementation-defined attributes,,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{44c}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{44d}
+@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{44e}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{44f}
@subsection Implementation-defined pragmas
@@ -29188,7 +29248,7 @@ avoiding compiler rejection of units that contain such pragmas; they are not
relevant in a GNAT context and hence are not otherwise implemented.
@node Implementation-defined attributes,Libraries,Implementation-defined pragmas,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{44e}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{44f}
+@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{450}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{451}
@subsection Implementation-defined attributes
@@ -29202,7 +29262,7 @@ Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and
@code{Type_Class}.
@node Libraries,Elaboration order,Implementation-defined attributes,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{450}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{451}
+@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{452}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{453}
@subsection Libraries
@@ -29231,7 +29291,7 @@ be preferable to retrofit the application using modular types.
@end itemize
@node Elaboration order,Target-specific aspects,Libraries,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{452}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{453}
+@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{455}
@subsection Elaboration order
@@ -29267,7 +29327,7 @@ pragmas either globally (as an effect of the @emph{-gnatE} switch) or locally
@end itemize
@node Target-specific aspects,,Elaboration order,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{455}
+@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{457}
@subsection Target-specific aspects
@@ -29280,10 +29340,10 @@ on the robustness of the original design. Moreover, Ada 95 (and thus
Ada 2005 and Ada 2012) are sometimes
incompatible with typical Ada 83 compiler practices regarding implicit
packing, the meaning of the Size attribute, and the size of access values.
-GNAT's approach to these issues is described in @ref{456,,Representation Clauses}.
+GNAT's approach to these issues is described in @ref{458,,Representation Clauses}.
@node Compatibility with Other Ada Systems,Representation Clauses,Implementation-dependent characteristics,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{457}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{458}
+@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{459}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{45a}
@section Compatibility with Other Ada Systems
@@ -29326,7 +29386,7 @@ far beyond this minimal set, as described in the next section.
@end itemize
@node Representation Clauses,Compatibility with HP Ada 83,Compatibility with Other Ada Systems,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{459}
+@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{45b}
@section Representation Clauses
@@ -29419,7 +29479,7 @@ with thin pointers.
@end itemize
@node Compatibility with HP Ada 83,,Representation Clauses,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{45a}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{45b}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{45d}
@section Compatibility with HP Ada 83
@@ -29449,7 +29509,7 @@ extension of package System.
@end itemize
@node GNU Free Documentation License,Index,Compatibility and Porting Guide,Top
-@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{45c}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{45d}
+@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{45e}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{45f}
@chapter GNU Free Documentation License
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 7371a76..e3d6a3a 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -463,6 +463,7 @@ Microsoft Windows Topics
* CONSOLE and WINDOWS subsystems::
* Temporary Files::
* Disabling Command Line Argument Expansion::
+* Windows Socket Timeouts::
* Mixed-Language Programming on Windows::
* Windows Specific Add-Ons::
@@ -532,15 +533,11 @@ Elaboration Order Handling in GNAT
* Checking the Elaboration Order::
* Controlling the Elaboration Order in Ada::
* Controlling the Elaboration Order in GNAT::
-* Common Elaboration-model Traits::
-* Dynamic Elaboration Model in GNAT::
-* Static Elaboration Model in GNAT::
-* SPARK Elaboration Model in GNAT::
-* Legacy Elaboration Model in GNAT::
* Mixing Elaboration Models::
+* ABE Diagnostics::
+* SPARK Diagnostics::
* Elaboration Circularities::
* Resolving Elaboration Circularities::
-* Resolving Task Issues::
* Elaboration-related Compiler Switches::
* Summary of Procedures for Elaboration Control::
* Inspecting the Chosen Elaboration Order::
@@ -6645,8 +6642,9 @@ identifiers with identical name (except casing) will generate compilation
errors (e.g. @code{shm_get} vs @code{SHM_GET}).
@end itemize
-The code generated is using the Ada 2005 syntax, which makes it
-easier to interface with other languages than previous versions of Ada.
+The code is generated using Ada 2012 syntax, which makes it easier to interface
+with other languages. In most cases you can still use the generated binding
+even if your code is compiled using earlier versions of Ada (e.g. @code{-gnat95}).
@menu
* Running the Binding Generator::
@@ -6667,7 +6665,7 @@ header files needed by these files transitively. For example:
@example
$ g++ -c -fdump-ada-spec -C /usr/include/time.h
-$ gcc -c -gnat05 *.ads
+$ gcc -c *.ads
@end example
will generate, under GNU/Linux, the following files: @code{time_h.ads},
@@ -9583,7 +9581,8 @@ checking options to be controlled from the command line.
@item @code{-gnatE}
-Full dynamic elaboration checks.
+Dynamic elaboration checking mode enabled. For further details see
+@ref{f,,Elaboration Order Handling in GNAT}.
@end table
@geindex -gnatf (gcc)
@@ -9649,8 +9648,9 @@ Output usage information. The output is written to @code{stdout}.
@item @code{-gnatH}
-Legacy elaboration-checking mode enabled. When this switch is in effect, the
-pre-18.x access-before-elaboration model becomes the de facto model.
+Legacy elaboration-checking mode enabled. When this switch is in effect,
+the pre-18.x access-before-elaboration model becomes the de facto model.
+For further details see @ref{f,,Elaboration Order Handling in GNAT}.
@end table
@geindex -gnati (gcc)
@@ -9747,7 +9747,8 @@ Select statements
Synchronous task suspension
@end itemize
-and does not emit compile-time diagnostics or run-time checks.
+and does not emit compile-time diagnostics or run-time checks. For further
+details see @ref{f,,Elaboration Order Handling in GNAT}.
@end table
@geindex -gnatk (gcc)
@@ -11039,6 +11040,37 @@ This switch suppresses warnings for assertions where the compiler can tell at
compile time that the assertion will fail.
@end table
+@geindex -gnatw_a
+
+
+@table @asis
+
+@item @code{-gnatw_a}
+
+@emph{Activate warnings on anonymous allocators.}
+
+@geindex Anonymous allocators
+
+This switch activates warnings for allocators of anonymous access types,
+which can involve run-time accessibility checks and lead to unexpected
+accessibility violations. For more details on the rules involved, see
+RM 3.10.2 (14).
+@end table
+
+@geindex -gnatw_A
+
+
+@table @asis
+
+@item @code{-gnatw_A}
+
+@emph{Supress warnings on anonymous allocators.}
+
+@geindex Anonymous allocators
+
+This switch suppresses warnings for anonymous access type allocators.
+@end table
+
@geindex -gnatwb (gcc)
@@ -14283,7 +14315,7 @@ $ gcc -c -gnats x.adb
compiles file @code{x.adb} in syntax-check-only mode. You can check a
series of files in a single command
-, and can use wild cards to specify such a group of files.
+, and can use wildcards to specify such a group of files.
Note that you must specify the @code{-c} (compile
only) flag in addition to the @code{-gnats} flag.
@@ -15745,7 +15777,8 @@ Currently the same as @code{-Ea}.
@item @code{-f@emph{elab-order}}
-Force elaboration order.
+Force elaboration order. For further details see @ref{120,,Elaboration Control}
+and @ref{f,,Elaboration Order Handling in GNAT}.
@end table
@geindex -F (gnatbind)
@@ -15772,22 +15805,41 @@ flag checks are generated.
@item @code{-h}
Output usage (help) information.
+@end table
+
+@geindex -H (gnatbind)
+
+
+@table @asis
+
+@item @code{-H}
+
+Legacy elaboration order model enabled. For further details see
+@ref{f,,Elaboration Order Handling in GNAT}.
+@end table
@geindex -H32 (gnatbind)
+
+@table @asis
+
@item @code{-H32}
Use 32-bit allocations for @code{__gnat_malloc} (and thus for access types).
-For further details see @ref{120,,Dynamic Allocation Control}.
+For further details see @ref{121,,Dynamic Allocation Control}.
+@end table
@geindex -H64 (gnatbind)
@geindex __gnat_malloc
+
+@table @asis
+
@item @code{-H64}
Use 64-bit allocations for @code{__gnat_malloc} (and thus for access types).
-For further details see @ref{120,,Dynamic Allocation Control}.
+For further details see @ref{121,,Dynamic Allocation Control}.
@geindex -I (gnatbind)
@@ -15840,6 +15892,25 @@ limit, then a message is output and the bind is abandoned.
A value of zero means that no limit is enforced. The equal
sign is optional.
+@geindex -minimal (gnatbind)
+
+@item @code{-minimal}
+
+Generate a binder file suitable for space-constrained applications. When
+active, binder-generated objects not required for program operation are no
+longer generated. @strong{Warning:} this option comes with the following
+limitations:
+
+
+@itemize *
+
+@item
+Debugging will not work;
+
+@item
+Programs using GNAT.Compiler_Version will not link.
+@end itemize
+
@geindex -n (gnatbind)
@item @code{-n}
@@ -16017,7 +16088,7 @@ Enable dynamic stack usage, with @code{n} results stored and displayed
at program termination. A result is generated when a task
terminates. Results that can't be stored are displayed on the fly, at
task termination. This option is currently not supported on Itanium
-platforms. (See @ref{121,,Dynamic Stack Usage Analysis} for details.)
+platforms. (See @ref{122,,Dynamic Stack Usage Analysis} for details.)
@geindex -v (gnatbind)
@@ -16086,7 +16157,7 @@ no arguments.
@end menu
@node Consistency-Checking Modes,Binder Error Message Control,,Switches for gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat consistency-checking-modes}@anchor{122}@anchor{gnat_ugn/building_executable_programs_with_gnat id35}@anchor{123}
+@anchor{gnat_ugn/building_executable_programs_with_gnat consistency-checking-modes}@anchor{123}@anchor{gnat_ugn/building_executable_programs_with_gnat id35}@anchor{124}
@subsubsection Consistency-Checking Modes
@@ -16140,7 +16211,7 @@ case the checking against sources has already been performed by
@end table
@node Binder Error Message Control,Elaboration Control,Consistency-Checking Modes,Switches for gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat id36}@anchor{124}@anchor{gnat_ugn/building_executable_programs_with_gnat binder-error-message-control}@anchor{125}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id36}@anchor{125}@anchor{gnat_ugn/building_executable_programs_with_gnat binder-error-message-control}@anchor{126}
@subsubsection Binder Error Message Control
@@ -16250,12 +16321,12 @@ with extreme care.
@end table
@node Elaboration Control,Output Control,Binder Error Message Control,Switches for gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat id37}@anchor{126}@anchor{gnat_ugn/building_executable_programs_with_gnat elaboration-control}@anchor{127}
+@anchor{gnat_ugn/building_executable_programs_with_gnat id37}@anchor{127}@anchor{gnat_ugn/building_executable_programs_with_gnat elaboration-control}@anchor{120}
@subsubsection Elaboration Control
The following switches provide additional control over the elaboration
-order. For full details see @ref{f,,Elaboration Order Handling in GNAT}.
+order. For further details see @ref{f,,Elaboration Order Handling in GNAT}.
@geindex -f (gnatbind)
@@ -16300,30 +16371,38 @@ above forced elaboration order file.
Blank lines and Ada-style comments are ignored. Unit names that do not exist
in the program are ignored. Units in the GNAT predefined library are also
ignored.
+@end table
@geindex -p (gnatbind)
+
+@table @asis
+
@item @code{-p}
-Normally the binder attempts to choose an elaboration order that is
-likely to minimize the likelihood of an elaboration order error resulting
-in raising a @code{Program_Error} exception. This switch reverses the
-action of the binder, and requests that it deliberately choose an order
-that is likely to maximize the likelihood of an elaboration error.
-This is useful in ensuring portability and avoiding dependence on
-accidental fortuitous elaboration ordering.
+Pessimistic elaboration order
-Normally it only makes sense to use the @code{-p}
-switch if dynamic
+This switch is only applicable to the pre-20.x legacy elaboration models.
+The post-20.x elaboration model uses a more informed approach of ordering
+the units.
+
+Normally the binder attempts to choose an elaboration order that is likely to
+minimize the likelihood of an elaboration order error resulting in raising a
+@code{Program_Error} exception. This switch reverses the action of the binder,
+and requests that it deliberately choose an order that is likely to maximize
+the likelihood of an elaboration error. This is useful in ensuring
+portability and avoiding dependence on accidental fortuitous elaboration
+ordering.
+
+Normally it only makes sense to use the @code{-p} switch if dynamic
elaboration checking is used (@code{-gnatE} switch used for compilation).
This is because in the default static elaboration mode, all necessary
@code{Elaborate} and @code{Elaborate_All} pragmas are implicitly inserted.
-These implicit pragmas are still respected by the binder in
-@code{-p} mode, so a
-safe elaboration order is assured.
+These implicit pragmas are still respected by the binder in @code{-p}
+mode, so a safe elaboration order is assured.
-Note that @code{-p} is not intended for
-production use; it is more for debugging/experimental use.
+Note that @code{-p} is not intended for production use; it is more for
+debugging/experimental use.
@end table
@node Output Control,Dynamic Allocation Control,Elaboration Control,Switches for gnatbind
@@ -16408,7 +16487,7 @@ be used to improve code generation in some cases.
@end table
@node Dynamic Allocation Control,Binding with Non-Ada Main Programs,Output Control,Switches for gnatbind
-@anchor{gnat_ugn/building_executable_programs_with_gnat dynamic-allocation-control}@anchor{120}@anchor{gnat_ugn/building_executable_programs_with_gnat id39}@anchor{12a}
+@anchor{gnat_ugn/building_executable_programs_with_gnat dynamic-allocation-control}@anchor{121}@anchor{gnat_ugn/building_executable_programs_with_gnat id39}@anchor{12a}
@subsubsection Dynamic Allocation Control
@@ -18964,7 +19043,7 @@ If you do not specify an extension, it will default to @code{htm}.
@item @code{f}
By default, gnathtml will generate html links only for global entities
-('with'ed units, global variables and types,...). If you specify
+('with'ed units, global variables and types,...). If you specify
@code{-f} on the command line, then links will be generated for local
entities too.
@end table
@@ -23167,7 +23246,7 @@ subprogram whose stack usage might be larger than the specified amount of
bytes. The wording is in keeping with the qualifier documented above.
@node Dynamic Stack Usage Analysis,,Static Stack Usage Analysis,Stack Related Facilities
-@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{121}@anchor{gnat_ugn/gnat_and_program_execution id60}@anchor{1c6}
+@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{122}@anchor{gnat_ugn/gnat_and_program_execution id60}@anchor{1c6}
@subsection Dynamic Stack Usage Analysis
@@ -23900,15 +23979,13 @@ This section describes topics that are specific to the Microsoft Windows
platforms.
-
-
-
@menu
* Using GNAT on Windows::
* Using a network installation of GNAT::
* CONSOLE and WINDOWS subsystems::
* Temporary Files::
* Disabling Command Line Argument Expansion::
+* Windows Socket Timeouts::
* Mixed-Language Programming on Windows::
* Windows Specific Add-Ons::
@@ -24082,7 +24159,7 @@ file will be created. This is particularly useful in networked
environments where you may not have write access to some
directories.
-@node Disabling Command Line Argument Expansion,Mixed-Language Programming on Windows,Temporary Files,Microsoft Windows Topics
+@node Disabling Command Line Argument Expansion,Windows Socket Timeouts,Temporary Files,Microsoft Windows Topics
@anchor{gnat_ugn/platform_specific_information disabling-command-line-argument-expansion}@anchor{1e1}
@subsection Disabling Command Line Argument Expansion
@@ -24153,8 +24230,54 @@ and:
Ada.Command_Line.Argument (1) -> "'*.txt'"
@end example
-@node Mixed-Language Programming on Windows,Windows Specific Add-Ons,Disabling Command Line Argument Expansion,Microsoft Windows Topics
-@anchor{gnat_ugn/platform_specific_information id13}@anchor{1e2}@anchor{gnat_ugn/platform_specific_information mixed-language-programming-on-windows}@anchor{1e3}
+@node Windows Socket Timeouts,Mixed-Language Programming on Windows,Disabling Command Line Argument Expansion,Microsoft Windows Topics
+@anchor{gnat_ugn/platform_specific_information windows-socket-timeouts}@anchor{1e2}
+@subsection Windows Socket Timeouts
+
+
+Microsoft Windows desktops older than @code{8.0} and Microsoft Windows Servers
+older than @code{2019} set a socket timeout 500 milliseconds longer than the value
+set by setsockopt with @code{SO_RCVTIMEO} and @code{SO_SNDTIMEO} options. The GNAT
+runtime makes a correction for the difference in the corresponding Windows
+versions. For Windows Server starting with version @code{2019}, the user must
+provide a manifest file for the GNAT runtime to be able to recognize that
+the Windows version does not need the timeout correction. The manifest file
+should be located in the same directory as the executable file, and its file
+name must match the executable name suffixed by @code{.manifest}. For example,
+if the executable name is @code{sock_wto.exe}, then the manifest file name
+has to be @code{sock_wto.exe.manifest}. The manifest file must contain at
+least the following data:
+
+@example
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+<application>
+ <!-- Windows Vista -->
+ <supportedOS Id="@{e2011457-1546-43c5-a5fe-008deee3d3f0@}"/>
+ <!-- Windows 7 -->
+ <supportedOS Id="@{35138b9a-5d96-4fbd-8e2d-a2440225f93a@}"/>
+ <!-- Windows 8 -->
+ <supportedOS Id="@{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38@}"/>
+ <!-- Windows 8.1 -->
+ <supportedOS Id="@{1f676c76-80e1-4239-95bb-83d0f6d0da78@}"/>
+ <!-- Windows 10 -->
+ <supportedOS Id="@{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a@}"/>
+</application>
+</compatibility>
+</assembly>
+@end example
+
+Without the manifest file, the socket timeout is going to be overcorrected on
+these Windows Server versions and the actual time is going to be 500
+milliseconds shorter than what was set with GNAT.Sockets.Set_Socket_Option.
+Note that on Microsoft Windows versions where correction is necessary, there
+is no way to set a socket timeout shorter than 500 ms. If a socket timeout
+shorter than 500 ms is needed on these Windows versions, a call to
+Check_Selector should be added before any socket read or write operations.
+
+@node Mixed-Language Programming on Windows,Windows Specific Add-Ons,Windows Socket Timeouts,Microsoft Windows Topics
+@anchor{gnat_ugn/platform_specific_information id13}@anchor{1e3}@anchor{gnat_ugn/platform_specific_information mixed-language-programming-on-windows}@anchor{1e4}
@subsection Mixed-Language Programming on Windows
@@ -24176,12 +24299,12 @@ to use the Microsoft tools for your C++ code, you have two choices:
Encapsulate your C++ code in a DLL to be linked with your Ada
application. In this case, use the Microsoft or whatever environment to
build the DLL and use GNAT to build your executable
-(@ref{1e4,,Using DLLs with GNAT}).
+(@ref{1e5,,Using DLLs with GNAT}).
@item
Or you can encapsulate your Ada code in a DLL to be linked with the
other part of your application. In this case, use GNAT to build the DLL
-(@ref{1e5,,Building DLLs with GNAT Project files}) and use the Microsoft
+(@ref{1e6,,Building DLLs with GNAT Project files}) and use the Microsoft
or whatever environment to build your executable.
@end itemize
@@ -24238,7 +24361,7 @@ native SEH support is used.
@end menu
@node Windows Calling Conventions,Introduction to Dynamic Link Libraries DLLs,,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information windows-calling-conventions}@anchor{1e6}@anchor{gnat_ugn/platform_specific_information id14}@anchor{1e7}
+@anchor{gnat_ugn/platform_specific_information windows-calling-conventions}@anchor{1e7}@anchor{gnat_ugn/platform_specific_information id14}@anchor{1e8}
@subsubsection Windows Calling Conventions
@@ -24283,7 +24406,7 @@ are available for Windows:
@end menu
@node C Calling Convention,Stdcall Calling Convention,,Windows Calling Conventions
-@anchor{gnat_ugn/platform_specific_information c-calling-convention}@anchor{1e8}@anchor{gnat_ugn/platform_specific_information id15}@anchor{1e9}
+@anchor{gnat_ugn/platform_specific_information c-calling-convention}@anchor{1e9}@anchor{gnat_ugn/platform_specific_information id15}@anchor{1ea}
@subsubsection @code{C} Calling Convention
@@ -24325,10 +24448,10 @@ is missing, as in the above example, this parameter is set to be the
When importing a variable defined in C, you should always use the @code{C}
calling convention unless the object containing the variable is part of a
DLL (in which case you should use the @code{Stdcall} calling
-convention, @ref{1ea,,Stdcall Calling Convention}).
+convention, @ref{1eb,,Stdcall Calling Convention}).
@node Stdcall Calling Convention,Win32 Calling Convention,C Calling Convention,Windows Calling Conventions
-@anchor{gnat_ugn/platform_specific_information stdcall-calling-convention}@anchor{1ea}@anchor{gnat_ugn/platform_specific_information id16}@anchor{1eb}
+@anchor{gnat_ugn/platform_specific_information stdcall-calling-convention}@anchor{1eb}@anchor{gnat_ugn/platform_specific_information id16}@anchor{1ec}
@subsubsection @code{Stdcall} Calling Convention
@@ -24425,7 +24548,7 @@ Note that to ease building cross-platform bindings this convention
will be handled as a @code{C} calling convention on non-Windows platforms.
@node Win32 Calling Convention,DLL Calling Convention,Stdcall Calling Convention,Windows Calling Conventions
-@anchor{gnat_ugn/platform_specific_information win32-calling-convention}@anchor{1ec}@anchor{gnat_ugn/platform_specific_information id17}@anchor{1ed}
+@anchor{gnat_ugn/platform_specific_information win32-calling-convention}@anchor{1ed}@anchor{gnat_ugn/platform_specific_information id17}@anchor{1ee}
@subsubsection @code{Win32} Calling Convention
@@ -24433,7 +24556,7 @@ This convention, which is GNAT-specific is fully equivalent to the
@code{Stdcall} calling convention described above.
@node DLL Calling Convention,,Win32 Calling Convention,Windows Calling Conventions
-@anchor{gnat_ugn/platform_specific_information id18}@anchor{1ee}@anchor{gnat_ugn/platform_specific_information dll-calling-convention}@anchor{1ef}
+@anchor{gnat_ugn/platform_specific_information id18}@anchor{1ef}@anchor{gnat_ugn/platform_specific_information dll-calling-convention}@anchor{1f0}
@subsubsection @code{DLL} Calling Convention
@@ -24441,7 +24564,7 @@ This convention, which is GNAT-specific is fully equivalent to the
@code{Stdcall} calling convention described above.
@node Introduction to Dynamic Link Libraries DLLs,Using DLLs with GNAT,Windows Calling Conventions,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id19}@anchor{1f0}@anchor{gnat_ugn/platform_specific_information introduction-to-dynamic-link-libraries-dlls}@anchor{1f1}
+@anchor{gnat_ugn/platform_specific_information id19}@anchor{1f1}@anchor{gnat_ugn/platform_specific_information introduction-to-dynamic-link-libraries-dlls}@anchor{1f2}
@subsubsection Introduction to Dynamic Link Libraries (DLLs)
@@ -24525,10 +24648,10 @@ As a side note, an interesting difference between Microsoft DLLs and
Unix shared libraries, is the fact that on most Unix systems all public
routines are exported by default in a Unix shared library, while under
Windows it is possible (but not required) to list exported routines in
-a definition file (see @ref{1f2,,The Definition File}).
+a definition file (see @ref{1f3,,The Definition File}).
@node Using DLLs with GNAT,Building DLLs with GNAT Project files,Introduction to Dynamic Link Libraries DLLs,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id20}@anchor{1f3}@anchor{gnat_ugn/platform_specific_information using-dlls-with-gnat}@anchor{1e4}
+@anchor{gnat_ugn/platform_specific_information id20}@anchor{1f4}@anchor{gnat_ugn/platform_specific_information using-dlls-with-gnat}@anchor{1e5}
@subsubsection Using DLLs with GNAT
@@ -24619,7 +24742,7 @@ example a fictitious DLL called @code{API.dll}.
@end menu
@node Creating an Ada Spec for the DLL Services,Creating an Import Library,,Using DLLs with GNAT
-@anchor{gnat_ugn/platform_specific_information id21}@anchor{1f4}@anchor{gnat_ugn/platform_specific_information creating-an-ada-spec-for-the-dll-services}@anchor{1f5}
+@anchor{gnat_ugn/platform_specific_information id21}@anchor{1f5}@anchor{gnat_ugn/platform_specific_information creating-an-ada-spec-for-the-dll-services}@anchor{1f6}
@subsubsection Creating an Ada Spec for the DLL Services
@@ -24659,7 +24782,7 @@ end API;
@end quotation
@node Creating an Import Library,,Creating an Ada Spec for the DLL Services,Using DLLs with GNAT
-@anchor{gnat_ugn/platform_specific_information id22}@anchor{1f6}@anchor{gnat_ugn/platform_specific_information creating-an-import-library}@anchor{1f7}
+@anchor{gnat_ugn/platform_specific_information id22}@anchor{1f7}@anchor{gnat_ugn/platform_specific_information creating-an-import-library}@anchor{1f8}
@subsubsection Creating an Import Library
@@ -24673,7 +24796,7 @@ as in this case it is possible to link directly against the
DLL. Otherwise read on.
@geindex Definition file
-@anchor{gnat_ugn/platform_specific_information the-definition-file}@anchor{1f2}
+@anchor{gnat_ugn/platform_specific_information the-definition-file}@anchor{1f3}
@subsubheading The Definition File
@@ -24721,17 +24844,17 @@ EXPORTS
@end table
Note that you must specify the correct suffix (@code{@@@emph{nn}})
-(see @ref{1e6,,Windows Calling Conventions}) for a Stdcall
+(see @ref{1e7,,Windows Calling Conventions}) for a Stdcall
calling convention function in the exported symbols list.
There can actually be other sections in a definition file, but these
sections are not relevant to the discussion at hand.
-@anchor{gnat_ugn/platform_specific_information create-def-file-automatically}@anchor{1f8}
+@anchor{gnat_ugn/platform_specific_information create-def-file-automatically}@anchor{1f9}
@subsubheading Creating a Definition File Automatically
You can automatically create the definition file @code{API.def}
-(see @ref{1f2,,The Definition File}) from a DLL.
+(see @ref{1f3,,The Definition File}) from a DLL.
For that use the @code{dlltool} program as follows:
@quotation
@@ -24741,7 +24864,7 @@ $ dlltool API.dll -z API.def --export-all-symbols
@end example
Note that if some routines in the DLL have the @code{Stdcall} convention
-(@ref{1e6,,Windows Calling Conventions}) with stripped @code{@@@emph{nn}}
+(@ref{1e7,,Windows Calling Conventions}) with stripped @code{@@@emph{nn}}
suffix then you'll have to edit @code{api.def} to add it, and specify
@code{-k} to @code{gnatdll} when creating the import library.
@@ -24765,13 +24888,13 @@ tells you what symbol is expected. You just have to go back to the
definition file and add the right suffix.
@end itemize
@end quotation
-@anchor{gnat_ugn/platform_specific_information gnat-style-import-library}@anchor{1f9}
+@anchor{gnat_ugn/platform_specific_information gnat-style-import-library}@anchor{1fa}
@subsubheading GNAT-Style Import Library
To create a static import library from @code{API.dll} with the GNAT tools
you should create the .def file, then use @code{gnatdll} tool
-(see @ref{1fa,,Using gnatdll}) as follows:
+(see @ref{1fb,,Using gnatdll}) as follows:
@quotation
@@ -24787,15 +24910,15 @@ definition file name is @code{xyz.def}, the import library name will
be @code{libxyz.a}. Note that in the previous example option
@code{-e} could have been removed because the name of the definition
file (before the @code{.def} suffix) is the same as the name of the
-DLL (@ref{1fa,,Using gnatdll} for more information about @code{gnatdll}).
+DLL (@ref{1fb,,Using gnatdll} for more information about @code{gnatdll}).
@end quotation
-@anchor{gnat_ugn/platform_specific_information msvs-style-import-library}@anchor{1fb}
+@anchor{gnat_ugn/platform_specific_information msvs-style-import-library}@anchor{1fc}
@subsubheading Microsoft-Style Import Library
A Microsoft import library is needed only if you plan to make an
Ada DLL available to applications developed with Microsoft
-tools (@ref{1e3,,Mixed-Language Programming on Windows}).
+tools (@ref{1e4,,Mixed-Language Programming on Windows}).
To create a Microsoft-style import library for @code{API.dll} you
should create the .def file, then build the actual import library using
@@ -24819,7 +24942,7 @@ See the Microsoft documentation for further details about the usage of
@end quotation
@node Building DLLs with GNAT Project files,Building DLLs with GNAT,Using DLLs with GNAT,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id23}@anchor{1fc}@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat-project-files}@anchor{1e5}
+@anchor{gnat_ugn/platform_specific_information id23}@anchor{1fd}@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat-project-files}@anchor{1e6}
@subsubsection Building DLLs with GNAT Project files
@@ -24835,7 +24958,7 @@ when inside the @code{DllMain} routine which is used for auto-initialization
of shared libraries, so it is not possible to have library level tasks in SALs.
@node Building DLLs with GNAT,Building DLLs with gnatdll,Building DLLs with GNAT Project files,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat}@anchor{1fd}@anchor{gnat_ugn/platform_specific_information id24}@anchor{1fe}
+@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnat}@anchor{1fe}@anchor{gnat_ugn/platform_specific_information id24}@anchor{1ff}
@subsubsection Building DLLs with GNAT
@@ -24866,7 +24989,7 @@ $ gcc -shared -shared-libgcc -o api.dll obj1.o obj2.o ...
It is important to note that in this case all symbols found in the
object files are automatically exported. It is possible to restrict
the set of symbols to export by passing to @code{gcc} a definition
-file (see @ref{1f2,,The Definition File}).
+file (see @ref{1f3,,The Definition File}).
For example:
@example
@@ -24904,7 +25027,7 @@ $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI
@end quotation
@node Building DLLs with gnatdll,Ada DLLs and Finalization,Building DLLs with GNAT,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnatdll}@anchor{1ff}@anchor{gnat_ugn/platform_specific_information id25}@anchor{200}
+@anchor{gnat_ugn/platform_specific_information building-dlls-with-gnatdll}@anchor{200}@anchor{gnat_ugn/platform_specific_information id25}@anchor{201}
@subsubsection Building DLLs with gnatdll
@@ -24912,8 +25035,8 @@ $ gnatmake main -Iapilib -bargs -shared -largs -Lapilib -lAPI
@geindex building
Note that it is preferred to use GNAT Project files
-(@ref{1e5,,Building DLLs with GNAT Project files}) or the built-in GNAT
-DLL support (@ref{1fd,,Building DLLs with GNAT}) or to build DLLs.
+(@ref{1e6,,Building DLLs with GNAT Project files}) or the built-in GNAT
+DLL support (@ref{1fe,,Building DLLs with GNAT}) or to build DLLs.
This section explains how to build DLLs containing Ada code using
@code{gnatdll}. These DLLs will be referred to as Ada DLLs in the
@@ -24929,20 +25052,20 @@ non-Ada applications are as follows:
You need to mark each Ada entity exported by the DLL with a @code{C} or
@code{Stdcall} calling convention to avoid any Ada name mangling for the
entities exported by the DLL
-(see @ref{201,,Exporting Ada Entities}). You can
+(see @ref{202,,Exporting Ada Entities}). You can
skip this step if you plan to use the Ada DLL only from Ada applications.
@item
Your Ada code must export an initialization routine which calls the routine
@code{adainit} generated by @code{gnatbind} to perform the elaboration of
-the Ada code in the DLL (@ref{202,,Ada DLLs and Elaboration}). The initialization
+the Ada code in the DLL (@ref{203,,Ada DLLs and Elaboration}). The initialization
routine exported by the Ada DLL must be invoked by the clients of the DLL
to initialize the DLL.
@item
When useful, the DLL should also export a finalization routine which calls
routine @code{adafinal} generated by @code{gnatbind} to perform the
-finalization of the Ada code in the DLL (@ref{203,,Ada DLLs and Finalization}).
+finalization of the Ada code in the DLL (@ref{204,,Ada DLLs and Finalization}).
The finalization routine exported by the Ada DLL must be invoked by the
clients of the DLL when the DLL services are no further needed.
@@ -24952,11 +25075,11 @@ of the programming languages to which you plan to make the DLL available.
@item
You must provide a definition file listing the exported entities
-(@ref{1f2,,The Definition File}).
+(@ref{1f3,,The Definition File}).
@item
Finally you must use @code{gnatdll} to produce the DLL and the import
-library (@ref{1fa,,Using gnatdll}).
+library (@ref{1fb,,Using gnatdll}).
@end itemize
Note that a relocatable DLL stripped using the @code{strip}
@@ -24976,7 +25099,7 @@ chapter of the @emph{GPRbuild User's Guide}.
@end menu
@node Limitations When Using Ada DLLs from Ada,Exporting Ada Entities,,Building DLLs with gnatdll
-@anchor{gnat_ugn/platform_specific_information limitations-when-using-ada-dlls-from-ada}@anchor{204}
+@anchor{gnat_ugn/platform_specific_information limitations-when-using-ada-dlls-from-ada}@anchor{205}
@subsubsection Limitations When Using Ada DLLs from Ada
@@ -24997,7 +25120,7 @@ It is completely safe to exchange plain elementary, array or record types,
Windows object handles, etc.
@node Exporting Ada Entities,Ada DLLs and Elaboration,Limitations When Using Ada DLLs from Ada,Building DLLs with gnatdll
-@anchor{gnat_ugn/platform_specific_information exporting-ada-entities}@anchor{201}@anchor{gnat_ugn/platform_specific_information id26}@anchor{205}
+@anchor{gnat_ugn/platform_specific_information exporting-ada-entities}@anchor{202}@anchor{gnat_ugn/platform_specific_information id26}@anchor{206}
@subsubsection Exporting Ada Entities
@@ -25097,10 +25220,10 @@ end API;
Note that if you do not export the Ada entities with a @code{C} or
@code{Stdcall} convention you will have to provide the mangled Ada names
in the definition file of the Ada DLL
-(@ref{206,,Creating the Definition File}).
+(@ref{207,,Creating the Definition File}).
@node Ada DLLs and Elaboration,,Exporting Ada Entities,Building DLLs with gnatdll
-@anchor{gnat_ugn/platform_specific_information ada-dlls-and-elaboration}@anchor{202}@anchor{gnat_ugn/platform_specific_information id27}@anchor{207}
+@anchor{gnat_ugn/platform_specific_information ada-dlls-and-elaboration}@anchor{203}@anchor{gnat_ugn/platform_specific_information id27}@anchor{208}
@subsubsection Ada DLLs and Elaboration
@@ -25118,7 +25241,7 @@ the Ada elaboration routine @code{adainit} generated by the GNAT binder
(@ref{b4,,Binding with Non-Ada Main Programs}). See the body of
@code{Initialize_Api} for an example. Note that the GNAT binder is
automatically invoked during the DLL build process by the @code{gnatdll}
-tool (@ref{1fa,,Using gnatdll}).
+tool (@ref{1fb,,Using gnatdll}).
When a DLL is loaded, Windows systematically invokes a routine called
@code{DllMain}. It would therefore be possible to call @code{adainit}
@@ -25131,7 +25254,7 @@ time), which means that the GNAT run-time will deadlock waiting for the
newly created task to complete its initialization.
@node Ada DLLs and Finalization,Creating a Spec for Ada DLLs,Building DLLs with gnatdll,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id28}@anchor{208}@anchor{gnat_ugn/platform_specific_information ada-dlls-and-finalization}@anchor{203}
+@anchor{gnat_ugn/platform_specific_information id28}@anchor{209}@anchor{gnat_ugn/platform_specific_information ada-dlls-and-finalization}@anchor{204}
@subsubsection Ada DLLs and Finalization
@@ -25146,10 +25269,10 @@ routine @code{adafinal} generated by the GNAT binder
See the body of @code{Finalize_Api} for an
example. As already pointed out the GNAT binder is automatically invoked
during the DLL build process by the @code{gnatdll} tool
-(@ref{1fa,,Using gnatdll}).
+(@ref{1fb,,Using gnatdll}).
@node Creating a Spec for Ada DLLs,GNAT and Windows Resources,Ada DLLs and Finalization,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id29}@anchor{209}@anchor{gnat_ugn/platform_specific_information creating-a-spec-for-ada-dlls}@anchor{20a}
+@anchor{gnat_ugn/platform_specific_information id29}@anchor{20a}@anchor{gnat_ugn/platform_specific_information creating-a-spec-for-ada-dlls}@anchor{20b}
@subsubsection Creating a Spec for Ada DLLs
@@ -25207,7 +25330,7 @@ end API;
@end menu
@node Creating the Definition File,Using gnatdll,,Creating a Spec for Ada DLLs
-@anchor{gnat_ugn/platform_specific_information creating-the-definition-file}@anchor{206}@anchor{gnat_ugn/platform_specific_information id30}@anchor{20b}
+@anchor{gnat_ugn/platform_specific_information creating-the-definition-file}@anchor{207}@anchor{gnat_ugn/platform_specific_information id30}@anchor{20c}
@subsubsection Creating the Definition File
@@ -25243,7 +25366,7 @@ EXPORTS
@end quotation
@node Using gnatdll,,Creating the Definition File,Creating a Spec for Ada DLLs
-@anchor{gnat_ugn/platform_specific_information using-gnatdll}@anchor{1fa}@anchor{gnat_ugn/platform_specific_information id31}@anchor{20c}
+@anchor{gnat_ugn/platform_specific_information using-gnatdll}@anchor{1fb}@anchor{gnat_ugn/platform_specific_information id31}@anchor{20d}
@subsubsection Using @code{gnatdll}
@@ -25454,7 +25577,7 @@ asks @code{gnatlink} to generate the routines @code{DllMain} and
is loaded into memory.
@item
-@code{gnatdll} uses @code{dlltool} (see @ref{20d,,Using dlltool}) to build the
+@code{gnatdll} uses @code{dlltool} (see @ref{20e,,Using dlltool}) to build the
export table (@code{api.exp}). The export table contains the relocation
information in a form which can be used during the final link to ensure
that the Windows loader is able to place the DLL anywhere in memory.
@@ -25493,7 +25616,7 @@ $ gnatbind -n api
$ gnatlink api api.exp -o api.dll -mdll
@end example
@end itemize
-@anchor{gnat_ugn/platform_specific_information using-dlltool}@anchor{20d}
+@anchor{gnat_ugn/platform_specific_information using-dlltool}@anchor{20e}
@subsubheading Using @code{dlltool}
@@ -25552,7 +25675,7 @@ DLL in the static import library generated by @code{dlltool} with switch
@item @code{-k}
Kill @code{@@@emph{nn}} from exported names
-(@ref{1e6,,Windows Calling Conventions}
+(@ref{1e7,,Windows Calling Conventions}
for a discussion about @code{Stdcall}-style symbols.
@end table
@@ -25608,7 +25731,7 @@ Use @code{assembler-name} as the assembler. The default is @code{as}.
@end table
@node GNAT and Windows Resources,Using GNAT DLLs from Microsoft Visual Studio Applications,Creating a Spec for Ada DLLs,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information gnat-and-windows-resources}@anchor{20e}@anchor{gnat_ugn/platform_specific_information id32}@anchor{20f}
+@anchor{gnat_ugn/platform_specific_information gnat-and-windows-resources}@anchor{20f}@anchor{gnat_ugn/platform_specific_information id32}@anchor{210}
@subsubsection GNAT and Windows Resources
@@ -25703,7 +25826,7 @@ the corresponding Microsoft documentation.
@end menu
@node Building Resources,Compiling Resources,,GNAT and Windows Resources
-@anchor{gnat_ugn/platform_specific_information building-resources}@anchor{210}@anchor{gnat_ugn/platform_specific_information id33}@anchor{211}
+@anchor{gnat_ugn/platform_specific_information building-resources}@anchor{211}@anchor{gnat_ugn/platform_specific_information id33}@anchor{212}
@subsubsection Building Resources
@@ -25723,7 +25846,7 @@ complete description of the resource script language can be found in the
Microsoft documentation.
@node Compiling Resources,Using Resources,Building Resources,GNAT and Windows Resources
-@anchor{gnat_ugn/platform_specific_information compiling-resources}@anchor{212}@anchor{gnat_ugn/platform_specific_information id34}@anchor{213}
+@anchor{gnat_ugn/platform_specific_information compiling-resources}@anchor{213}@anchor{gnat_ugn/platform_specific_information id34}@anchor{214}
@subsubsection Compiling Resources
@@ -25765,7 +25888,7 @@ $ windres -i myres.res -o myres.o
@end quotation
@node Using Resources,,Compiling Resources,GNAT and Windows Resources
-@anchor{gnat_ugn/platform_specific_information using-resources}@anchor{214}@anchor{gnat_ugn/platform_specific_information id35}@anchor{215}
+@anchor{gnat_ugn/platform_specific_information using-resources}@anchor{215}@anchor{gnat_ugn/platform_specific_information id35}@anchor{216}
@subsubsection Using Resources
@@ -25785,7 +25908,7 @@ $ gnatmake myprog -largs myres.o
@end quotation
@node Using GNAT DLLs from Microsoft Visual Studio Applications,Debugging a DLL,GNAT and Windows Resources,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information using-gnat-dll-from-msvs}@anchor{216}@anchor{gnat_ugn/platform_specific_information using-gnat-dlls-from-microsoft-visual-studio-applications}@anchor{217}
+@anchor{gnat_ugn/platform_specific_information using-gnat-dll-from-msvs}@anchor{217}@anchor{gnat_ugn/platform_specific_information using-gnat-dlls-from-microsoft-visual-studio-applications}@anchor{218}
@subsubsection Using GNAT DLLs from Microsoft Visual Studio Applications
@@ -25819,7 +25942,7 @@ $ gprbuild -p mylib.gpr
@item
Produce a .def file for the symbols you need to interface with, either by
hand or automatically with possibly some manual adjustments
-(see @ref{1f8,,Creating Definition File Automatically}):
+(see @ref{1f9,,Creating Definition File Automatically}):
@end enumerate
@quotation
@@ -25836,7 +25959,7 @@ $ dlltool libmylib.dll -z libmylib.def --export-all-symbols
Make sure that MSVS command-line tools are accessible on the path.
@item
-Create the Microsoft-style import library (see @ref{1fb,,MSVS-Style Import Library}):
+Create the Microsoft-style import library (see @ref{1fc,,MSVS-Style Import Library}):
@end enumerate
@quotation
@@ -25878,7 +26001,7 @@ or copy the DLL into into the directory containing the .exe.
@end enumerate
@node Debugging a DLL,Setting Stack Size from gnatlink,Using GNAT DLLs from Microsoft Visual Studio Applications,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information id36}@anchor{218}@anchor{gnat_ugn/platform_specific_information debugging-a-dll}@anchor{219}
+@anchor{gnat_ugn/platform_specific_information id36}@anchor{219}@anchor{gnat_ugn/platform_specific_information debugging-a-dll}@anchor{21a}
@subsubsection Debugging a DLL
@@ -25916,7 +26039,7 @@ tools suite used to build the DLL.
@end menu
@node Program and DLL Both Built with GCC/GNAT,Program Built with Foreign Tools and DLL Built with GCC/GNAT,,Debugging a DLL
-@anchor{gnat_ugn/platform_specific_information id37}@anchor{21a}@anchor{gnat_ugn/platform_specific_information program-and-dll-both-built-with-gcc-gnat}@anchor{21b}
+@anchor{gnat_ugn/platform_specific_information id37}@anchor{21b}@anchor{gnat_ugn/platform_specific_information program-and-dll-both-built-with-gcc-gnat}@anchor{21c}
@subsubsection Program and DLL Both Built with GCC/GNAT
@@ -25926,7 +26049,7 @@ the process. Let's suppose here that the main procedure is named
@code{ada_main} and that in the DLL there is an entry point named
@code{ada_dll}.
-The DLL (@ref{1f1,,Introduction to Dynamic Link Libraries (DLLs)}) and
+The DLL (@ref{1f2,,Introduction to Dynamic Link Libraries (DLLs)}) and
program must have been built with the debugging information (see GNAT -g
switch). Here are the step-by-step instructions for debugging it:
@@ -25966,7 +26089,7 @@ you can use the standard approach to debug the whole program
(@ref{24,,Running and Debugging Ada Programs}).
@node Program Built with Foreign Tools and DLL Built with GCC/GNAT,,Program and DLL Both Built with GCC/GNAT,Debugging a DLL
-@anchor{gnat_ugn/platform_specific_information program-built-with-foreign-tools-and-dll-built-with-gcc-gnat}@anchor{21c}@anchor{gnat_ugn/platform_specific_information id38}@anchor{21d}
+@anchor{gnat_ugn/platform_specific_information program-built-with-foreign-tools-and-dll-built-with-gcc-gnat}@anchor{21d}@anchor{gnat_ugn/platform_specific_information id38}@anchor{21e}
@subsubsection Program Built with Foreign Tools and DLL Built with GCC/GNAT
@@ -25983,7 +26106,7 @@ example some C code built with Microsoft Visual C) and that there is a
DLL named @code{test.dll} containing an Ada entry point named
@code{ada_dll}.
-The DLL (see @ref{1f1,,Introduction to Dynamic Link Libraries (DLLs)}) must have
+The DLL (see @ref{1f2,,Introduction to Dynamic Link Libraries (DLLs)}) must have
been built with debugging information (see the GNAT @code{-g} option).
@subsubheading Debugging the DLL Directly
@@ -26122,7 +26245,7 @@ approach to debug a program as described in
@ref{24,,Running and Debugging Ada Programs}.
@node Setting Stack Size from gnatlink,Setting Heap Size from gnatlink,Debugging a DLL,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information setting-stack-size-from-gnatlink}@anchor{136}@anchor{gnat_ugn/platform_specific_information id39}@anchor{21e}
+@anchor{gnat_ugn/platform_specific_information setting-stack-size-from-gnatlink}@anchor{136}@anchor{gnat_ugn/platform_specific_information id39}@anchor{21f}
@subsubsection Setting Stack Size from @code{gnatlink}
@@ -26165,7 +26288,7 @@ because the comma is a separator for this option.
@end itemize
@node Setting Heap Size from gnatlink,,Setting Stack Size from gnatlink,Mixed-Language Programming on Windows
-@anchor{gnat_ugn/platform_specific_information setting-heap-size-from-gnatlink}@anchor{137}@anchor{gnat_ugn/platform_specific_information id40}@anchor{21f}
+@anchor{gnat_ugn/platform_specific_information setting-heap-size-from-gnatlink}@anchor{137}@anchor{gnat_ugn/platform_specific_information id40}@anchor{220}
@subsubsection Setting Heap Size from @code{gnatlink}
@@ -26198,7 +26321,7 @@ because the comma is a separator for this option.
@end itemize
@node Windows Specific Add-Ons,,Mixed-Language Programming on Windows,Microsoft Windows Topics
-@anchor{gnat_ugn/platform_specific_information windows-specific-add-ons}@anchor{220}@anchor{gnat_ugn/platform_specific_information win32-specific-addons}@anchor{221}
+@anchor{gnat_ugn/platform_specific_information windows-specific-add-ons}@anchor{221}@anchor{gnat_ugn/platform_specific_information win32-specific-addons}@anchor{222}
@subsection Windows Specific Add-Ons
@@ -26211,7 +26334,7 @@ This section describes the Windows specific add-ons.
@end menu
@node Win32Ada,wPOSIX,,Windows Specific Add-Ons
-@anchor{gnat_ugn/platform_specific_information win32ada}@anchor{222}@anchor{gnat_ugn/platform_specific_information id41}@anchor{223}
+@anchor{gnat_ugn/platform_specific_information win32ada}@anchor{223}@anchor{gnat_ugn/platform_specific_information id41}@anchor{224}
@subsubsection Win32Ada
@@ -26242,7 +26365,7 @@ gprbuild p.gpr
@end quotation
@node wPOSIX,,Win32Ada,Windows Specific Add-Ons
-@anchor{gnat_ugn/platform_specific_information id42}@anchor{224}@anchor{gnat_ugn/platform_specific_information wposix}@anchor{225}
+@anchor{gnat_ugn/platform_specific_information id42}@anchor{225}@anchor{gnat_ugn/platform_specific_information wposix}@anchor{226}
@subsubsection wPOSIX
@@ -26275,7 +26398,7 @@ gprbuild p.gpr
@end quotation
@node Mac OS Topics,,Microsoft Windows Topics,Platform-Specific Information
-@anchor{gnat_ugn/platform_specific_information mac-os-topics}@anchor{2d}@anchor{gnat_ugn/platform_specific_information id43}@anchor{226}
+@anchor{gnat_ugn/platform_specific_information mac-os-topics}@anchor{2d}@anchor{gnat_ugn/platform_specific_information id43}@anchor{227}
@section Mac OS Topics
@@ -26290,7 +26413,7 @@ platform.
@end menu
@node Codesigning the Debugger,,,Mac OS Topics
-@anchor{gnat_ugn/platform_specific_information codesigning-the-debugger}@anchor{227}
+@anchor{gnat_ugn/platform_specific_information codesigning-the-debugger}@anchor{228}
@subsection Codesigning the Debugger
@@ -26371,7 +26494,7 @@ the location where you installed GNAT. Also, be sure that users are
in the Unix group @code{_developer}.
@node Example of Binder Output File,Elaboration Order Handling in GNAT,Platform-Specific Information,Top
-@anchor{gnat_ugn/example_of_binder_output example-of-binder-output-file}@anchor{e}@anchor{gnat_ugn/example_of_binder_output doc}@anchor{228}@anchor{gnat_ugn/example_of_binder_output id1}@anchor{229}
+@anchor{gnat_ugn/example_of_binder_output example-of-binder-output-file}@anchor{e}@anchor{gnat_ugn/example_of_binder_output doc}@anchor{229}@anchor{gnat_ugn/example_of_binder_output id1}@anchor{22a}
@chapter Example of Binder Output File
@@ -27123,7 +27246,7 @@ elaboration code in your own application).
@c -- Example: A |withing| unit has a |with| clause, it |withs| a |withed| unit
@node Elaboration Order Handling in GNAT,Inline Assembler,Example of Binder Output File,Top
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order-handling-in-gnat}@anchor{f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat doc}@anchor{22a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id1}@anchor{22b}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order-handling-in-gnat}@anchor{f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat doc}@anchor{22b}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id1}@anchor{22c}
@chapter Elaboration Order Handling in GNAT
@@ -27141,15 +27264,11 @@ GNAT, either automatically or with explicit programming features.
* Checking the Elaboration Order::
* Controlling the Elaboration Order in Ada::
* Controlling the Elaboration Order in GNAT::
-* Common Elaboration-model Traits::
-* Dynamic Elaboration Model in GNAT::
-* Static Elaboration Model in GNAT::
-* SPARK Elaboration Model in GNAT::
-* Legacy Elaboration Model in GNAT::
* Mixing Elaboration Models::
+* ABE Diagnostics::
+* SPARK Diagnostics::
* Elaboration Circularities::
* Resolving Elaboration Circularities::
-* Resolving Task Issues::
* Elaboration-related Compiler Switches::
* Summary of Procedures for Elaboration Control::
* Inspecting the Chosen Elaboration Order::
@@ -27157,7 +27276,7 @@ GNAT, either automatically or with explicit programming features.
@end menu
@node Elaboration Code,Elaboration Order,,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-code}@anchor{22c}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id2}@anchor{22d}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-code}@anchor{22d}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id2}@anchor{22e}
@section Elaboration Code
@@ -27197,9 +27316,15 @@ In addition to the Ada terminology, this appendix defines the following terms:
@itemize *
@item
+@emph{Invocation}
+
+The act of calling a subprogram, instantiating a generic, or activating a
+task.
+
+@item
@emph{Scenario}
-A construct that is elaborated or executed by elaboration code is referred to
+A construct that is elaborated or invoked by elaboration code is referred to
as an @emph{elaboration scenario} or simply a @strong{scenario}. GNAT recognizes the
following scenarios:
@@ -27271,7 +27396,7 @@ end Client;
In the example above, the call to @code{Server.Func} is an elaboration scenario
because it appears at the library level of package @code{Client}. Note that the
declaration of package @code{Nested} is ignored according to the definition
-given above. As a result, the call to @code{Server.Func} will be executed when
+given above. As a result, the call to @code{Server.Func} will be invoked when
the spec of unit @code{Client} is elaborated.
@item
@@ -27294,12 +27419,12 @@ end Client;
In the example above, the call to @code{Proc} is an elaboration scenario because
it appears within the statement sequence of package body @code{Client}. As a
-result, the call to @code{Proc} will be executed when the body of @code{Client} is
+result, the call to @code{Proc} will be invoked when the body of @code{Client} is
elaborated.
@end itemize
@node Elaboration Order,Checking the Elaboration Order,Elaboration Code,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order}@anchor{22e}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id3}@anchor{22f}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-order}@anchor{22f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id3}@anchor{230}
@section Elaboration Order
@@ -27308,6 +27433,8 @@ executed is referred to as @strong{elaboration order}.
Within a single unit, elaboration code is executed in sequential order.
+@quotation
+
@example
package body Client is
Result : ... := Server.Func;
@@ -27321,6 +27448,7 @@ begin
Proc;
end Client;
@end example
+@end quotation
In the example above, the elaboration order within package body @code{Client} is
as follows:
@@ -27368,17 +27496,25 @@ factors:
@emph{with}ed units
@item
+parent units
+
+@item
purity of units
@item
preelaborability of units
@item
-presence of elaboration control pragmas
+presence of elaboration-control pragmas
+
+@item
+invocations performed in elaboration code
@end itemize
A program may have several elaboration orders depending on its structure.
+@quotation
+
@example
package Server is
function Func (Index : Integer) return Integer;
@@ -27407,16 +27543,20 @@ end Client;
with Client;
procedure Main is begin null; end Main;
@end example
+@end quotation
The following elaboration order exhibits a fundamental problem referred to as
@emph{access-before-elaboration} or simply @strong{ABE}.
+@quotation
+
@example
spec of Server
spec of Client
body of Server
body of Main
@end example
+@end quotation
The elaboration of @code{Server}'s spec materializes function @code{Func}, making it
callable. The elaboration of @code{Client}'s spec elaborates the declaration of
@@ -27434,26 +27574,30 @@ vein as index or null exclusion checks. A failed ABE check raises exception
The following elaboration order avoids the ABE problem and the program can be
successfully elaborated.
+@quotation
+
@example
spec of Server
body of Server
spec of Client
body of Main
@end example
+@end quotation
Ada states that a total elaboration order must exist, but it does not define
what this order is. A compiler is thus tasked with choosing a suitable
elaboration order which satisfies the dependencies imposed by @emph{with} clauses,
-unit categorization, and elaboration control pragmas. Ideally an order which
-avoids ABE problems should be chosen, however a compiler may not always find
-such an order due to complications with respect to control and data flow.
+unit categorization, elaboration-control pragmas, and invocations performed in
+elaboration code. Ideally an order that avoids ABE problems should be chosen,
+however a compiler may not always find such an order due to complications with
+respect to control and data flow.
@node Checking the Elaboration Order,Controlling the Elaboration Order in Ada,Elaboration Order,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id4}@anchor{230}@anchor{gnat_ugn/elaboration_order_handling_in_gnat checking-the-elaboration-order}@anchor{231}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id4}@anchor{231}@anchor{gnat_ugn/elaboration_order_handling_in_gnat checking-the-elaboration-order}@anchor{232}
@section Checking the Elaboration Order
-To avoid placing the entire elaboration order burden on the programmer, Ada
+To avoid placing the entire elaboration-order burden on the programmer, Ada
provides three lines of defense:
@@ -27471,7 +27615,7 @@ always elaborated prior to Client. The same principle applies to child units
@emph{Dynamic semantics}
Dynamic checks are performed at run time, to ensure that a target is
-elaborated prior to a scenario that executes it, thus avoiding ABE problems.
+elaborated prior to a scenario that invokes it, thus avoiding ABE problems.
A failed run-time check raises exception @code{Program_Error}. The following
restrictions apply:
@@ -27500,8 +27644,7 @@ associated task type has been elaborated.
The restrictions above can be summarized by the following rule:
@emph{If a target has a body, then this body must be elaborated prior to the
-execution of the scenario that invokes, instantiates, or activates the
-target.}
+scenario that invokes the target.}
@item
@emph{Elaboration control}
@@ -27511,7 +27654,7 @@ order.
@end itemize
@node Controlling the Elaboration Order in Ada,Controlling the Elaboration Order in GNAT,Checking the Elaboration Order,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-ada}@anchor{232}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id5}@anchor{233}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-ada}@anchor{233}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id5}@anchor{234}
@section Controlling the Elaboration Order in Ada
@@ -27577,7 +27720,7 @@ but still strong enough to prevent ABE problems within a unit.
Pragma @code{Elaborate_Body} requires that the body of a unit is elaborated
immediately after its spec. This restriction guarantees that no client
-scenario can execute a server target before the target body has been
+scenario can invoke a server target before the target body has been
elaborated because the spec and body are effectively "glued" together.
@example
@@ -27777,7 +27920,7 @@ Note that there are several allowable suborders for the specs and bodies of
be elaborated prior to @code{Client}.
Removing pragma @code{Elaborate_All} could result in the following incorrect
-elaboration order
+elaboration order:
@example
spec of Math
@@ -27838,8 +27981,8 @@ Note that one additional advantage of using @code{Elaborate} and @code{Elaborate
is that the program continues to stay in the last state (one or more correct
orders exist) even if maintenance changes the bodies of targets.
-@node Controlling the Elaboration Order in GNAT,Common Elaboration-model Traits,Controlling the Elaboration Order in Ada,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id6}@anchor{234}@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-gnat}@anchor{235}
+@node Controlling the Elaboration Order in GNAT,Mixing Elaboration Models,Controlling the Elaboration Order in Ada,Elaboration Order Handling in GNAT
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id6}@anchor{235}@anchor{gnat_ugn/elaboration_order_handling_in_gnat controlling-the-elaboration-order-in-gnat}@anchor{236}
@section Controlling the Elaboration Order in GNAT
@@ -27855,12 +27998,34 @@ elaboration order and to diagnose elaboration problems.
@item
@emph{Dynamic elaboration model}
-This is the most permissive of the three elaboration models. When the
-dynamic model is in effect, GNAT assumes that all code within all units in
-a partition is elaboration code. GNAT performs very few diagnostics and
-generates run-time checks to verify the elaboration order of a program. This
-behavior is identical to that specified by the Ada Reference Manual. The
-dynamic model is enabled with compiler switch @code{-gnatE}.
+This is the most permissive of the three elaboration models and emulates the
+behavior specified by the Ada Reference Manual. When the dynamic model is in
+effect, GNAT makes the following assumptions:
+
+
+@itemize -
+
+@item
+All code within all units in a partition is considered to be elaboration
+code.
+
+@item
+Some of the invocations in elaboration code may not take place at run time
+due to conditional execution.
+@end itemize
+
+GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
+that invoke internal targets. In addition, GNAT generates run-time checks for
+all external targets and for all scenarios that may exhibit ABE problems.
+
+The elaboration order is obtained by honoring all @emph{with} clauses, purity and
+preelaborability of units, and elaboration-control pragmas. The dynamic model
+attempts to take all invocations in elaboration code into account. If an
+invocation leads to a circularity, GNAT ignores the invocation based on the
+assumptions stated above. An order obtained using the dynamic model may fail
+an ABE check at run time when GNAT ignored an invocation.
+
+The dynamic model is enabled with compiler switch @code{-gnatE}.
@end itemize
@geindex Static elaboration model
@@ -27872,12 +28037,31 @@ dynamic model is enabled with compiler switch @code{-gnatE}.
@emph{Static elaboration model}
This is the middle ground of the three models. When the static model is in
-effect, GNAT performs extensive diagnostics on a unit-by-unit basis for all
-scenarios that elaborate or execute internal targets. GNAT also generates
-run-time checks for all external targets and for all scenarios that may
-exhibit ABE problems. Finally, GNAT installs implicit @code{Elaborate} and
-@code{Elaborate_All} pragmas for server units based on the dependencies of
-client units. The static model is the default model in GNAT.
+effect, GNAT makes the following assumptions:
+
+
+@itemize -
+
+@item
+Only code at the library level and in package body statements within all
+units in a partition is considered to be elaboration code.
+
+@item
+All invocations in elaboration will take place at run time, regardless of
+conditional execution.
+@end itemize
+
+GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
+that invoke internal targets. In addition, GNAT generates run-time checks for
+all external targets and for all scenarios that may exhibit ABE problems.
+
+The elaboration order is obtained by honoring all @emph{with} clauses, purity and
+preelaborability of units, presence of elaboration-control pragmas, and all
+invocations in elaboration code. An order obtained using the static model is
+guaranteed to be ABE problem-free, excluding dispatching calls and
+access-to-subprogram types.
+
+The static model is the default model in GNAT.
@end itemize
@geindex SPARK elaboration model
@@ -27891,21 +28075,34 @@ client units. The static model is the default model in GNAT.
This is the most conservative of the three models and enforces the SPARK
rules of elaboration as defined in the SPARK Reference Manual, section 7.7.
The SPARK model is in effect only when a scenario and a target reside in a
-region subject to SPARK_Mode On, otherwise the dynamic or static model is in
-effect.
+region subject to @code{SPARK_Mode On}, otherwise the dynamic or static model
+is in effect.
+
+The SPARK model is enabled with compiler switch @code{-gnatd.v}.
@end itemize
-@geindex Legacy elaboration model
+@geindex Legacy elaboration models
@itemize *
@item
-@emph{Legacy elaboration model}
+@emph{Legacy elaboration models}
In addition to the three elaboration models outlined above, GNAT provides the
-elaboration model of pre-18.x versions referred to as @cite{legacy elaboration model}. The legacy elaboration model is enabled with compiler switch
-@code{-gnatH}.
+following legacy models:
+
+
+@itemize -
+
+@item
+@cite{Legacy elaboration-checking model} available in pre-18.x versions of GNAT.
+This model is enabled with compiler switch @code{-gnatH}.
+
+@item
+@cite{Legacy elaboration-order model} available in pre-20.x versions of GNAT.
+This model is enabled with binder switch @code{-H}.
+@end itemize
@end itemize
@geindex Relaxed elaboration mode
@@ -27914,32 +28111,72 @@ The dynamic, legacy, and static models can be relaxed using compiler switch
@code{-gnatJ}, making them more permissive. Note that in this mode, GNAT
may not diagnose certain elaboration issues or install run-time checks.
-@node Common Elaboration-model Traits,Dynamic Elaboration Model in GNAT,Controlling the Elaboration Order in GNAT,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat common-elaboration-model-traits}@anchor{236}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id7}@anchor{237}
-@section Common Elaboration-model Traits
+@node Mixing Elaboration Models,ABE Diagnostics,Controlling the Elaboration Order in GNAT,Elaboration Order Handling in GNAT
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat mixing-elaboration-models}@anchor{237}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id7}@anchor{238}
+@section Mixing Elaboration Models
-All three GNAT models are able to detect elaboration problems related to
-dispatching calls and a particular kind of ABE referred to as @emph{guaranteed ABE}.
+It is possible to mix units compiled with a different elaboration model,
+however the following rules must be observed:
@itemize *
@item
-@emph{Dispatching calls}
+A client unit compiled with the dynamic model can only @emph{with} a server unit
+that meets at least one of the following criteria:
+
+
+@itemize -
+
+@item
+The server unit is compiled with the dynamic model.
-GNAT installs run-time checks for each primitive subprogram of each tagged
-type defined in a partition on the assumption that a dispatching call
-invoked at elaboration time will execute one of these primitives. As a
-result, a dispatching call that executes a primitive whose body has not
-been elaborated yet will raise exception @code{Program_Error} at run time. The
-checks can be suppressed using pragma @code{Suppress (Elaboration_Check)}.
+@item
+The server unit is a GNAT implementation unit from the @code{Ada}, @code{GNAT},
+@code{Interfaces}, or @code{System} hierarchies.
+
+@item
+The server unit has pragma @code{Pure} or @code{Preelaborate}.
@item
-@emph{Guaranteed ABE}
+The client unit has an explicit @code{Elaborate_All} pragma for the server
+unit.
+@end itemize
+@end itemize
+
+These rules ensure that elaboration checks are not omitted. If the rules are
+violated, the binder emits a warning:
-A guaranteed ABE arises when the body of a target is not elaborated early
-enough, and causes all scenarios that directly execute the target to fail.
+@quotation
+
+@example
+warning: "x.ads" has dynamic elaboration checks and with's
+warning: "y.ads" which has static elaboration checks
+@end example
+@end quotation
+
+The warnings can be suppressed by binder switch @code{-ws}.
+
+@node ABE Diagnostics,SPARK Diagnostics,Mixing Elaboration Models,Elaboration Order Handling in GNAT
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat abe-diagnostics}@anchor{239}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id8}@anchor{23a}
+@section ABE Diagnostics
+
+
+GNAT performs extensive diagnostics on a unit-by-unit basis for all scenarios
+that invoke internal targets, regardless of whether the dynamic, SPARK, or
+static model is in effect.
+
+Note that GNAT emits warnings rather than hard errors whenever it encounters an
+elaboration problem. This is because the elaboration model in effect may be too
+conservative, or a particular scenario may not be invoked due conditional
+execution. The warnings can be suppressed selectively with @code{pragma Warnings
+(Off)} or globally with compiler switch @code{-gnatwL}.
+
+A @emph{guaranteed ABE} arises when the body of a target is not elaborated early
+enough, and causes @emph{all} scenarios that directly invoke the target to fail.
+
+@quotation
@example
package body Guaranteed_ABE is
@@ -27949,843 +28186,484 @@ package body Guaranteed_ABE is
function ABE return Integer is
begin
- ...
+ ...
end ABE;
end Guaranteed_ABE;
@end example
+@end quotation
In the example above, the elaboration of @code{Guaranteed_ABE}'s body elaborates
-the declaration of @code{Val}. This invokes function @code{ABE}, however the body
-of @code{ABE} has not been elaborated yet. GNAT emits similar diagnostics in all
-three models:
+the declaration of @code{Val}. This invokes function @code{ABE}, however the body of
+@code{ABE} has not been elaborated yet. GNAT emits the following diagnostic:
+
+@quotation
@example
-1. package body Guaranteed_ABE is
-2. function ABE return Integer;
-3.
4. Val : constant Integer := ABE;
|
>>> warning: cannot call "ABE" before body seen
>>> warning: Program_Error will be raised at run time
-
-5.
-6. function ABE return Integer is
-7. begin
-8. ...
-9. end ABE;
-10. end Guaranteed_ABE;
@end example
-@end itemize
-
-Note that GNAT emits warnings rather than hard errors whenever it encounters an
-elaboration problem. This is because the elaboration model in effect may be too
-conservative, or a particular scenario may not be elaborated or executed due to
-data and control flow. The warnings can be suppressed selectively with @code{pragma
-Warnigns (Off)} or globally with compiler switch @code{-gnatwL}.
-
-@node Dynamic Elaboration Model in GNAT,Static Elaboration Model in GNAT,Common Elaboration-model Traits,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat dynamic-elaboration-model-in-gnat}@anchor{238}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id8}@anchor{239}
-@section Dynamic Elaboration Model in GNAT
+@end quotation
+A @emph{conditional ABE} arises when the body of a target is not elaborated early
+enough, and causes @emph{some} scenarios that directly invoke the target to fail.
-The dynamic model assumes that all code within all units in a partition is
-elaboration code. As a result, run-time checks are installed for each scenario
-regardless of whether the target is internal or external. The checks can be
-suppressed using pragma @code{Suppress (Elaboration_Check)}. This behavior is
-identical to that specified by the Ada Reference Manual. The following example
-showcases run-time checks installed by GNAT to verify the elaboration state of
-package @code{Dynamic_Model}.
+@quotation
@example
-with Server;
-package body Dynamic_Model is
- procedure API is
- begin
- ...
- end API;
-
- <check that the body of Server.Gen is elaborated>
- package Inst is new Server.Gen;
+ 1. package body Conditional_ABE is
+ 2. procedure Force_Body is null;
+ 3.
+ 4. generic
+ 5. with function Func return Integer;
+ 6. package Gen is
+ 7. Val : constant Integer := Func;
+ 8. end Gen;
+ 9.
+10. function ABE return Integer;
+11.
+12. function Cause_ABE return Boolean is
+13. package Inst is new Gen (ABE);
+14. begin
+15. ...
+16. end Cause_ABE;
+17.
+18. Val : constant Boolean := Cause_ABE;
+19.
+20. function ABE return Integer is
+21. begin
+22. ...
+23. end ABE;
+24.
+25. Safe : constant Boolean := Cause_ABE;
+26. end Conditional_ABE;
+@end example
+@end quotation
- T : Server.Task_Type;
+In the example above, the elaboration of package body @code{Conditional_ABE}
+elaborates the declaration of @code{Val}. This invokes function @code{Cause_ABE},
+which instantiates generic unit @code{Gen} as @code{Inst}. The elaboration of
+@code{Inst} invokes function @code{ABE}, however the body of @code{ABE} has not been
+elaborated yet. GNAT emits the following diagnostic:
-begin
- <check that the body of Server.Task_Type is elaborated>
+@quotation
- <check that the body of Server.Proc is elaborated>
- Server.Proc;
-end Dynamic_Model;
+@example
+13. package Inst is new Gen (ABE);
+ |
+ >>> warning: in instantiation at line 7
+ >>> warning: cannot call "ABE" before body seen
+ >>> warning: Program_Error may be raised at run time
+ >>> warning: body of unit "Conditional_ABE" elaborated
+ >>> warning: function "Cause_ABE" called at line 18
+ >>> warning: function "ABE" called at line 7, instance at line 13
@end example
+@end quotation
-The checks verify that the body of a target has been successfully elaborated
-before a scenario activates, calls, or instantiates a target.
+Note that the same ABE problem does not occur with the elaboration of
+declaration @code{Safe} because the body of function @code{ABE} has already been
+elaborated at that point.
-Note that no scenario within package @code{Dynamic_Model} calls procedure @code{API}.
-In fact, procedure @code{API} may not be invoked by elaboration code within the
-partition, however the dynamic model assumes that this can happen.
+@node SPARK Diagnostics,Elaboration Circularities,ABE Diagnostics,Elaboration Order Handling in GNAT
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat spark-diagnostics}@anchor{23b}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id9}@anchor{23c}
+@section SPARK Diagnostics
-The dynamic model emits very few diagnostics, but can make suggestions on
-missing @code{Elaborate} and @code{Elaborate_All} pragmas for library-level
-scenarios. This information is available when compiler switch @code{-gnatel}
-is in effect.
+
+GNAT enforces the SPARK rules of elaboration as defined in the SPARK Reference
+Manual section 7.7 when compiler switch @code{-gnatd.v} is in effect. Note
+that GNAT emits hard errors whenever it encounters a violation of the SPARK
+rules.
+
+@quotation
@example
1. with Server;
-2. package body Dynamic_Model is
+2. package body SPARK_Diagnostics with SPARK_Mode is
3. Val : constant Integer := Server.Func;
|
- >>> info: call to "Func" during elaboration
- >>> info: missing pragma "Elaborate_All" for unit "Server"
+ >>> call to "Func" during elaboration in SPARK
+ >>> unit "SPARK_Diagnostics" requires pragma "Elaborate_All" for "Server"
+ >>> body of unit "SPARK_Model" elaborated
+ >>> function "Func" called at line 3
-4. end Dynamic_Model;
+4. end SPARK_Diagnostics;
@end example
+@end quotation
-@node Static Elaboration Model in GNAT,SPARK Elaboration Model in GNAT,Dynamic Elaboration Model in GNAT,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat static-elaboration-model-in-gnat}@anchor{23a}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id9}@anchor{23b}
-@section Static Elaboration Model in GNAT
-
+@node Elaboration Circularities,Resolving Elaboration Circularities,SPARK Diagnostics,Elaboration Order Handling in GNAT
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id10}@anchor{23d}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-circularities}@anchor{23e}
+@section Elaboration Circularities
-In contrast to the dynamic model, the static model is more precise in its
-analysis of elaboration code. The model makes a clear distinction between
-internal and external targets, and resorts to different diagnostics and
-run-time checks based on the nature of the target.
+An @strong{elaboration circularity} occurs whenever the elaboration of a set of
+units enters a deadlocked state, where each unit is waiting for another unit
+to be elaborated. This situation may be the result of improper use of @emph{with}
+clauses, elaboration-control pragmas, or invocations in elaboration code.
-@itemize *
+The following example exhibits an elaboration circularity.
-@item
-@emph{Internal targets}
+@quotation
-The static model performs extensive diagnostics on scenarios which elaborate
-or execute internal targets. The warnings resulting from these diagnostics
-are enabled by default, but can be suppressed selectively with @code{pragma
-Warnings (Off)} or globally with compiler switch @code{-gnatwL}.
+@example
+with B; pragma Elaborate (B);
+package A is
+end A;
+@end example
@example
- 1. package body Static_Model is
- 2. generic
- 3. with function Func return Integer;
- 4. package Gen is
- 5. Val : constant Integer := Func;
- 6. end Gen;
- 7.
- 8. function ABE return Integer;
- 9.
-10. function Cause_ABE return Boolean is
-11. package Inst is new Gen (ABE);
- |
- >>> warning: in instantiation at line 5
- >>> warning: cannot call "ABE" before body seen
- >>> warning: Program_Error may be raised at run time
- >>> warning: body of unit "Static_Model" elaborated
- >>> warning: function "Cause_ABE" called at line 16
- >>> warning: function "ABE" called at line 5, instance at line 11
-
-12. begin
-13. ...
-14. end Cause_ABE;
-15.
-16. Val : constant Boolean := Cause_ABE;
-17.
-18. function ABE return Integer is
-19. begin
-20. ...
-21. end ABE;
-22. end Static_Model;
+package B is
+ procedure Force_Body;
+end B;
@end example
-The example above illustrates an ABE problem within package @code{Static_Model},
-which is hidden by several layers of indirection. The elaboration of package
-body @code{Static_Model} elaborates the declaration of @code{Val}. This invokes
-function @code{Cause_ABE}, which instantiates generic unit @code{Gen} as @code{Inst}.
-The elaboration of @code{Inst} invokes function @code{ABE}, however the body of
-@code{ABE} has not been elaborated yet.
+@example
+with C;
+package body B is
+ procedure Force_Body is null;
-@item
-@emph{External targets}
+ Elab : constant Integer := C.Func;
+end B;
+@end example
-The static model installs run-time checks to verify the elaboration status
-of server targets only when the scenario that elaborates or executes that
-target is part of the elaboration code of the client unit. The checks can be
-suppressed using pragma @code{Suppress (Elaboration_Check)}.
+@example
+package C is
+ function Func return Integer;
+end C;
+@end example
@example
-with Server;
-package body Static_Model is
- generic
- with function Func return Integer;
- package Gen is
- Val : constant Integer := Func;
- end Gen;
-
- function Call_Func return Boolean is
- <check that the body of Server.Func is elaborated>
- package Inst is new Gen (Server.Func);
+with A;
+package body C is
+ function Func return Integer is
begin
...
- end Call_Func;
-
- Val : constant Boolean := Call_Func;
-end Static_Model;
-@end example
-
-In the example above, the elaboration of package body @code{Static_Model}
-elaborates the declaration of @code{Val}. This invokes function @code{Call_Func},
-which instantiates generic unit @code{Gen} as @code{Inst}. The elaboration of
-@code{Inst} invokes function @code{Server.Func}. Since @code{Server.Func} is an
-external target, GNAT installs a run-time check to verify that its body has
-been elaborated.
-
-In addition to checks, the static model installs implicit @code{Elaborate} and
-@code{Elaborate_All} pragmas to guarantee safe elaboration use of server units.
-This information is available when compiler switch @code{-gnatel} is in
-effect.
-
-@example
- 1. with Server;
- 2. package body Static_Model is
- 3. generic
- 4. with function Func return Integer;
- 5. package Gen is
- 6. Val : constant Integer := Func;
- 7. end Gen;
- 8.
- 9. function Call_Func return Boolean is
-10. package Inst is new Gen (Server.Func);
- |
- >>> info: instantiation of "Gen" during elaboration
- >>> info: in instantiation at line 6
- >>> info: call to "Func" during elaboration
- >>> info: in instantiation at line 6
- >>> info: implicit pragma "Elaborate_All" generated for unit "Server"
- >>> info: body of unit "Static_Model" elaborated
- >>> info: function "Call_Func" called at line 15
- >>> info: function "Func" called at line 6, instance at line 10
-
-11. begin
-12. ...
-13. end Call_Func;
-14.
-15. Val : constant Boolean := Call_Func;
- |
- >>> info: call to "Call_Func" during elaboration
-
-16. end Static_Model;
+ end Func;
+end C;
@end example
+@end quotation
-In the example above, the elaboration of package body @code{Static_Model}
-elaborates the declaration of @code{Val}. This invokes function @code{Call_Func},
-which instantiates generic unit @code{Gen} as @code{Inst}. The elaboration of
-@code{Inst} invokes function @code{Server.Func}. Since @code{Server.Func} is an
-external target, GNAT installs an implicit @code{Elaborate_All} pragma for unit
-@code{Server}. The pragma guarantees that both the spec and body of @code{Server},
-along with any additional dependencies that @code{Server} may require, are
-elaborated prior to the body of @code{Static_Model}.
-@end itemize
-
-@node SPARK Elaboration Model in GNAT,Legacy Elaboration Model in GNAT,Static Elaboration Model in GNAT,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id10}@anchor{23c}@anchor{gnat_ugn/elaboration_order_handling_in_gnat spark-elaboration-model-in-gnat}@anchor{23d}
-@section SPARK Elaboration Model in GNAT
-
+The binder emits the following diagnostic:
-The SPARK model is identical to the static model in its handling of internal
-targets. The SPARK model, however, requires explicit @code{Elaborate} or
-@code{Elaborate_All} pragmas to be present in the program when a target is
-external, and compiler switch @code{-gnatd.v} is in effect.
+@quotation
@example
-1. with Server;
-2. package body SPARK_Model with SPARK_Mode is
-3. Val : constant Integer := Server.Func;
- |
- >>> call to "Func" during elaboration in SPARK
- >>> unit "SPARK_Model" requires pragma "Elaborate_All" for "Server"
- >>> body of unit "SPARK_Model" elaborated
- >>> function "Func" called at line 3
-
-4. end SPARK_Model;
+error: Elaboration circularity detected
+info:
+info: Reason:
+info:
+info: unit "a (spec)" depends on its own elaboration
+info:
+info: Circularity:
+info:
+info: unit "a (spec)" has with clause and pragma Elaborate for unit "b (spec)"
+info: unit "b (body)" is in the closure of pragma Elaborate
+info: unit "b (body)" invokes a construct of unit "c (body)" at elaboration time
+info: unit "c (body)" has with clause for unit "a (spec)"
+info:
+info: Suggestions:
+info:
+info: remove pragma Elaborate for unit "b (body)" in unit "a (spec)"
+info: use the dynamic elaboration model (compiler switch -gnatE)
@end example
+@end quotation
-@node Legacy Elaboration Model in GNAT,Mixing Elaboration Models,SPARK Elaboration Model in GNAT,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat legacy-elaboration-model-in-gnat}@anchor{23e}
-@section Legacy Elaboration Model in GNAT
-
-
-The legacy elaboration model is provided for compatibility with code bases
-developed with pre-18.x versions of GNAT. It is similar in functionality to
-the dynamic and static models of post-18.x version of GNAT, but may differ
-in terms of diagnostics and run-time checks. The legacy elaboration model is
-enabled with compiler switch @code{-gnatH}.
-
-@node Mixing Elaboration Models,Elaboration Circularities,Legacy Elaboration Model in GNAT,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat mixing-elaboration-models}@anchor{23f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id11}@anchor{240}
-@section Mixing Elaboration Models
-
-
-It is possible to mix units compiled with a different elaboration model,
-however the following rules must be observed:
+The diagnostic consist of the following sections:
@itemize *
@item
-A client unit compiled with the dynamic model can only @emph{with} a server unit
-that meets at least one of the following criteria:
+Reason
-
-@itemize -
+This section provides a short explanation describing why the set of units
+could not be ordered.
@item
-The server unit is compiled with the dynamic model.
+Circularity
-@item
-The server unit is a GNAT implementation unit from the Ada, GNAT,
-Interfaces, or System hierarchies.
+This section enumerates the units comprising the deadlocked set, along with
+their interdependencies.
@item
-The server unit has pragma @code{Pure} or @code{Preelaborate}.
+Suggestions
-@item
-The client unit has an explicit @code{Elaborate_All} pragma for the server
-unit.
+This section enumerates various tactics for eliminating the circularity.
@end itemize
-@end itemize
-
-These rules ensure that elaboration checks are not omitted. If the rules are
-violated, the binder emits a warning:
-@example
-warning: "x.ads" has dynamic elaboration checks and with's
-warning: "y.ads" which has static elaboration checks
-@end example
-
-The warnings can be suppressed by binder switch @code{-ws}.
+@node Resolving Elaboration Circularities,Elaboration-related Compiler Switches,Elaboration Circularities,Elaboration Order Handling in GNAT
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id11}@anchor{23f}@anchor{gnat_ugn/elaboration_order_handling_in_gnat resolving-elaboration-circularities}@anchor{240}
+@section Resolving Elaboration Circularities
-@node Elaboration Circularities,Resolving Elaboration Circularities,Mixing Elaboration Models,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id12}@anchor{241}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-circularities}@anchor{242}
-@section Elaboration Circularities
+The most desirable option from the point of view of long-term maintenance is to
+rearrange the program so that the elaboration problems are avoided. One useful
+technique is to place the elaboration code into separate child packages.
+Another is to move some of the initialization code to explicitly invoked
+subprograms, where the program controls the order of initialization explicitly.
+Although this is the most desirable option, it may be impractical and involve
+too much modification, especially in the case of complex legacy code.
-If the binder cannot find an acceptable elaboration order, it outputs detailed
-diagnostics describing an @strong{elaboration circularity}.
+When faced with an elaboration circularity, the programmer should also consider
+the tactics given in the suggestions section of the circularity diagnostic.
+Depending on the units involved in the circularity, their @emph{with} clauses,
+purity, preelaborability, presence of elaboration-control pragmas and
+invocations at elaboration time, the binder may suggest one or more of the
+following tactics to eliminate the circularity:
-@example
-package Server is
- function Func return Integer;
-end Server;
-@end example
-@example
-with Client;
-package body Server is
- function Func return Integer is
- begin
- ...
- end Func;
-end Server;
-@end example
-
-@example
-with Server;
-package Client is
- Val : constant Integer := Server.Func;
-end Client;
-@end example
+@itemize *
-@example
-with Client;
-procedure Main is begin null; end Main;
-@end example
+@item
+Pragma Elaborate elimination
@example
-error: elaboration circularity detected
-info: "server (body)" must be elaborated before "client (spec)"
-info: reason: implicit Elaborate_All in unit "client (spec)"
-info: recompile "client (spec)" with -gnatel for full details
-info: "server (body)"
-info: must be elaborated along with its spec:
-info: "server (spec)"
-info: which is withed by:
-info: "client (spec)"
-info: "client (spec)" must be elaborated before "server (body)"
-info: reason: with clause
+remove pragma Elaborate for unit "..." in unit "..."
@end example
-In the example above, @code{Client} must be elaborated prior to @code{Main} by virtue
-of a @emph{with} clause. The elaboration of @code{Client} invokes @code{Server.Func}, and
-static model generates an implicit @code{Elaborate_All} pragma for @code{Server}. The
-pragma implies that both the spec and body of @code{Server}, along with any units
-they @emph{with}, must be elaborated prior to @code{Client}. However, @code{Server}'s body
-@emph{with}s @code{Client}, implying that @code{Client} must be elaborated prior to
-@code{Server}. The end result is that @code{Client} must be elaborated prior to
-@code{Client}, and this leads to a circularity.
-
-@node Resolving Elaboration Circularities,Resolving Task Issues,Elaboration Circularities,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id13}@anchor{243}@anchor{gnat_ugn/elaboration_order_handling_in_gnat resolving-elaboration-circularities}@anchor{244}
-@section Resolving Elaboration Circularities
+This tactic is suggested when the binder has determined that pragma
+@code{Elaborate}:
-When faced with an elaboration circularity, a programmer has several options
-available.
+@itemize -
+@item
+Prevents a set of units from being elaborated.
-@itemize *
+@item
+The removal of the pragma will not eliminate the semantic effects of the
+pragma. In other words, the argument of the pragma will still be elaborated
+prior to the unit containing the pragma.
@item
-@emph{Fix the program}
+The removal of the pragma will enable the successful ordering of the units.
+@end itemize
-The most desirable option from the point of view of long-term maintenance
-is to rearrange the program so that the elaboration problems are avoided.
-One useful technique is to place the elaboration code into separate child
-packages. Another is to move some of the initialization code to explicitly
-invoked subprograms, where the program controls the order of initialization
-explicitly. Although this is the most desirable option, it may be impractical
-and involve too much modification, especially in the case of complex legacy
-code.
+The programmer should remove the pragma as advised, and rebuild the program.
@item
-@emph{Switch to more permissive elaboration model}
+Pragma Elaborate_All elimination
-If the compilation was performed using the static model, enable the dynamic
-model with compiler switch @code{-gnatE}. GNAT will no longer generate
-implicit @code{Elaborate} and @code{Elaborate_All} pragmas, resulting in a behavior
-identical to that specified by the Ada Reference Manual. The binder will
-generate an executable program that may or may not raise @code{Program_Error},
-and it is the programmer's responsibility to ensure that it does not raise
-@code{Program_Error}.
+@example
+remove pragma Elaborate_All for unit "..." in unit "..."
+@end example
-If the compilation was performed using a post-18.x version of GNAT, consider
-using the legacy elaboration model, in the following order:
+This tactic is suggested when the binder has determined that pragma
+@code{Elaborate_All}:
@itemize -
@item
-Use the relaxed static elaboration model, with compiler switch
-@code{-gnatJ}.
+Prevents a set of units from being elaborated.
@item
-Use the relaxed dynamic elaboration model, with compiler switches
-@code{-gnatE} @code{-gnatJ}.
-
-@item
-Use the legacy static elaboration model, with compiler switch
-@code{-gnatH}.
+The removal of the pragma will not eliminate the semantic effects of the
+pragma. In other words, the argument of the pragma along with its @emph{with}
+closure will still be elaborated prior to the unit containing the pragma.
@item
-Use the legacy dynamic elaboration model, with compiler switches
-@code{-gnatE} @code{-gnatH}.
+The removal of the pragma will enable the successful ordering of the units.
@end itemize
-@item
-@emph{Suppress all elaboration checks}
-
-The drawback of run-time checks is that they generate overhead at run time,
-both in space and time. If the programmer is absolutely sure that a program
-will not raise an elaboration-related @code{Program_Error}, then using the
-pragma @code{Suppress (Elaboration_Check)} globally (as a configuration pragma)
-will eliminate all run-time checks.
+The programmer should remove the pragma as advised, and rebuild the program.
@item
-@emph{Suppress elaboration checks selectively}
+Pragma Elaborate_All downgrade
-If a scenario cannot possibly lead to an elaboration @code{Program_Error},
-and the binder nevertheless complains about implicit @code{Elaborate} and
-@code{Elaborate_All} pragmas that lead to elaboration circularities, it
-is possible to suppress the generation of implicit @code{Elaborate} and
-@code{Elaborate_All} pragmas, as well as run-time checks. Clearly this can
-be unsafe, and it is the responsibility of the programmer to make sure
-that the resulting program has no elaboration anomalies. Pragma
-@code{Suppress (Elaboration_Check)} can be used with different levels of
-granularity to achieve these effects.
+@example
+change pragma Elaborate_All for unit "..." to Elaborate in unit "..."
+@end example
+This tactic is always suggested with the pragma @code{Elaborate_All} elimination
+tactic. It offers a different alernative of guaranteeing that the argument of
+the pragma will still be elaborated prior to the unit containing the pragma.
-@itemize -
+The programmer should update the pragma as advised, and rebuild the program.
@item
-@emph{Target suppression}
-
-When the pragma is placed in a declarative part, without a second argument
-naming an entity, it will suppress implicit @code{Elaborate} and
-@code{Elaborate_All} pragma generation, as well as run-time checks, on all
-targets within the region.
+Pragma Elaborate_Body elimination
@example
-package Range_Suppress is
- pragma Suppress (Elaboration_Check);
-
- function Func return Integer;
+remove pragma Elaborate_Body in unit "..."
+@end example
- generic
- procedure Gen;
+This tactic is suggested when the binder has determined that pragma
+@code{Elaborate_Body}:
- pragma Unsuppress (Elaboration_Check);
- task type Tsk;
-end Range_Suppress;
-@end example
+@itemize -
-In the example above, a pair of Suppress/Unsuppress pragmas define a region
-of suppression within package @code{Range_Suppress}. As a result, no implicit
-@code{Elaborate} and @code{Elaborate_All} pragmas, nor any run-time checks, will
-be generated by callers of @code{Func} and instantiators of @code{Gen}. Note that
-task type @code{Tsk} is not within this region.
+@item
+Prevents a set of units from being elaborated.
-An alternative to the region-based suppression is to use multiple
-@code{Suppress} pragmas with arguments naming specific entities for which
-elaboration checks should be suppressed:
+@item
+The removal of the pragma will enable the successful ordering of the units.
+@end itemize
-@example
-package Range_Suppress is
- function Func return Integer;
- pragma Suppress (Elaboration_Check, Func);
+Note that the binder cannot determine whether the pragma is required for
+other purposes, such as guaranteeing the initialization of a variable
+declared in the spec by elaboration code in the body.
- generic
- procedure Gen;
- pragma Suppress (Elaboration_Check, Gen);
-
- task type Tsk;
-end Range_Suppress;
-@end example
+The programmer should remove the pragma as advised, and rebuild the program.
@item
-@emph{Scenario suppression}
-
-When the pragma @code{Suppress} is placed in a declarative or statement
-part, without an entity argument, it will suppress implicit @code{Elaborate}
-and @code{Elaborate_All} pragma generation, as well as run-time checks, on
-all scenarios within the region.
+Use of pragma Restrictions
@example
-with Server;
-package body Range_Suppress is
- pragma Suppress (Elaboration_Check);
-
- function Func return Integer is
- begin
- return Server.Func;
- end Func;
+use pragma Restrictions (No_Entry_Calls_In_Elaboration_Code)
+@end example
- procedure Gen is
- begin
- Server.Proc;
- end Gen;
+This tactic is suggested when the binder has determined that a task
+activation at elaboration time:
- pragma Unsuppress (Elaboration_Check);
- task body Tsk is
- begin
- Server.Proc;
- end Tsk;
-end Range_Suppress;
-@end example
+@itemize -
-In the example above, a pair of Suppress/Unsuppress pragmas define a region
-of suppression within package body @code{Range_Suppress}. As a result, the
-calls to @code{Server.Func} in @code{Func} and @code{Server.Proc} in @code{Gen} will
-not generate any implicit @code{Elaborate} and @code{Elaborate_All} pragmas or
-run-time checks.
-@end itemize
+@item
+Prevents a set of units from being elaborated.
@end itemize
-@node Resolving Task Issues,Elaboration-related Compiler Switches,Resolving Elaboration Circularities,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat id14}@anchor{245}@anchor{gnat_ugn/elaboration_order_handling_in_gnat resolving-task-issues}@anchor{246}
-@section Resolving Task Issues
+Note that the binder cannot determine with certainty whether the task will
+block at elaboration time.
+The programmer should create a configuration file, place the pragma within,
+update the general compilation arguments, and rebuild the program.
-The model of execution in Ada dictates that elaboration must first take place,
-and only then can the main program be started. Tasks which are activated during
-elaboration violate this model and may lead to serious concurrent problems at
-elaboration time.
+@item
+Use of dynamic elaboration model
-A task can be activated in two different ways:
+@example
+use the dynamic elaboration model (compiler switch -gnatE)
+@end example
+This tactic is suggested when the binder has determined that an invocation at
+elaboration time:
-@itemize *
+
+@itemize -
@item
-The task is created by an allocator in which case it is activated immediately
-after the allocator is evaluated.
+Prevents a set of units from being elaborated.
@item
-The task is declared at the library level or within some nested master in
-which case it is activated before starting execution of the statement
-sequence of the master defining the task.
+The use of the dynamic model will enable the successful ordering of the
+units.
@end itemize
-Since the elaboration of a partition is performed by the environment task
-servicing that partition, any tasks activated during elaboration may be in
-a race with the environment task, and lead to unpredictable state and behavior.
-The static model seeks to avoid such interactions by assuming that all code in
-the task body is executed at elaboration time, if the task was activated by
-elaboration code.
+The programmer has two options:
-@example
-package Decls is
- task Lib_Task is
- entry Start;
- end Lib_Task;
- type My_Int is new Integer;
+@itemize -
- function Ident (M : My_Int) return My_Int;
-end Decls;
-@end example
+@item
+Determine the units involved in the invocation using the detailed
+invocation information, and add compiler switch @code{-gnatE} to the
+compilation arguments of selected files only. This approach will yield
+safer elaboration orders compared to the other option because it will
+minimize the opportunities presented to the dynamic model for ignoring
+invocations.
-@example
-with Utils;
-package body Decls is
- task body Lib_Task is
- begin
- accept Start;
- Utils.Put_Val (2);
- end Lib_Task;
+@item
+Add compiler switch @code{-gnatE} to the general compilation arguments.
+@end itemize
- function Ident (M : My_Int) return My_Int is
- begin
- return M;
- end Ident;
-end Decls;
-@end example
+@item
+Use of detailed invocation information
@example
-with Decls;
-package Utils is
- procedure Put_Val (Arg : Decls.My_Int);
-end Utils;
+use detailed invocation information (compiler switch -gnatd_F)
@end example
-@example
-with Ada.Text_IO; use Ada.Text_IO;
-package body Utils is
- procedure Put_Val (Arg : Decls.My_Int) is
- begin
- Put_Line (Arg'Img);
- end Put_Val;
-end Utils;
-@end example
+This tactic is always suggested with the use of the dynamic model tactic. It
+causes the circularity section of the circularity diagnostic to describe the
+flow of elaboration code from a unit to a unit, enumerating all such paths in
+the process.
-@example
-with Decls;
-procedure Main is
-begin
- Decls.Lib_Task.Start;
-end Main;
-@end example
+The programmer should analyze this information to determine which units
+should be compiled with the dynamic model.
-When the above example is compiled with the static model, an elaboration
-circularity arises:
+@item
+Forced-dependency elimination
@example
-error: elaboration circularity detected
-info: "decls (body)" must be elaborated before "decls (body)"
-info: reason: implicit Elaborate_All in unit "decls (body)"
-info: recompile "decls (body)" with -gnatel for full details
-info: "decls (body)"
-info: must be elaborated along with its spec:
-info: "decls (spec)"
-info: which is withed by:
-info: "utils (spec)"
-info: which is withed by:
-info: "decls (body)"
+remove the dependency of unit "..." on unit "..." from the argument of switch -f
@end example
-In the above example, @code{Decls} must be elaborated prior to @code{Main} by virtue
-of a with clause. The elaboration of @code{Decls} activates task @code{Lib_Task}. The
-static model conservatibely assumes that all code within the body of
-@code{Lib_Task} is executed, and generates an implicit @code{Elaborate_All} pragma
-for @code{Units} due to the call to @code{Utils.Put_Val}. The pragma implies that
-both the spec and body of @code{Utils}, along with any units they @emph{with},
-must be elaborated prior to @code{Decls}. However, @code{Utils}'s spec @emph{with}s
-@code{Decls}, implying that @code{Decls} must be elaborated before @code{Utils}. The end
-result is that @code{Utils} must be elaborated prior to @code{Utils}, and this
-leads to a circularity.
-
-In reality, the example above will not exhibit an ABE problem at run time.
-When the body of task @code{Lib_Task} is activated, execution will wait for entry
-@code{Start} to be accepted, and the call to @code{Utils.Put_Val} will not take place
-at elaboration time. Task @code{Lib_Task} will resume its execution after the main
-program is executed because @code{Main} performs a rendezvous with
-@code{Lib_Task.Start}, and at that point all units have already been elaborated.
-As a result, the static model may seem overly conservative, partly because it
-does not take control and data flow into account.
-
-When faced with a task elaboration circularity, a programmer has several
-options available:
+This tactic is suggested when the binder has determined that a dependency
+present in the forced-elaboration-order file indicated by binder switch
+@code{-f}:
-@itemize *
+@itemize -
@item
-@emph{Use the dynamic model}
-
-The dynamic model does not generate implicit @code{Elaborate} and
-@code{Elaborate_All} pragmas. Instead, it will install checks prior to every
-call in the example above, thus verifying the successful elaboration of
-@code{Utils.Put_Val} in case the call to it takes place at elaboration time.
-The dynamic model is enabled with compiler switch @code{-gnatE}.
+Prevents a set of units from being elaborated.
@item
-@emph{Isolate the tasks}
-
-Relocating tasks in their own separate package could decouple them from
-dependencies that would otherwise cause an elaboration circularity. The
-example above can be rewritten as follows:
-
-@example
-package Decls1 is -- new
- task Lib_Task is
- entry Start;
- end Lib_Task;
-end Decls1;
-@end example
-
-@example
-with Utils;
-package body Decls1 is -- new
- task body Lib_Task is
- begin
- accept Start;
- Utils.Put_Val (2);
- end Lib_Task;
-end Decls1;
-@end example
+The removal of the dependency will enable the successful ordering of the
+units.
+@end itemize
-@example
-package Decls2 is -- new
- type My_Int is new Integer;
- function Ident (M : My_Int) return My_Int;
-end Decls2;
-@end example
+The programmer should edit the forced-elaboration-order file, remove the
+dependency, and rebind the program.
-@example
-with Utils;
-package body Decls2 is -- new
- function Ident (M : My_Int) return My_Int is
- begin
- return M;
- end Ident;
-end Decls2;
-@end example
+@item
+All forced-dependency elimination
@example
-with Decls2;
-package Utils is
- procedure Put_Val (Arg : Decls2.My_Int);
-end Utils;
+remove switch -f
@end example
-@example
-with Ada.Text_IO; use Ada.Text_IO;
-package body Utils is
- procedure Put_Val (Arg : Decls2.My_Int) is
- begin
- Put_Line (Arg'Img);
- end Put_Val;
-end Utils;
-@end example
+This tactic is suggested in case editing the forced-elaboration-order file is
+not an option.
-@example
-with Decls1;
-procedure Main is
-begin
- Decls1.Lib_Task.Start;
-end Main;
-@end example
+The programmer should remove binder switch @code{-f} from the binder
+arguments, and rebind.
@item
-@emph{Declare the tasks}
-
-The original example uses a single task declaration for @code{Lib_Task}. An
-explicit task type declaration and a properly placed task object could avoid
-the dependencies that would otherwise cause an elaboration circularity. The
-example can be rewritten as follows:
+Multiple-circularities diagnostic
@example
-package Decls is
- task type Lib_Task is -- new
- entry Start;
- end Lib_Task;
-
- type My_Int is new Integer;
-
- function Ident (M : My_Int) return My_Int;
-end Decls;
+diagnose all circularities (binder switch -d_C)
@end example
-@example
-with Utils;
-package body Decls is
- task body Lib_Task is
- begin
- accept Start;
- Utils.Put_Val (2);
- end Lib_Task;
-
- function Ident (M : My_Int) return My_Int is
- begin
- return M;
- end Ident;
-end Decls;
-@end example
+By default, the binder will diagnose only the highest-precedence circularity.
+If the program contains multiple circularities, the binder will suggest the
+use of binder switch @code{-d_C} in order to obtain the diagnostics of all
+circularities.
-@example
-with Decls;
-package Utils is
- procedure Put_Val (Arg : Decls.My_Int);
-end Utils;
-@end example
+The programmer should add binder switch @code{-d_C} to the binder
+arguments, and rebind.
+@end itemize
-@example
-with Ada.Text_IO; use Ada.Text_IO;
-package body Utils is
- procedure Put_Val (Arg : Decls.My_Int) is
- begin
- Put_Line (Arg'Img);
- end Put_Val;
-end Utils;
-@end example
+If none of the tactics suggested by the binder eliminate the elaboration
+circularity, the programmer should consider using one of the legacy elaboration
+models, in the following order:
-@example
-with Decls;
-package Obj_Decls is -- new
- Task_Obj : Decls.Lib_Task;
-end Obj_Decls;
-@end example
-@example
-with Obj_Decls;
-procedure Main is
-begin
- Obj_Decls.Task_Obj.Start; -- new
-end Main;
-@end example
+@itemize *
@item
-@emph{Use restriction No_Entry_Calls_In_Elaboration_Code}
+Use the pre-20.x legacy elaboration-order model, with binder switch
+@code{-H}.
-The issue exhibited in the original example under this section revolves
-around the body of @code{Lib_Task} blocking on an accept statement. There is
-no rule to prevent elaboration code from performing entry calls, however in
-practice this is highly unusual. In addition, the pattern of starting tasks
-at elaboration time and then immediately blocking on accept or select
-statements is quite common.
-
-If a programmer knows that elaboration code will not perform any entry
-calls, then the programmer can indicate that the static model should not
-process the remainder of a task body once an accept or select statement has
-been encountered. This behavior can be specified by a configuration pragma:
+@item
+Use both pre-18.x and pre-20.x legacy elaboration models, with compiler
+switch @code{-gnatH} and binder switch @code{-H}.
-@example
-pragma Restrictions (No_Entry_Calls_In_Elaboration_Code);
-@end example
+@item
+Use the relaxed static-elaboration model, with compiler switches
+@code{-gnatH} @code{-gnatJ} and binder switch @code{-H}.
-In addition to the change in behavior with respect to task bodies, the
-static model will verify that no entry calls take place at elaboration time.
+@item
+Use the relaxed dynamic-elaboration model, with compiler switches
+@code{-gnatH} @code{-gnatJ} @code{-gnatE} and binder switch
+@code{-H}.
@end itemize
-@node Elaboration-related Compiler Switches,Summary of Procedures for Elaboration Control,Resolving Task Issues,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-related-compiler-switches}@anchor{247}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id15}@anchor{248}
+@node Elaboration-related Compiler Switches,Summary of Procedures for Elaboration Control,Resolving Elaboration Circularities,Elaboration Order Handling in GNAT
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id12}@anchor{241}@anchor{gnat_ugn/elaboration_order_handling_in_gnat elaboration-related-compiler-switches}@anchor{242}
@section Elaboration-related Compiler Switches
@@ -28801,7 +28679,7 @@ the elaboration order chosen by the binder.
Dynamic elaboration checking mode enabled
-When this switch is in effect, GNAT activates the dynamic elaboration model.
+When this switch is in effect, GNAT activates the dynamic model.
@end table
@geindex -gnatel (gnat)
@@ -28813,6 +28691,10 @@ When this switch is in effect, GNAT activates the dynamic elaboration model.
Turn on info messages on generated Elaborate[_All] pragmas
+This switch is only applicable to the pre-20.x legacy elaboration models.
+The post-20.x elaboration model no longer relies on implicitly generated
+@code{Elaborate} and @code{Elaborate_All} pragmas to order units.
+
When this switch is in effect, GNAT will emit the following supplementary
information depending on the elaboration model in effect.
@@ -28828,7 +28710,7 @@ all library-level scenarios within the partition.
@item
@emph{Static model}
-GNAT will indicate all scenarios executed during elaboration. In addition,
+GNAT will indicate all scenarios invoked during elaboration. In addition,
it will provide detailed traceback when an implicit @code{Elaborate} or
@code{Elaborate_All} pragma is generated.
@@ -28962,7 +28844,7 @@ checks. The example above will still fail at run time with an ABE.
@end table
@node Summary of Procedures for Elaboration Control,Inspecting the Chosen Elaboration Order,Elaboration-related Compiler Switches,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat summary-of-procedures-for-elaboration-control}@anchor{249}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id16}@anchor{24a}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id13}@anchor{243}@anchor{gnat_ugn/elaboration_order_handling_in_gnat summary-of-procedures-for-elaboration-control}@anchor{244}
@section Summary of Procedures for Elaboration Control
@@ -28990,13 +28872,8 @@ as their origins. Elaboration warnings are enabled with compiler switch
@code{-gnatwl}.
@item
-Use switch @code{-gnatel} to obtain messages on generated implicit
-@code{Elaborate} and @code{Elaborate_All} pragmas. The trace information could
-indicate why a server unit must be elaborated prior to a client unit.
-
-@item
-If the warnings produced by the static model indicate that a task is
-involved, consider the options in section @ref{245,,Resolving Task Issues}.
+Cosider the tactics given in the suggestions section of the circularity
+diagnostic.
@item
If none of the steps outlined above resolve the circularity, use a more
@@ -29006,28 +28883,26 @@ permissive elaboration model, in the following order:
@itemize -
@item
-Use the dynamic elaboration model, with compiler switch @code{-gnatE}.
+Use the pre-20.x legacy elaboration-order model, with binder switch
+@code{-H}.
@item
-Use the legacy static elaboration model, with compiler switch
-@code{-gnatH}.
+Use both pre-18.x and pre-20.x legacy elaboration models, with compiler
+switch @code{-gnatH} and binder switch @code{-H}.
@item
-Use the legacy dynamic elaboration model, with compiler switches
-@code{-gnatH} @code{-gnatE}.
+Use the relaxed static elaboration model, with compiler switches
+@code{-gnatH} @code{-gnatJ} and binder switch @code{-H}.
@item
-Use the relaxed legacy static elaboration model, with compiler switches
-@code{-gnatH} @code{-gnatJ}.
-
-@item
-Use the relaxed legacy dynamic elaboration model, with compiler switches
-@code{-gnatH} @code{-gnatJ} @code{-gnatE}.
+Use the relaxed dynamic elaboration model, with compiler switches
+@code{-gnatH} @code{-gnatJ} @code{-gnatE} and binder switch
+@code{-H}.
@end itemize
@end itemize
@node Inspecting the Chosen Elaboration Order,,Summary of Procedures for Elaboration Control,Elaboration Order Handling in GNAT
-@anchor{gnat_ugn/elaboration_order_handling_in_gnat inspecting-the-chosen-elaboration-order}@anchor{24b}@anchor{gnat_ugn/elaboration_order_handling_in_gnat id17}@anchor{24c}
+@anchor{gnat_ugn/elaboration_order_handling_in_gnat id14}@anchor{245}@anchor{gnat_ugn/elaboration_order_handling_in_gnat inspecting-the-chosen-elaboration-order}@anchor{246}
@section Inspecting the Chosen Elaboration Order
@@ -29037,6 +28912,8 @@ elaboration order appears as a sequence of calls to @code{Elab_Body} and
@code{Elab_Spec}, interspersed with assignments to @cite{Exxx} which indicates that a
particular unit is elaborated. For example:
+@quotation
+
@example
System.Soft_Links'Elab_Body;
E14 := True;
@@ -29072,10 +28949,13 @@ Ada.Text_Io'Elab_Spec;
Ada.Text_Io'Elab_Body;
E07 := True;
@end example
+@end quotation
Note also binder switch @code{-l}, which outputs the chosen elaboration
order and provides a more readable form of the above:
+@quotation
+
@example
ada (spec)
interfaces (spec)
@@ -29162,9 +29042,10 @@ ada.text_io (body)
text_io (spec)
gdbstr (body)
@end example
+@end quotation
@node Inline Assembler,GNU Free Documentation License,Elaboration Order Handling in GNAT,Top
-@anchor{gnat_ugn/inline_assembler inline-assembler}@anchor{10}@anchor{gnat_ugn/inline_assembler doc}@anchor{24d}@anchor{gnat_ugn/inline_assembler id1}@anchor{24e}
+@anchor{gnat_ugn/inline_assembler inline-assembler}@anchor{10}@anchor{gnat_ugn/inline_assembler doc}@anchor{247}@anchor{gnat_ugn/inline_assembler id1}@anchor{248}
@chapter Inline Assembler
@@ -29223,7 +29104,7 @@ and with assembly language programming.
@end menu
@node Basic Assembler Syntax,A Simple Example of Inline Assembler,,Inline Assembler
-@anchor{gnat_ugn/inline_assembler id2}@anchor{24f}@anchor{gnat_ugn/inline_assembler basic-assembler-syntax}@anchor{250}
+@anchor{gnat_ugn/inline_assembler id2}@anchor{249}@anchor{gnat_ugn/inline_assembler basic-assembler-syntax}@anchor{24a}
@section Basic Assembler Syntax
@@ -29339,7 +29220,7 @@ Intel: Destination first; for example @code{mov eax, 4}@w{ }
@node A Simple Example of Inline Assembler,Output Variables in Inline Assembler,Basic Assembler Syntax,Inline Assembler
-@anchor{gnat_ugn/inline_assembler a-simple-example-of-inline-assembler}@anchor{251}@anchor{gnat_ugn/inline_assembler id3}@anchor{252}
+@anchor{gnat_ugn/inline_assembler a-simple-example-of-inline-assembler}@anchor{24b}@anchor{gnat_ugn/inline_assembler id3}@anchor{24c}
@section A Simple Example of Inline Assembler
@@ -29488,7 +29369,7 @@ If there are no errors, @code{as} will generate an object file
@code{nothing.out}.
@node Output Variables in Inline Assembler,Input Variables in Inline Assembler,A Simple Example of Inline Assembler,Inline Assembler
-@anchor{gnat_ugn/inline_assembler id4}@anchor{253}@anchor{gnat_ugn/inline_assembler output-variables-in-inline-assembler}@anchor{254}
+@anchor{gnat_ugn/inline_assembler id4}@anchor{24d}@anchor{gnat_ugn/inline_assembler output-variables-in-inline-assembler}@anchor{24e}
@section Output Variables in Inline Assembler
@@ -29855,7 +29736,7 @@ end Get_Flags_3;
@end quotation
@node Input Variables in Inline Assembler,Inlining Inline Assembler Code,Output Variables in Inline Assembler,Inline Assembler
-@anchor{gnat_ugn/inline_assembler id5}@anchor{255}@anchor{gnat_ugn/inline_assembler input-variables-in-inline-assembler}@anchor{256}
+@anchor{gnat_ugn/inline_assembler id5}@anchor{24f}@anchor{gnat_ugn/inline_assembler input-variables-in-inline-assembler}@anchor{250}
@section Input Variables in Inline Assembler
@@ -29944,7 +29825,7 @@ _increment__incr.1:
@end quotation
@node Inlining Inline Assembler Code,Other Asm Functionality,Input Variables in Inline Assembler,Inline Assembler
-@anchor{gnat_ugn/inline_assembler id6}@anchor{257}@anchor{gnat_ugn/inline_assembler inlining-inline-assembler-code}@anchor{258}
+@anchor{gnat_ugn/inline_assembler id6}@anchor{251}@anchor{gnat_ugn/inline_assembler inlining-inline-assembler-code}@anchor{252}
@section Inlining Inline Assembler Code
@@ -30015,7 +29896,7 @@ movl %esi,%eax
thus saving the overhead of stack frame setup and an out-of-line call.
@node Other Asm Functionality,,Inlining Inline Assembler Code,Inline Assembler
-@anchor{gnat_ugn/inline_assembler other-asm-functionality}@anchor{259}@anchor{gnat_ugn/inline_assembler id7}@anchor{25a}
+@anchor{gnat_ugn/inline_assembler other-asm-functionality}@anchor{253}@anchor{gnat_ugn/inline_assembler id7}@anchor{254}
@section Other @code{Asm} Functionality
@@ -30030,7 +29911,7 @@ and @code{Volatile}, which inhibits unwanted optimizations.
@end menu
@node The Clobber Parameter,The Volatile Parameter,,Other Asm Functionality
-@anchor{gnat_ugn/inline_assembler the-clobber-parameter}@anchor{25b}@anchor{gnat_ugn/inline_assembler id8}@anchor{25c}
+@anchor{gnat_ugn/inline_assembler the-clobber-parameter}@anchor{255}@anchor{gnat_ugn/inline_assembler id8}@anchor{256}
@subsection The @code{Clobber} Parameter
@@ -30094,7 +29975,7 @@ Use 'register' name @code{memory} if you changed a memory location
@end itemize
@node The Volatile Parameter,,The Clobber Parameter,Other Asm Functionality
-@anchor{gnat_ugn/inline_assembler the-volatile-parameter}@anchor{25d}@anchor{gnat_ugn/inline_assembler id9}@anchor{25e}
+@anchor{gnat_ugn/inline_assembler the-volatile-parameter}@anchor{257}@anchor{gnat_ugn/inline_assembler id9}@anchor{258}
@subsection The @code{Volatile} Parameter
@@ -30130,7 +30011,7 @@ to @code{True} only if the compiler's optimizations have created
problems.
@node GNU Free Documentation License,Index,Inline Assembler,Top
-@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{25f}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{260}
+@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{259}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{25a}
@chapter GNU Free Documentation License
diff --git a/gcc/ada/gnatbind.adb b/gcc/ada/gnatbind.adb
index 41541c3..a3b6a7e 100644
--- a/gcc/ada/gnatbind.adb
+++ b/gcc/ada/gnatbind.adb
@@ -26,7 +26,6 @@
with ALI; use ALI;
with ALI.Util; use ALI.Util;
with Bcheck; use Bcheck;
-with Binde; use Binde;
with Binderr; use Binderr;
with Bindgen; use Bindgen;
with Bindo; use Bindo;
@@ -475,6 +474,17 @@ procedure Gnatbind is
Mapping_File := new String'(Argv (4 .. Argv'Last));
+ -- -minimal
+
+ elsif Argv (2 .. Argv'Last) = "minimal" then
+ if not Is_Cross_Compiler then
+ Write_Line
+ ("gnatbind: -minimal not expected to be used on native " &
+ "platforms");
+ end if;
+
+ Opt.Minimal_Binder := True;
+
-- -Mname
elsif Argv'Length >= 3 and then Argv (2) = 'M' then
@@ -883,14 +893,7 @@ begin
Elab_Order : Unit_Id_Table;
begin
- -- Use the invocation and library graph-based elaboration order
- -- when switch -d_N (new bindo order) is in effect.
-
- if Debug_Flag_Underscore_NN then
- Find_Elaboration_Order (Elab_Order, First_Main_Lib_File);
- else
- Find_Elab_Order (Elab_Order, First_Main_Lib_File);
- end if;
+ Find_Elaboration_Order (Elab_Order, First_Main_Lib_File);
if Errors_Detected = 0 and then not Check_Only then
Gen_Output_File
diff --git a/gcc/ada/gnatlink.adb b/gcc/ada/gnatlink.adb
index 5e5ede0..69462e9 100644
--- a/gcc/ada/gnatlink.adb
+++ b/gcc/ada/gnatlink.adb
@@ -459,7 +459,7 @@ procedure Gnatlink is
when 'v' =>
- -- Support "double" verbose mode. Second -v
+ -- Support "double" verbose mode. Second -v
-- gets sent to the linker and binder phases.
if Verbose_Mode then
@@ -2068,7 +2068,7 @@ begin
end Link_Step;
-- Only keep the binder output file and it's associated object
- -- file if compiling with the -g option. These files are only
+ -- file if compiling with the -g option. These files are only
-- useful if debugging.
if not Debug_Flag_Present then
diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h
index 1821b1b..c44e134 100644
--- a/gcc/ada/gsocket.h
+++ b/gcc/ada/gsocket.h
@@ -82,6 +82,7 @@
#ifdef __MINGW32__
#include <winsock2.h>
#include <ws2tcpip.h>
+#include <versionhelpers.h>
#undef EACCES
#define EACCES WSAEACCES
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 00f32e5..f7e830e 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -54,8 +54,14 @@
#endif
#ifdef IN_RTS
+
+#ifdef STANDALONE
+#include "runtime.h"
+#else
#include "tconfig.h"
#include "tsystem.h"
+#endif
+
#include <sys/stat.h>
/* We don't have libiberty, so use malloc. */
@@ -463,6 +469,7 @@ void fake_linux_sigemptyset (sigset_t *set)
void
__gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
{
+#ifndef STANDALONE
mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
/* On the i386 and x86-64 architectures, stack checking is performed by
@@ -513,6 +520,7 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
mcontext->arm_pc+=1;
#endif
#endif
+#endif
}
#endif
@@ -1725,7 +1733,7 @@ __gnat_install_handler (void)
#include <iv.h>
#endif
-#if ((defined (ARMEL) && (_WRS_VXWORKS_MAJOR == 6)) || defined (__x86_64__)) && !defined(__RTP__)
+#if ((defined (ARMEL) && (_WRS_VXWORKS_MAJOR == 6))) && !defined(__RTP__)
#define VXWORKS_FORCE_GUARD_PAGE 1
#include <vmLib.h>
extern size_t vxIntStackOverflowSize;
diff --git a/gcc/ada/initialize.c b/gcc/ada/initialize.c
index ab6d81d..0e52feb 100644
--- a/gcc/ada/initialize.c
+++ b/gcc/ada/initialize.c
@@ -41,8 +41,7 @@
#endif
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
+#include "runtime.h"
/* We don't have libiberty, so use malloc. */
#define xmalloc(S) malloc (S)
#define xrealloc(V,S) realloc (V,S)
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index b2038a6..5b7fefc 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -1751,7 +1751,7 @@ package body Inline is
-- occurrences of pragmas referencing the formals are removed since
-- they have no meaning when the body is inlined and the formals are
-- rewritten (the analysis of the non-inlined body will handle these
- -- pragmas). A new internal name is associated with Body_To_Inline.
+ -- pragmas). A new internal name is associated with Body_To_Inline.
------------------------------
-- Generate_Subprogram_Body --
@@ -2481,8 +2481,7 @@ package body Inline is
-- thunk generated for it. Replace a return statement with an assignment
-- to the target of the call, with appropriate conversions if needed.
- function Process_Formals_In_Aspects (N : Node_Id)
- return Traverse_Result;
+ function Process_Formals_In_Aspects (N : Node_Id) return Traverse_Result;
-- Because aspects are linked indirectly to the rest of the tree,
-- replacement of formals appearing in aspect specifications must
-- be performed in a separate pass, using an instantiation of the
@@ -2832,10 +2831,11 @@ package body Inline is
-- Process_Formals_In_Aspects --
--------------------------------
- function Process_Formals_In_Aspects (N : Node_Id)
- return Traverse_Result
+ function Process_Formals_In_Aspects
+ (N : Node_Id) return Traverse_Result
is
A : Node_Id;
+
begin
if Has_Aspects (N) then
A := First (Aspect_Specifications (N));
@@ -2849,7 +2849,7 @@ package body Inline is
end Process_Formals_In_Aspects;
procedure Replace_Formals_In_Aspects is
- new Traverse_Proc (Process_Formals_In_Aspects);
+ new Traverse_Proc (Process_Formals_In_Aspects);
------------------
-- Process_Sloc --
diff --git a/gcc/ada/lib-writ.adb b/gcc/ada/lib-writ.adb
index ffd6a90..987afcb 100644
--- a/gcc/ada/lib-writ.adb
+++ b/gcc/ada/lib-writ.adb
@@ -59,65 +59,32 @@ with System.WCh_Con; use System.WCh_Con;
package body Lib.Writ is
-----------------------
- -- Local Subprograms --
+ -- Local subprograms --
-----------------------
- function Column (IS_Id : Invocation_Signature_Id) return Nat;
- pragma Inline (Column);
- -- Obtain attribute Column of an invocation signature with id IS_Id
-
- function Extra (IR_Id : Invocation_Relation_Id) return Name_Id;
- pragma Inline (Extra);
- -- Obtain attribute Extra of an invocation relation with id IR_Id
-
- function Invoker
- (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id;
- pragma Inline (Invoker);
- -- Obtain attribute Invoker of an invocation relation with id IR_Id
-
- function Kind
- (IC_Id : Invocation_Construct_Id) return Invocation_Construct_Kind;
- pragma Inline (Kind);
- -- Obtain attribute Kind of an invocation construct with id IC_Id
-
- function Kind (IR_Id : Invocation_Relation_Id) return Invocation_Kind;
- pragma Inline (Kind);
- -- Obtain attribute Kind of an invocation relation with id IR_Id
-
- function Line (IS_Id : Invocation_Signature_Id) return Nat;
- pragma Inline (Line);
- -- Obtain attribute Line of an invocation signature with id IS_Id
-
- function Locations (IS_Id : Invocation_Signature_Id) return Name_Id;
- pragma Inline (Locations);
- -- Obtain attribute Locations of an invocation signature with id IS_Id
-
- function Name (IS_Id : Invocation_Signature_Id) return Name_Id;
- pragma Inline (Name);
- -- Obtain attribute Name of an invocation signature with id IS_Id
-
- function Placement
- (IC_Id : Invocation_Construct_Id) return Body_Placement_Kind;
- pragma Inline (Placement);
- -- Obtain attribute Placement of an invocation construct with id IC_Id
-
function Present (N_Id : Name_Id) return Boolean;
pragma Inline (Present);
-- Determine whether a name with id N_Id exists
- function Scope (IS_Id : Invocation_Signature_Id) return Name_Id;
- pragma Inline (Scope);
- -- Obtain attribute Scope of an invocation signature with id IS_Id
+ procedure Write_Invocation_Construct (IC_Id : Invocation_Construct_Id);
+ pragma Inline (Write_Invocation_Construct);
+ -- Write invocation construct IC_Id to the ALI file
+
+ procedure Write_Invocation_Graph;
+ pragma Inline (Write_Invocation_Graph);
+ -- Write out the invocation graph
- function Signature
- (IC_Id : Invocation_Construct_Id) return Invocation_Signature_Id;
- pragma Inline (Signature);
- -- Obtain attribute Signature of an invocation construct with id IC_Id
+ procedure Write_Invocation_Graph_Attributes;
+ pragma Inline (Write_Invocation_Graph_Attributes);
+ -- Write out the attributes of the invocation graph
- function Target
- (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id;
- pragma Inline (Target);
- -- Obtain attribute Target of an invocation relation with id IR_Id
+ procedure Write_Invocation_Relation (IR_Id : Invocation_Relation_Id);
+ pragma Inline (Write_Invocation_Relation);
+ -- Write invocation relation IR_Id to the ALI file
+
+ procedure Write_Invocation_Signature (IS_Id : Invocation_Signature_Id);
+ pragma Inline (Write_Invocation_Signature);
+ -- Write invocation signature IS_Id to the ALI file
procedure Write_Unit_Name (N : Node_Id);
-- Used to write out the unit name for R (pragma Restriction) lines
@@ -161,16 +128,6 @@ package body Lib.Writ is
OA_Setting => 'O');
end Add_Preprocessing_Dependency;
- ------------
- -- Column --
- ------------
-
- function Column (IS_Id : Invocation_Signature_Id) return Nat is
- begin
- pragma Assert (Present (IS_Id));
- return Invocation_Signatures.Table (IS_Id).Column;
- end Column;
-
------------------------------
-- Ensure_System_Dependency --
------------------------------
@@ -186,7 +143,7 @@ package body Lib.Writ is
-- Nothing to do if we already compiled System
for Unum in Units.First .. Last_Unit loop
- if Units.Table (Unum).Source_Index = System_Source_File_Index then
+ if Source_Index (Unum) = System_Source_File_Index then
return;
end if;
end loop;
@@ -252,92 +209,6 @@ package body Lib.Writ is
end;
end Ensure_System_Dependency;
- -----------
- -- Extra --
- -----------
-
- function Extra (IR_Id : Invocation_Relation_Id) return Name_Id is
- begin
- pragma Assert (Present (IR_Id));
- return Invocation_Relations.Table (IR_Id).Extra;
- end Extra;
-
- -------------
- -- Invoker --
- -------------
-
- function Invoker
- (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id
- is
- begin
- pragma Assert (Present (IR_Id));
- return Invocation_Relations.Table (IR_Id).Invoker;
- end Invoker;
-
- ----------
- -- Kind --
- ----------
-
- function Kind
- (IC_Id : Invocation_Construct_Id) return Invocation_Construct_Kind
- is
- begin
- pragma Assert (Present (IC_Id));
- return Invocation_Constructs.Table (IC_Id).Kind;
- end Kind;
-
- ----------
- -- Kind --
- ----------
-
- function Kind (IR_Id : Invocation_Relation_Id) return Invocation_Kind is
- begin
- pragma Assert (Present (IR_Id));
- return Invocation_Relations.Table (IR_Id).Kind;
- end Kind;
-
- ----------
- -- Line --
- ----------
-
- function Line (IS_Id : Invocation_Signature_Id) return Nat is
- begin
- pragma Assert (Present (IS_Id));
- return Invocation_Signatures.Table (IS_Id).Line;
- end Line;
-
- ---------------
- -- Locations --
- ---------------
-
- function Locations (IS_Id : Invocation_Signature_Id) return Name_Id is
- begin
- pragma Assert (Present (IS_Id));
- return Invocation_Signatures.Table (IS_Id).Locations;
- end Locations;
-
- ----------
- -- Name --
- ----------
-
- function Name (IS_Id : Invocation_Signature_Id) return Name_Id is
- begin
- pragma Assert (Present (IS_Id));
- return Invocation_Signatures.Table (IS_Id).Name;
- end Name;
-
- ---------------
- -- Placement --
- ---------------
-
- function Placement
- (IC_Id : Invocation_Construct_Id) return Body_Placement_Kind
- is
- begin
- pragma Assert (Present (IC_Id));
- return Invocation_Constructs.Table (IC_Id).Placement;
- end Placement;
-
-------------
-- Present --
-------------
@@ -347,40 +218,6 @@ package body Lib.Writ is
return N_Id /= No_Name;
end Present;
- -----------
- -- Scope --
- -----------
-
- function Scope (IS_Id : Invocation_Signature_Id) return Name_Id is
- begin
- pragma Assert (Present (IS_Id));
- return Invocation_Signatures.Table (IS_Id).Scope;
- end Scope;
-
- ---------------
- -- Signature --
- ---------------
-
- function Signature
- (IC_Id : Invocation_Construct_Id) return Invocation_Signature_Id
- is
- begin
- pragma Assert (Present (IC_Id));
- return Invocation_Constructs.Table (IC_Id).Signature;
- end Signature;
-
- ------------
- -- Target --
- ------------
-
- function Target
- (IR_Id : Invocation_Relation_Id) return Invocation_Signature_Id
- is
- begin
- pragma Assert (Present (IR_Id));
- return Invocation_Relations.Table (IR_Id).Target;
- end Target;
-
---------------
-- Write_ALI --
---------------
@@ -441,9 +278,6 @@ package body Lib.Writ is
-- this file (using Scan_ALI) and returns True. If no file exists,
-- or the file is not up to date, then False is returned.
- procedure Write_Invocation_Graph;
- -- Write out the invocation graph
-
procedure Write_Unit_Information (Unit_Num : Unit_Number_Type);
-- Write out the library information for one unit for which code is
-- generated (includes unit line and with lines).
@@ -597,7 +431,7 @@ package body Lib.Writ is
Id := First_Sdep_Entry;
for J in 1 .. Num_Sdep loop
- Sind := Units.Table (Sdep_Table (J)).Source_Index;
+ Sind := Source_Index (Sdep_Table (J));
while Sdep.Table (Id).Sfile /= File_Name (Sind) loop
if Id = Sdep.Last then
@@ -633,175 +467,6 @@ package body Lib.Writ is
end Update_Tables_From_ALI_File;
----------------------------
- -- Write_Invocation_Graph --
- ----------------------------
-
- procedure Write_Invocation_Graph is
- procedure Write_Invocation_Construct
- (IC_Id : Invocation_Construct_Id);
- pragma Inline (Write_Invocation_Construct);
- -- Write invocation construct IC_Id to the ALI file
-
- procedure Write_Invocation_Relation (IR_Id : Invocation_Relation_Id);
- pragma Inline (Write_Invocation_Relation);
- -- Write invocation relation IR_Id to the ALI file
-
- procedure Write_Invocation_Signature
- (IS_Id : Invocation_Signature_Id);
- pragma Inline (Write_Invocation_Signature);
- -- Write invocation signature IS_Id to the ALI file
-
- --------------------------------
- -- Write_Invocation_Construct --
- --------------------------------
-
- procedure Write_Invocation_Construct
- (IC_Id : Invocation_Construct_Id)
- is
- begin
- -- G header
-
- Write_Info_Initiate ('G');
- Write_Info_Char (' ');
-
- -- line-kind
-
- Write_Info_Char
- (Invocation_Graph_Line_Kind_To_Code (Invocation_Construct_Line));
- Write_Info_Char (' ');
-
- -- construct-kind
-
- Write_Info_Char (Invocation_Construct_Kind_To_Code (Kind (IC_Id)));
- Write_Info_Char (' ');
-
- -- construct-body-placement
-
- Write_Info_Char (Body_Placement_Kind_To_Code (Placement (IC_Id)));
- Write_Info_Char (' ');
-
- -- construct-signature
-
- Write_Invocation_Signature (Signature (IC_Id));
- Write_Info_EOL;
- end Write_Invocation_Construct;
-
- -------------------------------
- -- Write_Invocation_Relation --
- -------------------------------
-
- procedure Write_Invocation_Relation
- (IR_Id : Invocation_Relation_Id)
- is
- begin
- -- G header
-
- Write_Info_Initiate ('G');
- Write_Info_Char (' ');
-
- -- line-kind
-
- Write_Info_Char
- (Invocation_Graph_Line_Kind_To_Code (Invocation_Relation_Line));
- Write_Info_Char (' ');
-
- -- relation-kind
-
- Write_Info_Char (Invocation_Kind_To_Code (Kind (IR_Id)));
- Write_Info_Char (' ');
-
- -- (extra-name | "none")
-
- if Present (Extra (IR_Id)) then
- Write_Info_Name (Extra (IR_Id));
- else
- Write_Info_Str ("none");
- end if;
-
- Write_Info_Char (' ');
-
- -- invoker-signature
-
- Write_Invocation_Signature (Invoker (IR_Id));
- Write_Info_Char (' ');
-
- -- target-signature
-
- Write_Invocation_Signature (Target (IR_Id));
-
- Write_Info_EOL;
- end Write_Invocation_Relation;
-
- --------------------------------
- -- Write_Invocation_Signature --
- --------------------------------
-
- procedure Write_Invocation_Signature
- (IS_Id : Invocation_Signature_Id)
- is
- begin
- -- [
-
- Write_Info_Char ('[');
-
- -- name
-
- Write_Info_Name (Name (IS_Id));
- Write_Info_Char (' ');
-
- -- scope
-
- Write_Info_Name (Scope (IS_Id));
- Write_Info_Char (' ');
-
- -- line
-
- Write_Info_Nat (Line (IS_Id));
- Write_Info_Char (' ');
-
- -- column
-
- Write_Info_Nat (Column (IS_Id));
- Write_Info_Char (' ');
-
- -- (locations | "none")
-
- if Present (Locations (IS_Id)) then
- Write_Info_Name (Locations (IS_Id));
- else
- Write_Info_Str ("none");
- end if;
-
- -- ]
-
- Write_Info_Char (']');
- end Write_Invocation_Signature;
-
- -- Start of processing for Write_Invocation_Graph
-
- begin
- -- First write out all invocation constructs declared within the
- -- current unit. This ensures that when this invocation is read,
- -- the invocation constructs are materialized before they are
- -- referenced by invocation relations.
-
- for IC_Id in Invocation_Constructs.First ..
- Invocation_Constructs.Last
- loop
- Write_Invocation_Construct (IC_Id);
- end loop;
-
- -- Write out all invocation relations that originate from invocation
- -- constructs delared in the current unit.
-
- for IR_Id in Invocation_Relations.First ..
- Invocation_Relations.Last
- loop
- Write_Invocation_Relation (IR_Id);
- end loop;
- end Write_Invocation_Graph;
-
- ----------------------------
-- Write_Unit_Information --
----------------------------
@@ -1416,7 +1081,7 @@ package body Lib.Writ is
begin
-- We never write an ALI file if the original operating mode was
- -- syntax-only (-gnats switch used in compiler invocation line)
+ -- syntax-only (-gnats switch used in compiler invocation line).
if Original_Operating_Mode = Check_Syntax then
return;
@@ -1898,7 +1563,7 @@ package body Lib.Writ is
for J in 1 .. Num_Sdep loop
Unum := Sdep_Table (J);
Units.Table (Unum).Dependency_Num := J;
- Sind := Units.Table (Unum).Source_Index;
+ Sind := Source_Index (Unum);
Write_Info_Initiate ('D');
Write_Info_Char (' ');
@@ -2010,6 +1675,179 @@ package body Lib.Writ is
Close_Output_Library_Info;
end Write_ALI;
+ --------------------------------
+ -- Write_Invocation_Construct --
+ --------------------------------
+
+ procedure Write_Invocation_Construct (IC_Id : Invocation_Construct_Id) is
+ begin
+ -- G header
+
+ Write_Info_Initiate ('G');
+ Write_Info_Char (' ');
+
+ -- line-kind
+
+ Write_Info_Char
+ (Invocation_Graph_Line_Kind_To_Code (Invocation_Construct_Line));
+ Write_Info_Char (' ');
+
+ -- construct-kind
+
+ Write_Info_Char (Invocation_Construct_Kind_To_Code (Kind (IC_Id)));
+ Write_Info_Char (' ');
+
+ -- construct-spec-placement
+
+ Write_Info_Char
+ (Declaration_Placement_Kind_To_Code (Spec_Placement (IC_Id)));
+ Write_Info_Char (' ');
+
+ -- construct-body-placement
+
+ Write_Info_Char
+ (Declaration_Placement_Kind_To_Code (Body_Placement (IC_Id)));
+ Write_Info_Char (' ');
+
+ -- construct-signature
+
+ Write_Invocation_Signature (Signature (IC_Id));
+ Write_Info_EOL;
+ end Write_Invocation_Construct;
+
+ ---------------------------------------
+ -- Write_Invocation_Graph_Attributes --
+ ---------------------------------------
+
+ procedure Write_Invocation_Graph_Attributes is
+ begin
+ -- G header
+
+ Write_Info_Initiate ('G');
+ Write_Info_Char (' ');
+
+ -- line-kind
+
+ Write_Info_Char
+ (Invocation_Graph_Line_Kind_To_Code
+ (Invocation_Graph_Attributes_Line));
+ Write_Info_Char (' ');
+
+ -- encoding-kind
+
+ Write_Info_Char
+ (Invocation_Graph_Encoding_Kind_To_Code (Invocation_Graph_Encoding));
+ Write_Info_EOL;
+ end Write_Invocation_Graph_Attributes;
+
+ ----------------------------
+ -- Write_Invocation_Graph --
+ ----------------------------
+
+ procedure Write_Invocation_Graph is
+ begin
+ Write_Invocation_Graph_Attributes;
+
+ -- First write out all invocation constructs declared within the current
+ -- unit. This ensures that when this invocation is read, the invocation
+ -- constructs are materialized before they are referenced by invocation
+ -- relations.
+
+ For_Each_Invocation_Construct (Write_Invocation_Construct'Access);
+
+ -- Write out all invocation relations that originate from invocation
+ -- constructs delared in the current unit.
+
+ For_Each_Invocation_Relation (Write_Invocation_Relation'Access);
+ end Write_Invocation_Graph;
+
+ -------------------------------
+ -- Write_Invocation_Relation --
+ -------------------------------
+
+ procedure Write_Invocation_Relation (IR_Id : Invocation_Relation_Id) is
+ begin
+ -- G header
+
+ Write_Info_Initiate ('G');
+ Write_Info_Char (' ');
+
+ -- line-kind
+
+ Write_Info_Char
+ (Invocation_Graph_Line_Kind_To_Code (Invocation_Relation_Line));
+ Write_Info_Char (' ');
+
+ -- relation-kind
+
+ Write_Info_Char (Invocation_Kind_To_Code (Kind (IR_Id)));
+ Write_Info_Char (' ');
+
+ -- (extra-name | "none")
+
+ if Present (Extra (IR_Id)) then
+ Write_Info_Name (Extra (IR_Id));
+ else
+ Write_Info_Str ("none");
+ end if;
+
+ Write_Info_Char (' ');
+
+ -- invoker-signature
+
+ Write_Invocation_Signature (Invoker (IR_Id));
+ Write_Info_Char (' ');
+
+ -- target-signature
+
+ Write_Invocation_Signature (Target (IR_Id));
+
+ Write_Info_EOL;
+ end Write_Invocation_Relation;
+
+ --------------------------------
+ -- Write_Invocation_Signature --
+ --------------------------------
+
+ procedure Write_Invocation_Signature (IS_Id : Invocation_Signature_Id) is
+ begin
+ -- [
+
+ Write_Info_Char ('[');
+
+ -- name
+
+ Write_Info_Name (Name (IS_Id));
+ Write_Info_Char (' ');
+
+ -- scope
+
+ Write_Info_Name (Scope (IS_Id));
+ Write_Info_Char (' ');
+
+ -- line
+
+ Write_Info_Nat (Line (IS_Id));
+ Write_Info_Char (' ');
+
+ -- column
+
+ Write_Info_Nat (Column (IS_Id));
+ Write_Info_Char (' ');
+
+ -- (locations | "none")
+
+ if Present (Locations (IS_Id)) then
+ Write_Info_Name (Locations (IS_Id));
+ else
+ Write_Info_Str ("none");
+ end if;
+
+ -- ]
+
+ Write_Info_Char (']');
+ end Write_Invocation_Signature;
+
---------------------
-- Write_Unit_Name --
---------------------
diff --git a/gcc/ada/lib-writ.ads b/gcc/ada/lib-writ.ads
index c17233a..7248a61 100644
--- a/gcc/ada/lib-writ.ads
+++ b/gcc/ada/lib-writ.ads
@@ -880,18 +880,32 @@ package Lib.Writ is
-- locations of all instances where the initial declaration of the
-- construct appears.
--
+ -- When the line-kind denotes invocation graph attributes, line-attributes
+ -- are set as follows:
+ --
+ -- encoding-kind
+ --
+ -- Attribute encoding-kind is a Character which specifies the encoding
+ -- kind used when collecting invocation constructs and relations. Table
+ -- ALI.Invocation_Graph_Encoding_Codes lists all legal values.
+ --
-- When the line-kind denotes an invocation construct, line-attributes are
-- set as follows:
--
- -- construct-kind construct-body-placement construct-signature
+ -- construct-kind construct-spec-placement construct-body-placement
+ -- construct-signature
--
-- Attribute construct-kind is a Character which denotes the nature of
-- the construct. Table ALI.Invocation_Construct_Codes lists all legal
-- values.
--
+ -- Attribute construct-spec-placement is a Character which denotes the
+ -- placement of the construct's spec within the unit. All legal values
+ -- are listed in table ALI.Spec_And_Body_Placement_Codes.
+ --
-- Attribute construct-body-placement is a Character which denotes the
-- placement of the construct's body within the unit. All legal values
- -- are listed in table ALI.Body_Placement_Codes.
+ -- are listed in table ALI.Spec_And_Body_Placement_Codes.
--
-- Attribute construct-signature is the invocation signature of the
-- construct.
@@ -925,7 +939,7 @@ package Lib.Writ is
-- Postcondition_Verification - related routine
-- Protected_Entry_Call - not present
-- Protected_Subprogram_Call - not present
- -- Task_Activation - related task object
+ -- Task_Activation - not present
-- Task_Entry_Call - not present
-- Type_Initialization - related type
--
diff --git a/gcc/ada/lib-xref-spark_specific.adb b/gcc/ada/lib-xref-spark_specific.adb
index 36aaefb..0ad7044 100644
--- a/gcc/ada/lib-xref-spark_specific.adb
+++ b/gcc/ada/lib-xref-spark_specific.adb
@@ -298,6 +298,7 @@ package body SPARK_Specific is
Set_Ekind (Heap, E_Variable);
Set_Is_Internal (Heap, True);
+ Set_Etype (Heap, Standard_Void_Type);
Set_Scope (Heap, Standard_Standard);
Set_Has_Fully_Qualified_Name (Heap);
end Create_Heap;
diff --git a/gcc/ada/lib.ads b/gcc/ada/lib.ads
index c6c11c1..504120e 100644
--- a/gcc/ada/lib.ads
+++ b/gcc/ada/lib.ads
@@ -993,7 +993,7 @@ private
-- clause. The First entry is the main unit. The second entry, if present
-- is a unit on which the first unit depends, etc. This stack is used to
-- generate error messages showing the dependency chain if a file is not
- -- found, or whether a true circular dependency exists. The Load_Unit
+ -- found, or whether a true circular dependency exists. The Load_Unit
-- function makes an entry in this table when it is called, and removes
-- the entry just before it returns.
diff --git a/gcc/ada/libgnarl/a-taside.ads b/gcc/ada/libgnarl/a-taside.ads
index 4939d1e..6bdb252 100644
--- a/gcc/ada/libgnarl/a-taside.ads
+++ b/gcc/ada/libgnarl/a-taside.ads
@@ -33,6 +33,12 @@
-- --
------------------------------------------------------------------------------
+-- Preconditions in this unit are meant for analysis only, not for run-time
+-- checking, so that the expected exceptions are raised.
+-- This is enforced by setting the corresponding assertion policy to Ignore.
+
+pragma Assertion_Policy (Pre => Ignore);
+
with System;
with System.Tasking;
@@ -67,17 +73,20 @@ is
pragma Inline (Environment_Task);
procedure Abort_Task (T : Task_Id) with
+ Pre => T /= Null_Task_Id,
Global => null;
pragma Inline (Abort_Task);
-- Note: parameter is mode IN, not IN OUT, per AI-00101
function Is_Terminated (T : Task_Id) return Boolean with
Volatile_Function,
+ Pre => T /= Null_Task_Id,
Global => Tasking_State;
pragma Inline (Is_Terminated);
function Is_Callable (T : Task_Id) return Boolean with
Volatile_Function,
+ Pre => T /= Null_Task_Id,
Global => Tasking_State;
pragma Inline (Is_Callable);
diff --git a/gcc/ada/libgnarl/g-thread.adb b/gcc/ada/libgnarl/g-thread.adb
index f4ce92e..ae61937 100644
--- a/gcc/ada/libgnarl/g-thread.adb
+++ b/gcc/ada/libgnarl/g-thread.adb
@@ -168,9 +168,14 @@ package body GNAT.Threads is
----------------
procedure Get_Thread (Id : Address; Thread : Address) is
- Thr : constant Thread_Id_Ptr := To_Thread (Thread);
begin
- Thr.all := Task_Primitives.Operations.Get_Thread_Id (To_Id (Id));
+ To_Thread (Thread).all :=
+ Task_Primitives.Operations.Get_Thread_Id (To_Id (Id));
+ end Get_Thread;
+
+ procedure Get_Thread (Id : Task_Id; Thread : Address) is
+ begin
+ Get_Thread (To_Addr (Id), Thread);
end Get_Thread;
----------------------
diff --git a/gcc/ada/libgnarl/g-thread.ads b/gcc/ada/libgnarl/g-thread.ads
index ad4a075..8792e9a 100644
--- a/gcc/ada/libgnarl/g-thread.ads
+++ b/gcc/ada/libgnarl/g-thread.ads
@@ -129,9 +129,11 @@ package GNAT.Threads is
procedure Get_Thread (Id : System.Address; Thread : System.Address);
pragma Export (C, Get_Thread, "__gnat_get_thread");
+ procedure Get_Thread
+ (Id : Ada.Task_Identification.Task_Id; Thread : System.Address);
-- This procedure is used to retrieve the thread id of a given task.
-- The value Id is the value that was passed to the thread code procedure
- -- at activation time.
+ -- at activation time or a Task_Id.
-- Thread is a pointer to a thread id that will be updated by this
-- procedure.
--
diff --git a/gcc/ada/libgnarl/s-linux.ads b/gcc/ada/libgnarl/s-linux.ads
index 94c2ea1..4220fa0 100644
--- a/gcc/ada/libgnarl/s-linux.ads
+++ b/gcc/ada/libgnarl/s-linux.ads
@@ -82,7 +82,7 @@ package System.Linux is
SIGILL : constant := 4; -- illegal instruction (not reset)
SIGTRAP : constant := 5; -- trace trap (not reset)
SIGIOT : constant := 6; -- IOT instruction
- SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
SIGFPE : constant := 8; -- floating point exception
SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
SIGBUS : constant := 7; -- bus error
diff --git a/gcc/ada/libgnarl/s-linux__alpha.ads b/gcc/ada/libgnarl/s-linux__alpha.ads
index 18a1253..fea3746 100644
--- a/gcc/ada/libgnarl/s-linux__alpha.ads
+++ b/gcc/ada/libgnarl/s-linux__alpha.ads
@@ -82,7 +82,7 @@ package System.Linux is
SIGILL : constant := 4; -- illegal instruction (not reset)
SIGTRAP : constant := 5; -- trace trap (not reset)
SIGIOT : constant := 6; -- IOT instruction
- SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
SIGFPE : constant := 8; -- floating point exception
SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
SIGBUS : constant := 10; -- bus error
diff --git a/gcc/ada/libgnarl/s-linux__android.ads b/gcc/ada/libgnarl/s-linux__android.ads
index 914f08d..8d8a1f4 100644
--- a/gcc/ada/libgnarl/s-linux__android.ads
+++ b/gcc/ada/libgnarl/s-linux__android.ads
@@ -82,7 +82,7 @@ package System.Linux is
SIGILL : constant := 4; -- illegal instruction (not reset)
SIGTRAP : constant := 5; -- trace trap (not reset)
SIGIOT : constant := 6; -- IOT instruction
- SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
SIGFPE : constant := 8; -- floating point exception
SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
SIGBUS : constant := 7; -- bus error
diff --git a/gcc/ada/libgnarl/s-linux__hppa.ads b/gcc/ada/libgnarl/s-linux__hppa.ads
index bc7034a..feb21f6 100644
--- a/gcc/ada/libgnarl/s-linux__hppa.ads
+++ b/gcc/ada/libgnarl/s-linux__hppa.ads
@@ -82,7 +82,7 @@ package System.Linux is
SIGILL : constant := 4; -- illegal instruction (not reset)
SIGTRAP : constant := 5; -- trace trap (not reset)
SIGIOT : constant := 6; -- IOT instruction
- SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
SIGEMT : constant := 7; -- EMT
SIGFPE : constant := 8; -- floating point exception
SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
diff --git a/gcc/ada/libgnarl/s-linux__mips.ads b/gcc/ada/libgnarl/s-linux__mips.ads
index 0fa808f..6aea5a8 100644
--- a/gcc/ada/libgnarl/s-linux__mips.ads
+++ b/gcc/ada/libgnarl/s-linux__mips.ads
@@ -82,7 +82,7 @@ package System.Linux is
SIGILL : constant := 4; -- illegal instruction (not reset)
SIGTRAP : constant := 5; -- trace trap (not reset)
SIGIOT : constant := 6; -- IOT instruction
- SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
SIGEMT : constant := 7; -- EMT
SIGFPE : constant := 8; -- floating point exception
SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
diff --git a/gcc/ada/libgnarl/s-linux__riscv.ads b/gcc/ada/libgnarl/s-linux__riscv.ads
index 6151b29..61ccc3b 100644
--- a/gcc/ada/libgnarl/s-linux__riscv.ads
+++ b/gcc/ada/libgnarl/s-linux__riscv.ads
@@ -82,7 +82,7 @@ package System.Linux is
SIGILL : constant := 4; -- illegal instruction (not reset)
SIGTRAP : constant := 5; -- trace trap (not reset)
SIGIOT : constant := 6; -- IOT instruction
- SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
SIGBUS : constant := 7; -- bus error
SIGFPE : constant := 8; -- floating point exception
SIGKILL : constant := 9; -- kill (cannot be caught or ignored)
diff --git a/gcc/ada/libgnarl/s-linux__sparc.ads b/gcc/ada/libgnarl/s-linux__sparc.ads
index de31105..e619890 100644
--- a/gcc/ada/libgnarl/s-linux__sparc.ads
+++ b/gcc/ada/libgnarl/s-linux__sparc.ads
@@ -81,7 +81,7 @@ package System.Linux is
SIGQUIT : constant := 3; -- quit (ASCD FS)
SIGILL : constant := 4; -- illegal instruction (not reset)
SIGTRAP : constant := 5; -- trace trap (not reset)
- SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
+ SIGABRT : constant := 6; -- used by abort, replace SIGIOT in the future
SIGIOT : constant := 6; -- IOT instruction
SIGEMT : constant := 7; -- EMT
SIGFPE : constant := 8; -- floating point exception
diff --git a/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads b/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads
index f46bbda..aa6c1a8 100644
--- a/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads
+++ b/gcc/ada/libgnarl/s-osinte__kfreebsd-gnu.ads
@@ -206,9 +206,8 @@ package System.OS_Interface is
function nanosleep (rqtp, rmtp : access timespec) return int;
pragma Import (C, nanosleep, "nanosleep");
- type clockid_t is private;
-
- CLOCK_REALTIME : constant clockid_t;
+ type clockid_t is new int;
+ CLOCK_REALTIME : constant clockid_t := 0;
function clock_gettime
(clock_id : clockid_t;
@@ -607,9 +606,6 @@ private
end record;
pragma Convention (C, timespec);
- type clockid_t is new int;
- CLOCK_REALTIME : constant clockid_t := 0;
-
type pthread_attr_t is record
detachstate : int;
schedpolicy : int;
diff --git a/gcc/ada/libgnarl/s-osinte__linux.ads b/gcc/ada/libgnarl/s-osinte__linux.ads
index ba3b824..80cb2b2 100644
--- a/gcc/ada/libgnarl/s-osinte__linux.ads
+++ b/gcc/ada/libgnarl/s-osinte__linux.ads
@@ -46,10 +46,11 @@ with System.OS_Constants;
package System.OS_Interface is
pragma Preelaborate;
- pragma Linker_Options ("-lpthread");
pragma Linker_Options ("-lrt");
-- Needed for clock_getres with glibc versions prior to 2.17
+ pragma Linker_Options ("-lpthread");
+
subtype int is Interfaces.C.int;
subtype char is Interfaces.C.char;
subtype short is Interfaces.C.short;
diff --git a/gcc/ada/libgnarl/s-osinte__mingw.ads b/gcc/ada/libgnarl/s-osinte__mingw.ads
index 2cf47b7..2a98664 100644
--- a/gcc/ada/libgnarl/s-osinte__mingw.ads
+++ b/gcc/ada/libgnarl/s-osinte__mingw.ads
@@ -369,7 +369,7 @@ private
-- section for the resource.
LockSemaphore : Win32.HANDLE;
- SpinCount : Win32.DWORD;
+ SpinCount : Interfaces.C.size_t;
end record;
end System.OS_Interface;
diff --git a/gcc/ada/libgnat/a-cfhama.adb b/gcc/ada/libgnat/a-cfhama.adb
index 2cdde01..580ca12 100644
--- a/gcc/ada/libgnat/a-cfhama.adb
+++ b/gcc/ada/libgnat/a-cfhama.adb
@@ -509,8 +509,11 @@ is
procedure Free (HT : in out Map; X : Count_Type) is
begin
- HT.Nodes (X).Has_Element := False;
- HT_Ops.Free (HT, X);
+ if X /= 0 then
+ pragma Assert (X <= HT.Capacity);
+ HT.Nodes (X).Has_Element := False;
+ HT_Ops.Free (HT, X);
+ end if;
end Free;
----------------------
diff --git a/gcc/ada/libgnat/a-cfhase.adb b/gcc/ada/libgnat/a-cfhase.adb
index ae8ae12..8cc220c 100644
--- a/gcc/ada/libgnat/a-cfhase.adb
+++ b/gcc/ada/libgnat/a-cfhase.adb
@@ -760,8 +760,11 @@ is
procedure Free (HT : in out Set; X : Count_Type) is
begin
- HT.Nodes (X).Has_Element := False;
- HT_Ops.Free (HT, X);
+ if X /= 0 then
+ pragma Assert (X <= HT.Capacity);
+ HT.Nodes (X).Has_Element := False;
+ HT_Ops.Free (HT, X);
+ end if;
end Free;
----------------------
diff --git a/gcc/ada/libgnat/a-cofove.adb b/gcc/ada/libgnat/a-cofove.adb
index f9675ab..c848ad8 100644
--- a/gcc/ada/libgnat/a-cofove.adb
+++ b/gcc/ada/libgnat/a-cofove.adb
@@ -26,7 +26,6 @@
------------------------------------------------------------------------------
with Ada.Containers.Generic_Array_Sort;
-with Ada.Unchecked_Deallocation;
with System; use type System.Address;
@@ -34,41 +33,10 @@ package body Ada.Containers.Formal_Vectors with
SPARK_Mode => Off
is
- Growth_Factor : constant := 2;
- -- When growing a container, multiply current capacity by this. Doubling
- -- leads to amortized linear-time copying.
-
type Int is range System.Min_Int .. System.Max_Int;
- procedure Free is
- new Ada.Unchecked_Deallocation (Elements_Array, Elements_Array_Ptr);
-
- type Maximal_Array_Ptr is access all Elements_Array (Array_Index)
- with Storage_Size => 0;
- type Maximal_Array_Ptr_Const is access constant Elements_Array (Array_Index)
- with Storage_Size => 0;
-
- function Elems (Container : in out Vector) return Maximal_Array_Ptr;
- function Elemsc
- (Container : Vector) return Maximal_Array_Ptr_Const;
- -- Returns a pointer to the Elements array currently in use -- either
- -- Container.Elements_Ptr or a pointer to Container.Elements. We work with
- -- pointers to a bogus array subtype that is constrained with the maximum
- -- possible bounds. This means that the pointer is a thin pointer. This is
- -- necessary because 'Unrestricted_Access doesn't work when it produces
- -- access-to-unconstrained and is returned from a function.
- --
- -- Note that this is dangerous: make sure calls to this use an indexed
- -- component or slice that is within the bounds 1 .. Length (Container).
-
- function Get_Element
- (Container : Vector;
- Position : Capacity_Range) return Element_Type;
-
function To_Array_Index (Index : Index_Type'Base) return Count_Type'Base;
- function Current_Capacity (Container : Vector) return Capacity_Range;
-
procedure Insert_Space
(Container : in out Vector;
Before : Extended_Index;
@@ -89,7 +57,7 @@ is
end if;
for J in 1 .. Length (Left) loop
- if Get_Element (Left, J) /= Get_Element (Right, J) then
+ if Left.Elements (J) /= Right.Elements (J) then
return False;
end if;
end loop;
@@ -148,7 +116,7 @@ is
return;
end if;
- if Bounded and then Target.Capacity < LS then
+ if Target.Capacity < LS then
raise Constraint_Error;
end if;
@@ -162,11 +130,7 @@ is
function Capacity (Container : Vector) return Capacity_Range is
begin
- return
- (if Bounded then
- Container.Capacity
- else
- Capacity_Range'Last);
+ return Container.Capacity;
end Capacity;
-----------
@@ -176,10 +140,6 @@ is
procedure Clear (Container : in out Vector) is
begin
Container.Last := No_Index;
-
- -- Free element, note that this is OK if Elements_Ptr is null
-
- Free (Container.Elements_Ptr);
end Clear;
--------------
@@ -215,24 +175,11 @@ is
end if;
return Target : Vector (C) do
- Elems (Target) (1 .. LS) := Elemsc (Source) (1 .. LS);
+ Target.Elements (1 .. LS) := Source.Elements (1 .. LS);
Target.Last := Source.Last;
end return;
end Copy;
- ----------------------
- -- Current_Capacity --
- ----------------------
-
- function Current_Capacity (Container : Vector) return Capacity_Range is
- begin
- return
- (if Container.Elements_Ptr = null then
- Container.Elements'Length
- else
- Container.Elements_Ptr.all'Length);
- end Current_Capacity;
-
------------
-- Delete --
------------
@@ -333,7 +280,7 @@ is
-- so we just slide down to Index the elements that weren't deleted.
declare
- EA : Maximal_Array_Ptr renames Elems (Container);
+ EA : Elements_Array renames Container.Elements;
Idx : constant Count_Type := EA'First + Off;
begin
EA (Idx .. Old_Len - Count) := EA (Idx + Count .. Old_Len);
@@ -418,32 +365,10 @@ is
II : constant Int'Base := Int (Index) - Int (No_Index);
I : constant Capacity_Range := Capacity_Range (II);
begin
- return Get_Element (Container, I);
+ return Container.Elements (I);
end;
end Element;
- -----------
- -- Elems --
- -----------
-
- function Elems (Container : in out Vector) return Maximal_Array_Ptr is
- begin
- return
- (if Container.Elements_Ptr = null then
- Container.Elements'Unrestricted_Access
- else
- Container.Elements_Ptr.all'Unrestricted_Access);
- end Elems;
-
- function Elemsc (Container : Vector) return Maximal_Array_Ptr_Const is
- begin
- return
- (if Container.Elements_Ptr = null then
- Container.Elements'Unrestricted_Access
- else
- Container.Elements_Ptr.all'Unrestricted_Access);
- end Elemsc;
-
----------------
-- Find_Index --
----------------
@@ -459,7 +384,7 @@ is
begin
K := Capacity_Range (Int (Index) - Int (No_Index));
for Indx in Index .. Last loop
- if Get_Element (Container, K) = Item then
+ if Container.Elements (K) = Item then
return Indx;
end if;
@@ -478,7 +403,7 @@ is
if Is_Empty (Container) then
raise Constraint_Error with "Container is empty";
else
- return Get_Element (Container, 1);
+ return Container.Elements (1);
end if;
end First_Element;
@@ -622,7 +547,7 @@ is
begin
for Position in 1 .. Length (Container) loop
- R := M.Add (R, Elemsc (Container) (Position));
+ R := M.Add (R, Container.Elements (Position));
end loop;
return R;
@@ -684,8 +609,8 @@ is
begin
for J in 1 .. L - 1 loop
- if Get_Element (Container, J + 1) <
- Get_Element (Container, J)
+ if Container.Elements (J + 1) <
+ Container.Elements (J)
then
return False;
end if;
@@ -712,7 +637,7 @@ is
if Container.Last <= Index_Type'First then
return;
else
- Sort (Elems (Container) (1 .. Len));
+ Sort (Container.Elements (1 .. Len));
end if;
end Sort;
@@ -744,16 +669,6 @@ is
New_Length : constant Count_Type := I + Length (Source);
begin
- if not Bounded
- and then Current_Capacity (Target) < Capacity_Range (New_Length)
- then
- Reserve_Capacity
- (Target,
- Capacity_Range'Max
- (Current_Capacity (Target) * Growth_Factor,
- Capacity_Range (New_Length)));
- end if;
-
if Index_Type'Base'Last >= Count_Type'Pos (Count_Type'Last) then
Target.Last := No_Index + Index_Type'Base (New_Length);
@@ -764,8 +679,8 @@ is
end;
declare
- TA : Maximal_Array_Ptr renames Elems (Target);
- SA : Maximal_Array_Ptr renames Elems (Source);
+ TA : Elements_Array renames Target.Elements;
+ SA : Elements_Array renames Source.Elements;
begin
J := Length (Target);
@@ -793,18 +708,6 @@ is
end Generic_Sorting;
-----------------
- -- Get_Element --
- -----------------
-
- function Get_Element
- (Container : Vector;
- Position : Capacity_Range) return Element_Type
- is
- begin
- return Elemsc (Container) (Position);
- end Get_Element;
-
- -----------------
-- Has_Element --
-----------------
@@ -844,7 +747,7 @@ is
J := To_Array_Index (Before);
- Elems (Container) (J .. J - 1 + Count) := (others => New_Item);
+ Container.Elements (J .. J - 1 + Count) := (others => New_Item);
end Insert;
procedure Insert
@@ -876,7 +779,7 @@ is
B := To_Array_Index (Before);
- Elems (Container) (B .. B + N - 1) := Elemsc (New_Item) (1 .. N);
+ Container.Elements (B .. B + N - 1) := New_Item.Elements (1 .. N);
end Insert;
------------------
@@ -1053,19 +956,8 @@ is
J := To_Array_Index (Before);
- -- Increase the capacity of container if needed
-
- if not Bounded
- and then Current_Capacity (Container) < Capacity_Range (New_Length)
- then
- Reserve_Capacity
- (Container,
- Capacity_Range'Max (Current_Capacity (Container) * Growth_Factor,
- Capacity_Range (New_Length)));
- end if;
-
declare
- EA : Maximal_Array_Ptr renames Elems (Container);
+ EA : Elements_Array renames Container.Elements;
begin
if Before <= Container.Last then
@@ -1105,7 +997,7 @@ is
if Is_Empty (Container) then
raise Constraint_Error with "Container is empty";
else
- return Get_Element (Container, Length (Container));
+ return Container.Elements (Length (Container));
end if;
end Last_Element;
@@ -1143,7 +1035,7 @@ is
return;
end if;
- if Bounded and then Target.Capacity < LS then
+ if Target.Capacity < LS then
raise Constraint_Error;
end if;
@@ -1194,7 +1086,7 @@ is
I : constant Capacity_Range := Capacity_Range (II);
begin
- Elems (Container) (I) := New_Item;
+ Container.Elements (I) := New_Item;
end;
end Replace_Element;
@@ -1207,24 +1099,8 @@ is
Capacity : Capacity_Range)
is
begin
- if Bounded then
- if Capacity > Container.Capacity then
- raise Constraint_Error with "Capacity is out of range";
- end if;
-
- else
- if Capacity > Formal_Vectors.Current_Capacity (Container) then
- declare
- New_Elements : constant Elements_Array_Ptr :=
- new Elements_Array (1 .. Capacity);
- L : constant Capacity_Range := Length (Container);
-
- begin
- New_Elements (1 .. L) := Elemsc (Container) (1 .. L);
- Free (Container.Elements_Ptr);
- Container.Elements_Ptr := New_Elements;
- end;
- end if;
+ if Capacity > Container.Capacity then
+ raise Constraint_Error with "Capacity is out of range";
end if;
end Reserve_Capacity;
@@ -1241,7 +1117,7 @@ is
declare
I, J : Capacity_Range;
E : Elements_Array renames
- Elems (Container) (1 .. Length (Container));
+ Container.Elements (1 .. Length (Container));
begin
I := 1;
@@ -1282,7 +1158,7 @@ is
K := Capacity_Range (Int (Last) - Int (No_Index));
for Indx in reverse Index_Type'First .. Last loop
- if Get_Element (Container, K) = Item then
+ if Container.Elements (K) = Item then
return Indx;
end if;
@@ -1318,8 +1194,8 @@ is
II : constant Int'Base := Int (I) - Int (No_Index);
JJ : constant Int'Base := Int (J) - Int (No_Index);
- EI : Element_Type renames Elems (Container) (Capacity_Range (II));
- EJ : Element_Type renames Elems (Container) (Capacity_Range (JJ));
+ EI : Element_Type renames Container.Elements (Capacity_Range (II));
+ EJ : Element_Type renames Container.Elements (Capacity_Range (JJ));
EI_Copy : constant Element_Type := EI;
@@ -1388,10 +1264,9 @@ is
Last := Index_Type (Last_As_Int);
return
- (Capacity => Length,
- Last => Last,
- Elements_Ptr => <>,
- Elements => (others => New_Item));
+ (Capacity => Length,
+ Last => Last,
+ Elements => (others => New_Item));
end;
end To_Vector;
diff --git a/gcc/ada/libgnat/a-cofove.ads b/gcc/ada/libgnat/a-cofove.ads
index 635ef48..5b62664 100644
--- a/gcc/ada/libgnat/a-cofove.ads
+++ b/gcc/ada/libgnat/a-cofove.ads
@@ -40,12 +40,6 @@ with Ada.Containers.Functional_Vectors;
generic
type Index_Type is range <>;
type Element_Type is private;
-
- Bounded : Boolean := True;
- -- If True, the containers are bounded; the initial capacity is the maximum
- -- size, and heap allocation will be avoided. If False, the containers can
- -- grow via heap allocation.
-
package Ada.Containers.Formal_Vectors with
SPARK_Mode
is
@@ -73,17 +67,8 @@ is
subtype Capacity_Range is Count_Type range 0 .. Last_Count;
- type Vector (Capacity : Capacity_Range) is limited private with
+ type Vector (Capacity : Capacity_Range) is private with
Default_Initial_Condition => Is_Empty (Vector);
- -- In the bounded case, Capacity is the capacity of the container, which
- -- never changes. In the unbounded case, Capacity is the initial capacity
- -- of the container, and operations such as Reserve_Capacity and Append can
- -- increase the capacity. The capacity never shrinks, except in the case of
- -- Clear.
- --
- -- Note that all objects of type Vector are constrained, including in the
- -- unbounded case; you can't assign from one object to another if the
- -- Capacity is different.
function Length (Container : Vector) return Capacity_Range with
Global => null,
@@ -220,11 +205,7 @@ is
function Capacity (Container : Vector) return Capacity_Range with
Global => null,
Post =>
- Capacity'Result =
- (if Bounded then
- Container.Capacity
- else
- Capacity_Range'Last);
+ Capacity'Result = Container.Capacity;
pragma Annotate (GNATprove, Inline_For_Proof, Capacity);
procedure Reserve_Capacity
@@ -232,7 +213,7 @@ is
Capacity : Capacity_Range)
with
Global => null,
- Pre => (if Bounded then Capacity <= Container.Capacity),
+ Pre => Capacity <= Container.Capacity,
Post => Model (Container) = Model (Container)'Old;
function Is_Empty (Container : Vector) return Boolean with
@@ -242,13 +223,10 @@ is
procedure Clear (Container : in out Vector) with
Global => null,
Post => Length (Container) = 0;
- -- Note that this reclaims storage in the unbounded case. You need to call
- -- this before a container goes out of scope in order to avoid storage
- -- leaks. In addition, "X := ..." can leak unless you Clear(X) first.
procedure Assign (Target : in out Vector; Source : Vector) with
Global => null,
- Pre => (if Bounded then Length (Source) <= Target.Capacity),
+ Pre => Length (Source) <= Target.Capacity,
Post => Model (Target) = Model (Source);
function Copy
@@ -256,7 +234,7 @@ is
Capacity : Capacity_Range := 0) return Vector
with
Global => null,
- Pre => (if Bounded then (Capacity = 0 or Length (Source) <= Capacity)),
+ Pre => (Capacity = 0 or Length (Source) <= Capacity),
Post =>
Model (Copy'Result) = Model (Source)
and (if Capacity = 0 then
@@ -267,7 +245,7 @@ is
procedure Move (Target : in out Vector; Source : in out Vector)
with
Global => null,
- Pre => (if Bounded then Length (Source) <= Capacity (Target)),
+ Pre => Length (Source) <= Capacity (Target),
Post => Model (Target) = Model (Source)'Old and Length (Source) = 0;
function Element
@@ -894,30 +872,11 @@ private
type Elements_Array is array (Array_Index range <>) of Element_Type;
function "=" (L, R : Elements_Array) return Boolean is abstract;
- type Elements_Array_Ptr is access all Elements_Array;
-
- type Vector (Capacity : Capacity_Range) is limited record
-
- -- In the bounded case, the elements are stored in Elements. In the
- -- unbounded case, the elements are initially stored in Elements, until
- -- we run out of room, then we switch to Elements_Ptr.
-
- Last : Extended_Index := No_Index;
- Elements_Ptr : Elements_Array_Ptr := null;
- Elements : aliased Elements_Array (1 .. Capacity);
+ type Vector (Capacity : Capacity_Range) is record
+ Last : Extended_Index := No_Index;
+ Elements : Elements_Array (1 .. Capacity);
end record;
- -- The primary reason Vector is limited is that in the unbounded case, once
- -- Elements_Ptr is in use, assignment statements won't work. "X := Y;" will
- -- cause X and Y to share state; that is, X.Elements_Ptr = Y.Elements_Ptr,
- -- so for example "Append (X, ...);" will modify BOTH X and Y. That would
- -- allow SPARK to "prove" things that are false. We could fix that by
- -- making Vector a controlled type, and override Adjust to make a deep
- -- copy, but finalization is not allowed in SPARK.
- --
- -- Note that (unfortunately) this means that 'Old and 'Loop_Entry are not
- -- allowed on Vectors.
-
function Empty_Vector return Vector is
((Capacity => 0, others => <>));
diff --git a/gcc/ada/libgnat/a-strbou.ads b/gcc/ada/libgnat/a-strbou.ads
index f525ccf..ae61b86 100644
--- a/gcc/ada/libgnat/a-strbou.ads
+++ b/gcc/ada/libgnat/a-strbou.ads
@@ -33,6 +33,12 @@
-- --
------------------------------------------------------------------------------
+-- Preconditions in this unit are meant for analysis only, not for run-time
+-- checking, so that the expected exceptions are raised. This is enforced by
+-- setting the corresponding assertion policy to Ignore.
+
+pragma Assertion_Policy (Pre => Ignore);
+
with Ada.Strings.Maps;
with Ada.Strings.Superbounded;
@@ -43,7 +49,9 @@ package Ada.Strings.Bounded is
Max : Positive;
-- Maximum length of a Bounded_String
- package Generic_Bounded_Length is
+ package Generic_Bounded_Length with
+ Initial_Condition => Length (Null_Bounded_String) = 0
+ is
Max_Length : constant Positive := Max;
@@ -54,7 +62,8 @@ package Ada.Strings.Bounded is
subtype Length_Range is Natural range 0 .. Max_Length;
- function Length (Source : Bounded_String) return Length_Range;
+ function Length (Source : Bounded_String) return Length_Range with
+ Global => null;
--------------------------------------------------------
-- Conversion, Concatenation, and Selection Functions --
@@ -62,162 +71,302 @@ package Ada.Strings.Bounded is
function To_Bounded_String
(Source : String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre => (if Source'Length > Max_Length then Drop /= Error),
+ Post =>
+ Length (To_Bounded_String'Result)
+ = Natural'Min (Max_Length, Source'Length),
+ Global => null;
- function To_String (Source : Bounded_String) return String;
+ function To_String (Source : Bounded_String) return String with
+ Post => To_String'Result'Length = Length (Source),
+ Global => null;
procedure Set_Bounded_String
(Target : out Bounded_String;
Source : String;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre => (if Source'Length > Max_Length then Drop /= Error),
+ Post => Length (Target) = Natural'Min (Max_Length, Source'Length),
+ Global => null;
pragma Ada_05 (Set_Bounded_String);
function Append
(Left : Bounded_String;
Right : Bounded_String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ (if Length (Left) > Max_Length - Length (Right)
+ then Drop /= Error),
+ Post =>
+ Length (Append'Result)
+ = Natural'Min (Max_Length, Length (Left) + Length (Right)),
+ Global => null;
function Append
(Left : Bounded_String;
Right : String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ (if Right'Length > Max_Length - Length (Left)
+ then Drop /= Error),
+ Post =>
+ Length (Append'Result)
+ = Natural'Min (Max_Length, Length (Left) + Right'Length),
+ Global => null;
function Append
(Left : String;
Right : Bounded_String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ (if Left'Length > Max_Length - Length (Right)
+ then Drop /= Error),
+ Post =>
+ Length (Append'Result)
+ = Natural'Min (Max_Length, Left'Length + Length (Right)),
+ Global => null;
function Append
(Left : Bounded_String;
Right : Character;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre => (if Length (Left) = Max_Length then Drop /= Error),
+ Post =>
+ Length (Append'Result)
+ = Natural'Min (Max_Length, Length (Left) + 1),
+ Global => null;
function Append
(Left : Character;
Right : Bounded_String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre => (if Length (Right) = Max_Length then Drop /= Error),
+ Post =>
+ Length (Append'Result)
+ = Natural'Min (Max_Length, 1 + Length (Right)),
+ Global => null;
procedure Append
(Source : in out Bounded_String;
New_Item : Bounded_String;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre =>
+ (if Length (Source) > Max_Length - Length (New_Item)
+ then Drop /= Error),
+ Post =>
+ Length (Source)
+ = Natural'Min (Max_Length, Length (Source)'Old + Length (New_Item)),
+ Global => null;
procedure Append
(Source : in out Bounded_String;
New_Item : String;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre =>
+ (if New_Item'Length > Max_Length - Length (Source)
+ then Drop /= Error),
+ Post =>
+ Length (Source)
+ = Natural'Min (Max_Length, Length (Source)'Old + New_Item'Length),
+ Global => null;
procedure Append
(Source : in out Bounded_String;
New_Item : Character;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre => (if Length (Source) = Max_Length then Drop /= Error),
+ Post =>
+ Length (Source)
+ = Natural'Min (Max_Length, Length (Source)'Old + 1),
+ Global => null;
function "&"
(Left : Bounded_String;
- Right : Bounded_String) return Bounded_String;
+ Right : Bounded_String) return Bounded_String
+ with
+ Pre => Length (Left) <= Max_Length - Length (Right),
+ Post => Length ("&"'Result) = Length (Left) + Length (Right),
+ Global => null;
function "&"
(Left : Bounded_String;
- Right : String) return Bounded_String;
+ Right : String) return Bounded_String
+ with
+ Pre => Right'Length <= Max_Length - Length (Left),
+ Post => Length ("&"'Result) = Length (Left) + Right'Length,
+ Global => null;
function "&"
(Left : String;
- Right : Bounded_String) return Bounded_String;
+ Right : Bounded_String) return Bounded_String
+ with
+ Pre => Left'Length <= Max_Length - Length (Right),
+ Post => Length ("&"'Result) = Left'Length + Length (Right),
+ Global => null;
function "&"
(Left : Bounded_String;
- Right : Character) return Bounded_String;
+ Right : Character) return Bounded_String
+ with
+ Pre => Length (Left) < Max_Length,
+ Post => Length ("&"'Result) = Length (Left) + 1,
+ Global => null;
function "&"
(Left : Character;
- Right : Bounded_String) return Bounded_String;
+ Right : Bounded_String) return Bounded_String
+ with
+ Pre => Length (Right) < Max_Length,
+ Post => Length ("&"'Result) = 1 + Length (Right),
+ Global => null;
function Element
(Source : Bounded_String;
- Index : Positive) return Character;
+ Index : Positive) return Character
+ with
+ Pre => Index <= Length (Source),
+ Global => null;
procedure Replace_Element
(Source : in out Bounded_String;
Index : Positive;
- By : Character);
+ By : Character)
+ with
+ Pre => Index <= Length (Source),
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
function Slice
(Source : Bounded_String;
Low : Positive;
- High : Natural) return String;
+ High : Natural) return String
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post => Slice'Result'Length = Natural'Max (0, High - Low + 1),
+ Global => null;
function Bounded_Slice
(Source : Bounded_String;
Low : Positive;
- High : Natural) return Bounded_String;
+ High : Natural) return Bounded_String
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post =>
+ Length (Bounded_Slice'Result) = Natural'Max (0, High - Low + 1),
+ Global => null;
pragma Ada_05 (Bounded_Slice);
procedure Bounded_Slice
(Source : Bounded_String;
Target : out Bounded_String;
Low : Positive;
- High : Natural);
+ High : Natural)
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post => Length (Target) = Natural'Max (0, High - Low + 1),
+ Global => null;
pragma Ada_05 (Bounded_Slice);
function "="
(Left : Bounded_String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function "="
(Left : Bounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "="
(Left : String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function "<"
(Left : Bounded_String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function "<"
(Left : Bounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "<"
(Left : String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function "<="
(Left : Bounded_String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function "<="
(Left : Bounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "<="
(Left : String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function ">"
(Left : Bounded_String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function ">"
(Left : Bounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function ">"
(Left : String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function ">="
(Left : Bounded_String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
function ">="
(Left : Bounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function ">="
(Left : String;
- Right : Bounded_String) return Boolean;
+ Right : Bounded_String) return Boolean
+ with
+ Global => null;
----------------------
-- Search Functions --
@@ -227,26 +376,40 @@ package Ada.Strings.Bounded is
(Source : Bounded_String;
Pattern : String;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Index
(Source : Bounded_String;
Pattern : String;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Index
(Source : Bounded_String;
Set : Maps.Character_Set;
Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
function Index
(Source : Bounded_String;
Pattern : String;
From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre =>
+ (if Length (Source) /= 0
+ then From <= Length (Source))
+ and then Pattern'Length /= 0,
+ Global => null;
pragma Ada_05 (Index);
function Index
@@ -254,7 +417,13 @@ package Ada.Strings.Bounded is
Pattern : String;
From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre =>
+ (if Length (Source) /= 0
+ then From <= Length (Source))
+ and then Pattern'Length /= 0,
+ Global => null;
pragma Ada_05 (Index);
function Index
@@ -262,32 +431,48 @@ package Ada.Strings.Bounded is
Set : Maps.Character_Set;
From : Positive;
Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_05 (Index);
function Index_Non_Blank
(Source : Bounded_String;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
function Index_Non_Blank
(Source : Bounded_String;
From : Positive;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_05 (Index_Non_Blank);
function Count
(Source : Bounded_String;
Pattern : String;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Count
(Source : Bounded_String;
Pattern : String;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Count
(Source : Bounded_String;
- Set : Maps.Character_Set) return Natural;
+ Set : Maps.Character_Set) return Natural
+ with
+ Global => null;
procedure Find_Token
(Source : Bounded_String;
@@ -295,7 +480,10 @@ package Ada.Strings.Bounded is
From : Positive;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_2012 (Find_Token);
procedure Find_Token
@@ -303,7 +491,9 @@ package Ada.Strings.Bounded is
Set : Maps.Character_Set;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Global => null;
------------------------------------
-- String Translation Subprograms --
@@ -311,19 +501,31 @@ package Ada.Strings.Bounded is
function Translate
(Source : Bounded_String;
- Mapping : Maps.Character_Mapping) return Bounded_String;
+ Mapping : Maps.Character_Mapping) return Bounded_String
+ with
+ Post => Length (Translate'Result) = Length (Source),
+ Global => null;
procedure Translate
(Source : in out Bounded_String;
- Mapping : Maps.Character_Mapping);
+ Mapping : Maps.Character_Mapping)
+ with
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
function Translate
(Source : Bounded_String;
- Mapping : Maps.Character_Mapping_Function) return Bounded_String;
+ Mapping : Maps.Character_Mapping_Function) return Bounded_String
+ with
+ Post => Length (Translate'Result) = Length (Source),
+ Global => null;
procedure Translate
(Source : in out Bounded_String;
- Mapping : Maps.Character_Mapping_Function);
+ Mapping : Maps.Character_Mapping_Function)
+ with
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
---------------------------------------
-- String Transformation Subprograms --
@@ -334,48 +536,149 @@ package Ada.Strings.Bounded is
Low : Positive;
High : Natural;
By : String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ Low - 1 <= Length (Source)
+ and then
+ (if Drop = Error
+ then (if High >= Low
+ then Low - 1
+ <= Max_Length - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Max_Length - By'Length)),
+ Contract_Cases =>
+ (High >= Low =>
+ Length (Replace_Slice'Result)
+ = Natural'Min
+ (Max_Length,
+ Low - 1 + By'Length + Natural'Max (Length (Source) - High,
+ 0)),
+ others =>
+ Length (Replace_Slice'Result)
+ = Natural'Min (Max_Length, Length (Source) + By'Length)),
+ Global => null;
procedure Replace_Slice
(Source : in out Bounded_String;
Low : Positive;
High : Natural;
By : String;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre =>
+ Low - 1 <= Length (Source)
+ and then
+ (if Drop = Error
+ then (if High >= Low
+ then Low - 1
+ <= Max_Length - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Max_Length - By'Length)),
+ Contract_Cases =>
+ (High >= Low =>
+ Length (Source)
+ = Natural'Min
+ (Max_Length,
+ Low - 1 + By'Length + Natural'Max (Length (Source)'Old - High,
+ 0)),
+ others =>
+ Length (Source)
+ = Natural'Min (Max_Length, Length (Source)'Old + By'Length)),
+ Global => null;
function Insert
(Source : Bounded_String;
Before : Positive;
New_Item : String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ Before - 1 <= Length (Source)
+ and then (if New_Item'Length > Max_Length - Length (Source)
+ then Drop /= Error),
+ Post =>
+ Length (Insert'Result)
+ = Natural'Min (Max_Length, Length (Source) + New_Item'Length),
+ Global => null;
procedure Insert
(Source : in out Bounded_String;
Before : Positive;
New_Item : String;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre =>
+ Before - 1 <= Length (Source)
+ and then (if New_Item'Length > Max_Length - Length (Source)
+ then Drop /= Error),
+ Post =>
+ Length (Source)
+ = Natural'Min (Max_Length, Length (Source)'Old + New_Item'Length),
+ Global => null;
function Overwrite
(Source : Bounded_String;
Position : Positive;
New_Item : String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ Position - 1 <= Length (Source)
+ and then (if New_Item'Length > Max_Length - (Position - 1)
+ then Drop /= Error),
+ Post =>
+ Length (Overwrite'Result)
+ = Natural'Max
+ (Length (Source),
+ Natural'Min (Max_Length, Position - 1 + New_Item'Length)),
+ Global => null;
procedure Overwrite
(Source : in out Bounded_String;
Position : Positive;
New_Item : String;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre =>
+ Position - 1 <= Length (Source)
+ and then (if New_Item'Length > Max_Length - (Position - 1)
+ then Drop /= Error),
+ Post =>
+ Length (Source)
+ = Natural'Max
+ (Length (Source)'Old,
+ Natural'Min (Max_Length, Position - 1 + New_Item'Length)),
+ Global => null;
function Delete
(Source : Bounded_String;
From : Positive;
- Through : Natural) return Bounded_String;
+ Through : Natural) return Bounded_String
+ with
+ Pre =>
+ (if Through <= From then From - 1 <= Length (Source)),
+ Contract_Cases =>
+ (Through >= From =>
+ Length (Delete'Result) = Length (Source) - (Through - From + 1),
+ others =>
+ Length (Delete'Result) = Length (Source)),
+
+ Global => null;
procedure Delete
(Source : in out Bounded_String;
From : Positive;
- Through : Natural);
+ Through : Natural)
+ with
+ Pre =>
+ (if Through <= From then From - 1 <= Length (Source)),
+ Contract_Cases =>
+ (Through >= From =>
+ Length (Source) = Length (Source)'Old - (Through - From + 1),
+ others =>
+ Length (Source) = Length (Source)'Old),
+ Global => null;
---------------------------------
-- String Selector Subprograms --
@@ -383,45 +686,73 @@ package Ada.Strings.Bounded is
function Trim
(Source : Bounded_String;
- Side : Trim_End) return Bounded_String;
+ Side : Trim_End) return Bounded_String
+ with
+ Post => Length (Trim'Result) <= Length (Source),
+ Global => null;
procedure Trim
(Source : in out Bounded_String;
- Side : Trim_End);
+ Side : Trim_End)
+ with
+ Post => Length (Source) <= Length (Source)'Old,
+ Global => null;
function Trim
(Source : Bounded_String;
Left : Maps.Character_Set;
- Right : Maps.Character_Set) return Bounded_String;
+ Right : Maps.Character_Set) return Bounded_String
+ with
+ Post => Length (Trim'Result) <= Length (Source),
+ Global => null;
procedure Trim
(Source : in out Bounded_String;
Left : Maps.Character_Set;
- Right : Maps.Character_Set);
+ Right : Maps.Character_Set)
+ with
+ Post => Length (Source) <= Length (Source)'Old,
+ Global => null;
function Head
(Source : Bounded_String;
Count : Natural;
Pad : Character := Space;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre => (if Count > Max_Length then Drop /= Error),
+ Post => Length (Head'Result) = Natural'Min (Max_Length, Count),
+ Global => null;
procedure Head
(Source : in out Bounded_String;
Count : Natural;
Pad : Character := Space;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre => (if Count > Max_Length then Drop /= Error),
+ Post => Length (Source) = Natural'Min (Max_Length, Count),
+ Global => null;
function Tail
(Source : Bounded_String;
Count : Natural;
Pad : Character := Space;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre => (if Count > Max_Length then Drop /= Error),
+ Post => Length (Tail'Result) = Natural'Min (Max_Length, Count),
+ Global => null;
procedure Tail
(Source : in out Bounded_String;
Count : Natural;
Pad : Character := Space;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre => (if Count > Max_Length then Drop /= Error),
+ Post => Length (Source) = Natural'Min (Max_Length, Count),
+ Global => null;
------------------------------------
-- String Constructor Subprograms --
@@ -429,30 +760,66 @@ package Ada.Strings.Bounded is
function "*"
(Left : Natural;
- Right : Character) return Bounded_String;
+ Right : Character) return Bounded_String
+ with
+ Pre => Left <= Max_Length,
+ Post => Length ("*"'Result) = Left,
+ Global => null;
function "*"
(Left : Natural;
- Right : String) return Bounded_String;
+ Right : String) return Bounded_String
+ with
+ Pre => (if Left /= 0 then Right'Length <= Max_Length / Left),
+ Post => Length ("*"'Result) = Left * Right'Length,
+ Global => null;
function "*"
(Left : Natural;
- Right : Bounded_String) return Bounded_String;
+ Right : Bounded_String) return Bounded_String
+ with
+ Pre => (if Left /= 0 then Length (Right) <= Max_Length / Left),
+ Post => Length ("*"'Result) = Left * Length (Right),
+ Global => null;
function Replicate
(Count : Natural;
Item : Character;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre => (if Count > Max_Length then Drop /= Error),
+ Post =>
+ Length (Replicate'Result)
+ = Natural'Min (Max_Length, Count),
+ Global => null;
function Replicate
(Count : Natural;
Item : String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ (if Item'Length /= 0
+ and then Count > Max_Length / Item'Length
+ then Drop /= Error),
+ Post =>
+ Length (Replicate'Result)
+ = Natural'Min (Max_Length, Count * Item'Length),
+ Global => null;
function Replicate
(Count : Natural;
Item : Bounded_String;
- Drop : Truncation := Error) return Bounded_String;
+ Drop : Truncation := Error) return Bounded_String
+ with
+ Pre =>
+ (if Length (Item) /= 0
+ and then Count > Max_Length / Length (Item)
+ then Drop /= Error),
+ Post =>
+ Length (Replicate'Result)
+ = Natural'Min (Max_Length, Count * Length (Item)),
+ Global => null;
private
-- Most of the implementation is in the separate non generic package
diff --git a/gcc/ada/libgnat/a-strfix.adb b/gcc/ada/libgnat/a-strfix.adb
index 6bf825b..b8b5f42 100644
--- a/gcc/ada/libgnat/a-strfix.adb
+++ b/gcc/ada/libgnat/a-strfix.adb
@@ -192,7 +192,15 @@ package body Ada.Strings.Fixed is
elsif From not in Source'Range
or else Through > Source'Last
then
- raise Index_Error;
+ -- In most cases this raises an exception, but the case of deleting
+ -- a null string at the end of the current one is a special-case, and
+ -- reflects the equivalence with Replace_String (RM A.4.3 (86/3)).
+
+ if From = Source'Last + 1 and then From = Through then
+ return Source;
+ else
+ raise Index_Error;
+ end if;
else
declare
diff --git a/gcc/ada/libgnat/a-strfix.ads b/gcc/ada/libgnat/a-strfix.ads
index 56db8bc..7d6e121 100644
--- a/gcc/ada/libgnat/a-strfix.ads
+++ b/gcc/ada/libgnat/a-strfix.ads
@@ -13,9 +13,34 @@
-- --
------------------------------------------------------------------------------
+-- Preconditions in this unit are meant for analysis only, not for run-time
+-- checking, so that the expected exceptions are raised. This is enforced by
+-- setting the corresponding assertion policy to Ignore.
+
+pragma Assertion_Policy (Pre => Ignore);
+
with Ada.Strings.Maps;
-package Ada.Strings.Fixed is
+-- The language-defined package Strings.Fixed provides string-handling
+-- subprograms for fixed-length strings; that is, for values of type
+-- Standard.String. Several of these subprograms are procedures that modify
+-- the contents of a String that is passed as an out or an in out parameter;
+-- each has additional parameters to control the effect when the logical
+-- length of the result differs from the parameter's length.
+--
+-- For each function that returns a String, the lower bound of the returned
+-- value is 1.
+--
+-- The basic model embodied in the package is that a fixed-length string
+-- comprises significant characters and possibly padding (with space
+-- characters) on either or both ends. When a shorter string is copied to a
+-- longer string, padding is inserted, and when a longer string is copied to a
+-- shorter one, padding is stripped. The Move procedure in Strings.Fixed,
+-- which takes a String as an out parameter, allows the programmer to control
+-- these effects. Similar control is provided by the string transformation
+-- procedures.
+
+package Ada.Strings.Fixed with SPARK_Mode is
pragma Preelaborate;
--------------------------------------------------------------
@@ -27,7 +52,50 @@ package Ada.Strings.Fixed is
Target : out String;
Drop : Truncation := Error;
Justify : Alignment := Left;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+
+ -- Incomplete contract
+
+ Global => null;
+ -- The Move procedure copies characters from Source to Target. If Source
+ -- has the same length as Target, then the effect is to assign Source to
+ -- Target. If Source is shorter than Target then:
+ --
+ -- * If Justify=Left, then Source is copied into the first Source'Length
+ -- characters of Target.
+ --
+ -- * If Justify=Right, then Source is copied into the last Source'Length
+ -- characters of Target.
+ --
+ -- * If Justify=Center, then Source is copied into the middle Source'Length
+ -- characters of Target. In this case, if the difference in length
+ -- between Target and Source is odd, then the extra Pad character is on
+ -- the right.
+ --
+ -- * Pad is copied to each Target character not otherwise assigned.
+ --
+ -- If Source is longer than Target, then the effect is based on Drop.
+ --
+ -- * If Drop=Left, then the rightmost Target'Length characters of Source
+ -- are copied into Target.
+ --
+ -- * If Drop=Right, then the leftmost Target'Length characters of Source
+ -- are copied into Target.
+ --
+ -- * If Drop=Error, then the effect depends on the value of the Justify
+ -- parameter and also on whether any characters in Source other than Pad
+ -- would fail to be copied:
+ --
+ -- * If Justify=Left, and if each of the rightmost
+ -- Source'Length-Target'Length characters in Source is Pad, then the
+ -- leftmost Target'Length characters of Source are copied to Target.
+ --
+ -- * If Justify=Right, and if each of the leftmost
+ -- Source'Length-Target'Length characters in Source is Pad, then the
+ -- rightmost Target'Length characters of Source are copied to Target.
+ --
+ -- * Otherwise, Length_Error is propagated.
------------------------
-- Search Subprograms --
@@ -36,68 +104,139 @@ package Ada.Strings.Fixed is
function Index
(Source : String;
Pattern : String;
+ From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre =>
+ Pattern'Length /= 0
+ and then (if Source'Length /= 0 then From in Source'Range),
+ Global => null;
+ pragma Ada_05 (Index);
function Index
(Source : String;
Pattern : String;
+ From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre =>
+ Pattern'Length /= 0
+ and then (if Source'Length /= 0 then From in Source'Range),
+ Global => null;
+ pragma Ada_05 (Index);
- function Index
- (Source : String;
- Set : Maps.Character_Set;
- Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ -- Each Index function searches, starting from From, for a slice of
+ -- Source, with length Pattern'Length, that matches Pattern with respect to
+ -- Mapping; the parameter Going indicates the direction of the lookup. If
+ -- Source is the null string, Index returns 0; otherwise, if From is not in
+ -- Source'Range, then Index_Error is propagated. If Going = Forward, then
+ -- Index returns the smallest index I which is greater than or equal to
+ -- From such that the slice of Source starting at I matches Pattern. If
+ -- Going = Backward, then Index returns the largest index I such that the
+ -- slice of Source starting at I matches Pattern and has an upper bound
+ -- less than or equal to From. If there is no such slice, then 0 is
+ -- returned. If Pattern is the null string, then Pattern_Error is
+ -- propagated.
function Index
(Source : String;
Pattern : String;
- From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
- pragma Ada_05 (Index);
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length > 0,
+ Global => null;
function Index
(Source : String;
Pattern : String;
- From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
- pragma Ada_05 (Index);
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
+
+ -- If Going = Forward, returns:
+ --
+ -- Index (Source, Pattern, Source'First, Forward, Mapping)
+ --
+ -- otherwise, returns:
+ --
+ -- Index (Source, Pattern, Source'Last, Backward, Mapping).
+
+ function Index
+ (Source : String;
+ Set : Maps.Character_Set;
+ Test : Membership := Inside;
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
function Index
(Source : String;
Set : Maps.Character_Set;
From : Positive;
Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Source'Length /= 0 then From in Source'Range),
+ Global => null;
pragma Ada_05 (Index);
+ -- Index searches for the first or last occurrence of any of a set of
+ -- characters (when Test=Inside), or any of the complement of a set of
+ -- characters (when Test=Outside). If Source is the null string, Index
+ -- returns 0; otherwise, if From is not in Source'Range, then Index_Error
+ -- is propagated. Otherwise, it returns the smallest index I >= From (if
+ -- Going=Forward) or the largest index I <= From (if Going=Backward) such
+ -- that Source(I) satisfies the Test condition with respect to Set; it
+ -- returns 0 if there is no such Character in Source.
function Index_Non_Blank
(Source : String;
- Going : Direction := Forward) return Natural;
+ From : Positive;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Source'Length /= 0 then From in Source'Range),
+ Global => null;
+ pragma Ada_05 (Index_Non_Blank);
+ -- Returns Index (Source, Maps.To_Set(Space), From, Outside, Going)
function Index_Non_Blank
(Source : String;
- From : Positive;
- Going : Direction := Forward) return Natural;
- pragma Ada_05 (Index_Non_Blank);
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
+ -- Returns Index (Source, Maps.To_Set(Space), Outside, Going)
function Count
(Source : String;
Pattern : String;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Count
(Source : String;
Pattern : String;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
+
+ -- Returns the maximum number of nonoverlapping slices of Source that match
+ -- Pattern with respect to Mapping. If Pattern is the null string then
+ -- Pattern_Error is propagated.
function Count
(Source : String;
- Set : Maps.Character_Set) return Natural;
+ Set : Maps.Character_Set) return Natural
+ with
+ Global => null;
+ -- Returns the number of occurrences in Source of characters that are in
+ -- Set.
procedure Find_Token
(Source : String;
@@ -105,15 +244,28 @@ package Ada.Strings.Fixed is
From : Positive;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Pre => (if Source'Length /= 0 then From in Source'Range),
+ Global => null;
pragma Ada_2012 (Find_Token);
+ -- If Source is not the null string and From is not in Source'Range, then
+ -- Index_Error is raised. Otherwise, First is set to the index of the first
+ -- character in Source(From .. Source'Last) that satisfies the Test
+ -- condition. Last is set to the largest index such that all characters in
+ -- Source(First .. Last) satisfy the Test condition. If no characters in
+ -- Source(From .. Source'Last) satisfy the Test condition, First is set to
+ -- From, and Last is set to 0.
procedure Find_Token
(Source : String;
Set : Maps.Character_Set;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Global => null;
+ -- Equivalent to Find_Token (Source, Set, Source'First, Test, First, Last)
------------------------------------
-- String Translation Subprograms --
@@ -121,30 +273,40 @@ package Ada.Strings.Fixed is
function Translate
(Source : String;
- Mapping : Maps.Character_Mapping) return String;
-
- procedure Translate
- (Source : in out String;
- Mapping : Maps.Character_Mapping);
+ Mapping : Maps.Character_Mapping_Function) return String
+ with
+ Post => Translate'Result'Length = Source'Length,
+ Global => null;
function Translate
(Source : String;
- Mapping : Maps.Character_Mapping_Function) return String;
+ Mapping : Maps.Character_Mapping) return String
+ with
+ Post => Translate'Result'Length = Source'Length,
+ Global => null;
+
+ -- Returns the string S whose length is Source'Length and such that S (I)
+ -- is the character to which Mapping maps the corresponding element of
+ -- Source, for I in 1 .. Source'Length.
procedure Translate
(Source : in out String;
- Mapping : Maps.Character_Mapping_Function);
+ Mapping : Maps.Character_Mapping_Function)
+ with
+ Global => null;
+
+ procedure Translate
+ (Source : in out String;
+ Mapping : Maps.Character_Mapping)
+ with
+ Global => null;
+
+ -- Equivalent to Source := Translate(Source, Mapping)
---------------------------------------
-- String Transformation Subprograms --
---------------------------------------
- function Replace_Slice
- (Source : String;
- Low : Positive;
- High : Natural;
- By : String) return String;
-
procedure Replace_Slice
(Source : in out String;
Low : Positive;
@@ -152,41 +314,152 @@ package Ada.Strings.Fixed is
By : String;
Drop : Truncation := Error;
Justify : Alignment := Left;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+ Pre =>
+
+ -- Incomplete contract
+
+ Low - 1 <= Source'Last
+ and then High >= Source'First - 1,
+ Global => null;
+ -- If Low > Source'Last+1, or High < Source'First - 1, then Index_Error is
+ -- propagated. Otherwise:
+ --
+ -- * If High >= Low, then the returned string comprises
+ -- Source (Source'First .. Low - 1)
+ -- & By & Source(High + 1 .. Source'Last), but with lower bound 1.
+ --
+ -- * If High < Low, then the returned string is
+ -- Insert (Source, Before => Low, New_Item => By).
+
+ function Replace_Slice
+ (Source : String;
+ Low : Positive;
+ High : Natural;
+ By : String) return String
+ with
+ Pre =>
+ Low - 1 <= Source'Last
+ and then High >= Source'First - 1
+ and then (if High >= Low
+ then Natural'Max (0, Low - Source'First)
+ <= Natural'Last - By'Length
+ - Natural'Max (Source'Last - High, 0)
+ else Source'Length <= Natural'Last - By'Length),
+ Contract_Cases =>
+ (High >= Low =>
+ Replace_Slice'Result'Length
+ = Natural'Max (0, Low - Source'First)
+ + By'Length
+ + Natural'Max (Source'Last - High, 0),
+ others =>
+ Replace_Slice'Result'Length = Source'Length + By'Length),
+ Global => null;
+ -- Equivalent to:
+ --
+ -- Move (Replace_Slice (Source, Low, High, By),
+ -- Source, Drop, Justify, Pad).
function Insert
(Source : String;
Before : Positive;
- New_Item : String) return String;
+ New_Item : String) return String
+ with
+ Pre =>
+ Before - 1 in Source'First - 1 .. Source'Last
+ and then Source'Length <= Natural'Last - New_Item'Length,
+ Post => Insert'Result'Length = Source'Length + New_Item'Length,
+ Global => null;
+ -- Propagates Index_Error if Before is not in
+ -- Source'First .. Source'Last+1; otherwise, returns
+ -- Source (Source'First .. Before - 1)
+ -- & New_Item & Source(Before..Source'Last), but with lower bound 1.
procedure Insert
(Source : in out String;
Before : Positive;
New_Item : String;
- Drop : Truncation := Error);
+ Drop : Truncation := Error)
+ with
+ Pre => Before - 1 in Source'First - 1 .. Source'Last,
+
+ -- Incomplete contract
+
+ Global => null;
+ -- Equivalent to Move (Insert (Source, Before, New_Item), Source, Drop)
function Overwrite
(Source : String;
Position : Positive;
- New_Item : String) return String;
+ New_Item : String) return String
+ with
+ Pre =>
+ Position - 1 in Source'First - 1 .. Source'Last
+ and then
+ (if Position - Source'First >= Source'Length - New_Item'Length
+ then Position - Source'First <= Natural'Last - New_Item'Length),
+ Post =>
+ Overwrite'Result'Length
+ = Integer'Max (Source'Length,
+ Position - Source'First + New_Item'Length),
+ Global => null;
+ -- Propagates Index_Error if Position is not in
+ -- Source'First .. Source'Last + 1; otherwise, returns the string obtained
+ -- from Source by consecutively replacing characters starting at Position
+ -- with corresponding characters from New_Item. If the end of Source is
+ -- reached before the characters in New_Item are exhausted, the remaining
+ -- characters from New_Item are appended to the string.
procedure Overwrite
(Source : in out String;
Position : Positive;
New_Item : String;
- Drop : Truncation := Right);
+ Drop : Truncation := Right)
+ with
+ Pre => Position - 1 in Source'First - 1 .. Source'Last,
+
+ -- Incomplete contract
+
+ Global => null;
+ -- Equivalent to Move(Overwrite(Source, Position, New_Item), Source, Drop)
function Delete
(Source : String;
From : Positive;
- Through : Natural) return String;
+ Through : Natural) return String
+ with
+ Pre => (if From <= Through
+ then (From in Source'Range
+ and then Through <= Source'Last)),
+ Post =>
+ Delete'Result'Length
+ = Source'Length - (if From <= Through
+ then Through - From + 1
+ else 0),
+ Global => null;
+ -- If From <= Through, the returned string is
+ -- Replace_Slice(Source, From, Through, ""); otherwise, it is Source with
+ -- lower bound 1.
procedure Delete
(Source : in out String;
From : Positive;
Through : Natural;
Justify : Alignment := Left;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+ Pre => (if From <= Through
+ then (From in Source'Range
+ and then Through <= Source'Last)),
+
+ -- Incomplete contract
+
+ Global => null;
+ -- Equivalent to:
+ --
+ -- Move (Delete (Source, From, Through),
+ -- Source, Justify => Justify, Pad => Pad).
---------------------------------
-- String Selector Subprograms --
@@ -194,47 +467,106 @@ package Ada.Strings.Fixed is
function Trim
(Source : String;
- Side : Trim_End) return String;
+ Side : Trim_End) return String
+ with
+ Post => Trim'Result'Length <= Source'Length,
+ Global => null;
+ -- Returns the string obtained by removing from Source all leading Space
+ -- characters (if Side = Left), all trailing Space characters (if
+ -- Side = Right), or all leading and trailing Space characters (if
+ -- Side = Both).
procedure Trim
(Source : in out String;
Side : Trim_End;
Justify : Alignment := Left;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+
+ -- Incomplete contract
+
+ Global => null;
+ -- Equivalent to:
+ --
+ -- Move (Trim (Source, Side), Source, Justify=>Justify, Pad=>Pad).
function Trim
(Source : String;
Left : Maps.Character_Set;
- Right : Maps.Character_Set) return String;
+ Right : Maps.Character_Set) return String
+ with
+ Post => Trim'Result'Length <= Source'Length,
+ Global => null;
+ -- Returns the string obtained by removing from Source all leading
+ -- characters in Left and all trailing characters in Right.
procedure Trim
(Source : in out String;
Left : Maps.Character_Set;
Right : Maps.Character_Set;
Justify : Alignment := Strings.Left;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+
+ -- Incomplete contract
+
+ Global => null;
+ -- Equivalent to:
+ --
+ -- Move (Trim (Source, Left, Right),
+ -- Source, Justify => Justify, Pad=>Pad).
function Head
(Source : String;
Count : Natural;
- Pad : Character := Space) return String;
+ Pad : Character := Space) return String
+ with
+ Post => Head'Result'Length = Count,
+ Global => null;
+ -- Returns a string of length Count. If Count <= Source'Length, the string
+ -- comprises the first Count characters of Source. Otherwise, its contents
+ -- are Source concatenated with Count - Source'Length Pad characters.
procedure Head
(Source : in out String;
Count : Natural;
Justify : Alignment := Left;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+
+ -- Incomplete contract
+
+ Global => null;
+ -- Equivalent to:
+ --
+ -- Move (Head (Source, Count, Pad),
+ -- Source, Drop => Error, Justify => Justify, Pad => Pad).
function Tail
(Source : String;
Count : Natural;
- Pad : Character := Space) return String;
+ Pad : Character := Space) return String
+ with
+ Post => Tail'Result'Length = Count,
+ Global => null;
+ -- Returns a string of length Count. If Count <= Source'Length, the string
+ -- comprises the last Count characters of Source. Otherwise, its contents
+ -- are Count-Source'Length Pad characters concatenated with Source.
procedure Tail
(Source : in out String;
Count : Natural;
Justify : Alignment := Left;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+
+ -- Incomplete contract
+
+ Global => null;
+ -- Equivalent to:
+ --
+ -- Move (Tail (Source, Count, Pad),
+ -- Source, Drop => Error, Justify => Justify, Pad => Pad).
----------------------------------
-- String Constructor Functions --
@@ -242,10 +574,23 @@ package Ada.Strings.Fixed is
function "*"
(Left : Natural;
- Right : Character) return String;
+ Right : Character) return String
+ with
+ Post => "*"'Result'Length = Left,
+ Global => null;
function "*"
(Left : Natural;
- Right : String) return String;
+ Right : String) return String
+ with
+ Pre => (if Right'Length /= 0 then Left <= Natural'Last / Right'Length),
+ Post => "*"'Result'Length = Left * Right'Length,
+ Global => null;
+
+ -- These functions replicate a character or string a specified number of
+ -- times. The first function returns a string whose length is Left and each
+ -- of whose elements is Right. The second function returns a string whose
+ -- length is Left * Right'Length and whose value is the null string if
+ -- Left = 0 and otherwise is (Left - 1)*Right & Right with lower bound 1.
end Ada.Strings.Fixed;
diff --git a/gcc/ada/libgnat/a-strunb.ads b/gcc/ada/libgnat/a-strunb.ads
index 601e69e..e875b5b 100644
--- a/gcc/ada/libgnat/a-strunb.ads
+++ b/gcc/ada/libgnat/a-strunb.ads
@@ -33,158 +33,318 @@
-- --
------------------------------------------------------------------------------
+-- Preconditions in this unit are meant for analysis only, not for run-time
+-- checking, so that the expected exceptions are raised. This is enforced by
+-- setting the corresponding assertion policy to Ignore.
+
+pragma Assertion_Policy (Pre => Ignore);
+
with Ada.Strings.Maps;
with Ada.Finalization;
-package Ada.Strings.Unbounded is
+-- The language-defined package Strings.Unbounded provides a private type
+-- Unbounded_String and a set of operations. An object of type
+-- Unbounded_String represents a String whose low bound is 1 and whose length
+-- can vary conceptually between 0 and Natural'Last. The subprograms for
+-- fixed-length string handling are either overloaded directly for
+-- Unbounded_String, or are modified as needed to reflect the flexibility in
+-- length. Since the Unbounded_String type is private, relevant constructor
+-- and selector operations are provided.
+
+package Ada.Strings.Unbounded with
+ Initial_Condition => Length (Null_Unbounded_String) = 0
+is
pragma Preelaborate;
type Unbounded_String is private;
pragma Preelaborable_Initialization (Unbounded_String);
Null_Unbounded_String : constant Unbounded_String;
+ -- Represents the null String. If an object of type Unbounded_String is not
+ -- otherwise initialized, it will be initialized to the same value as
+ -- Null_Unbounded_String.
- function Length (Source : Unbounded_String) return Natural;
+ function Length (Source : Unbounded_String) return Natural with
+ Global => null;
+ -- Returns the length of the String represented by Source
type String_Access is access all String;
+ -- Provides a (nonprivate) access type for explicit processing of
+ -- unbounded-length strings.
procedure Free (X : in out String_Access);
+ -- Performs an unchecked deallocation of an object of type String_Access
--------------------------------------------------------
-- Conversion, Concatenation, and Selection Functions --
--------------------------------------------------------
function To_Unbounded_String
- (Source : String) return Unbounded_String;
+ (Source : String) return Unbounded_String
+ with
+ Post => Length (To_Unbounded_String'Result) = Source'Length,
+ Global => null;
+ -- Returns an Unbounded_String that represents Source
function To_Unbounded_String
- (Length : Natural) return Unbounded_String;
-
- function To_String (Source : Unbounded_String) return String;
+ (Length : Natural) return Unbounded_String
+ with
+ Post =>
+ Ada.Strings.Unbounded.Length (To_Unbounded_String'Result)
+ = Length,
+ Global => null;
+ -- Returns an Unbounded_String that represents an uninitialized String
+ -- whose length is Length.
+
+ function To_String (Source : Unbounded_String) return String with
+ Post => To_String'Result'Length = Length (Source),
+ Global => null;
+ -- Returns the String with lower bound 1 represented by Source
+
+ -- To_String and To_Unbounded_String are related as follows:
+ --
+ -- * If S is a String, then To_String (To_Unbounded_String (S)) = S.
+ --
+ -- * If U is an Unbounded_String, then
+ -- To_Unbounded_String (To_String (U)) = U.
procedure Set_Unbounded_String
(Target : out Unbounded_String;
- Source : String);
+ Source : String)
+ with
+ Global => null;
pragma Ada_05 (Set_Unbounded_String);
+ -- Sets Target to an Unbounded_String that represents Source
procedure Append
(Source : in out Unbounded_String;
- New_Item : Unbounded_String);
+ New_Item : Unbounded_String)
+ with
+ Pre => Length (New_Item) <= Natural'Last - Length (Source),
+ Post => Length (Source) = Length (Source)'Old + Length (New_Item),
+ Global => null;
procedure Append
(Source : in out Unbounded_String;
- New_Item : String);
+ New_Item : String)
+ with
+ Pre => New_Item'Length <= Natural'Last - Length (Source),
+ Post => Length (Source) = Length (Source)'Old + New_Item'Length,
+ Global => null;
procedure Append
(Source : in out Unbounded_String;
- New_Item : Character);
+ New_Item : Character)
+ with
+ Pre => Length (Source) < Natural'Last,
+ Post => Length (Source) = Length (Source)'Old + 1,
+ Global => null;
+
+ -- For each of the Append procedures, the resulting string represented by
+ -- the Source parameter is given by the concatenation of the original value
+ -- of Source and the value of New_Item.
function "&"
(Left : Unbounded_String;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => Length (Right) <= Natural'Last - Length (Left),
+ Post => Length ("&"'Result) = Length (Left) + Length (Right),
+ Global => null;
function "&"
(Left : Unbounded_String;
- Right : String) return Unbounded_String;
+ Right : String) return Unbounded_String
+ with
+ Pre => Right'Length <= Natural'Last - Length (Left),
+ Post => Length ("&"'Result) = Length (Left) + Right'Length,
+ Global => null;
function "&"
(Left : String;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => Left'Length <= Natural'Last - Length (Right),
+ Post => Length ("&"'Result) = Left'Length + Length (Right),
+ Global => null;
function "&"
(Left : Unbounded_String;
- Right : Character) return Unbounded_String;
+ Right : Character) return Unbounded_String
+ with
+ Pre => Length (Left) < Natural'Last,
+ Post => Length ("&"'Result) = Length (Left) + 1,
+ Global => null;
function "&"
(Left : Character;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => Length (Right) < Natural'Last,
+ Post => Length ("&"'Result) = Length (Right) + 1,
+ Global => null;
+
+ -- Each of the "&" functions returns an Unbounded_String obtained by
+ -- concatenating the string or character given or represented by one of the
+ -- parameters, with the string or character given or represented by the
+ -- other parameter, and applying To_Unbounded_String to the concatenation
+ -- result string.
function Element
(Source : Unbounded_String;
- Index : Positive) return Character;
+ Index : Positive) return Character
+ with
+ Pre => Index <= Length (Source),
+ Global => null;
+ -- Returns the character at position Index in the string represented by
+ -- Source; propagates Index_Error if Index > Length (Source).
procedure Replace_Element
(Source : in out Unbounded_String;
Index : Positive;
- By : Character);
+ By : Character)
+ with
+ Pre => Index <= Length (Source),
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
+ -- Updates Source such that the character at position Index in the string
+ -- represented by Source is By; propagates Index_Error if
+ -- Index > Length (Source).
function Slice
(Source : Unbounded_String;
Low : Positive;
- High : Natural) return String;
+ High : Natural) return String
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post => Slice'Result'Length = Natural'Max (0, High - Low + 1),
+ Global => null;
+ -- Returns the slice at positions Low through High in the string
+ -- represented by Source; propagates Index_Error if
+ -- Low > Length (Source) + 1 or High > Length (Source). The bounds of the
+ -- returned string are Low and High.
function Unbounded_Slice
(Source : Unbounded_String;
Low : Positive;
- High : Natural) return Unbounded_String;
+ High : Natural) return Unbounded_String
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post =>
+ Length (Unbounded_Slice'Result) = Natural'Max (0, High - Low + 1),
+ Global => null;
pragma Ada_05 (Unbounded_Slice);
+ -- Returns the slice at positions Low through High in the string
+ -- represented by Source as an Unbounded_String. This propagates
+ -- Index_Error if Low > Length(Source) + 1 or High > Length (Source).
procedure Unbounded_Slice
(Source : Unbounded_String;
Target : out Unbounded_String;
Low : Positive;
- High : Natural);
+ High : Natural)
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post => Length (Target) = Natural'Max (0, High - Low + 1),
+ Global => null;
pragma Ada_05 (Unbounded_Slice);
+ -- Sets Target to the Unbounded_String representing the slice at positions
+ -- Low through High in the string represented by Source. This propagates
+ -- Index_Error if Low > Length(Source) + 1 or High > Length (Source).
function "="
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "="
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "="
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<"
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<"
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "<"
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<="
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<="
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "<="
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">"
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">"
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function ">"
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">="
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">="
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function ">="
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
+
+ -- Each of the functions "=", "<", ">", "<=", and ">=" returns the same
+ -- result as the corresponding String operation applied to the String
+ -- values given or represented by Left and Right.
------------------------
-- Search Subprograms --
@@ -194,26 +354,38 @@ package Ada.Strings.Unbounded is
(Source : Unbounded_String;
Pattern : String;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Index
(Source : Unbounded_String;
Pattern : String;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Index
(Source : Unbounded_String;
Set : Maps.Character_Set;
Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
function Index
(Source : Unbounded_String;
Pattern : String;
From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source))
+ and then Pattern'Length /= 0,
+ Global => null;
pragma Ada_05 (Index);
function Index
@@ -221,7 +393,11 @@ package Ada.Strings.Unbounded is
Pattern : String;
From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source))
+ and then Pattern'Length /= 0,
+ Global => null;
pragma Ada_05 (Index);
function Index
@@ -229,32 +405,48 @@ package Ada.Strings.Unbounded is
Set : Maps.Character_Set;
From : Positive;
Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_05 (Index);
function Index_Non_Blank
(Source : Unbounded_String;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
function Index_Non_Blank
(Source : Unbounded_String;
From : Positive;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_05 (Index_Non_Blank);
function Count
(Source : Unbounded_String;
Pattern : String;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Count
(Source : Unbounded_String;
Pattern : String;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Count
(Source : Unbounded_String;
- Set : Maps.Character_Set) return Natural;
+ Set : Maps.Character_Set) return Natural
+ with
+ Global => null;
procedure Find_Token
(Source : Unbounded_String;
@@ -262,7 +454,10 @@ package Ada.Strings.Unbounded is
From : Positive;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_2012 (Find_Token);
procedure Find_Token
@@ -270,7 +465,14 @@ package Ada.Strings.Unbounded is
Set : Maps.Character_Set;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Global => null;
+
+ -- Each of the search subprograms (Index, Index_Non_Blank, Count,
+ -- Find_Token) has the same effect as the corresponding subprogram in
+ -- Strings.Fixed applied to the string represented by the Unbounded_String
+ -- parameter.
------------------------------------
-- String Translation Subprograms --
@@ -278,19 +480,36 @@ package Ada.Strings.Unbounded is
function Translate
(Source : Unbounded_String;
- Mapping : Maps.Character_Mapping) return Unbounded_String;
+ Mapping : Maps.Character_Mapping) return Unbounded_String
+ with
+ Post => Length (Translate'Result) = Length (Source),
+ Global => null;
procedure Translate
(Source : in out Unbounded_String;
- Mapping : Maps.Character_Mapping);
+ Mapping : Maps.Character_Mapping)
+ with
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
function Translate
(Source : Unbounded_String;
- Mapping : Maps.Character_Mapping_Function) return Unbounded_String;
+ Mapping : Maps.Character_Mapping_Function) return Unbounded_String
+ with
+ Post => Length (Translate'Result) = Length (Source),
+ Global => null;
procedure Translate
(Source : in out Unbounded_String;
- Mapping : Maps.Character_Mapping_Function);
+ Mapping : Maps.Character_Mapping_Function)
+ with
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
+
+ -- The Translate function has an analogous effect to the corresponding
+ -- subprogram in Strings.Fixed. The translation is applied to the string
+ -- represented by the Unbounded_String parameter, and the result is
+ -- converted (via To_Unbounded_String) to an Unbounded_String.
---------------------------------------
-- String Transformation Subprograms --
@@ -300,93 +519,217 @@ package Ada.Strings.Unbounded is
(Source : Unbounded_String;
Low : Positive;
High : Natural;
- By : String) return Unbounded_String;
+ By : String) return Unbounded_String
+ with
+ Pre =>
+ Low - 1 <= Length (Source)
+ and then (if High >= Low
+ then Low - 1
+ <= Natural'Last - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Natural'Last - By'Length),
+ Contract_Cases =>
+ (High >= Low =>
+ Length (Replace_Slice'Result)
+ = Low - 1 + By'Length + Natural'Max (Length (Source)'Old - High, 0),
+ others =>
+ Length (Replace_Slice'Result) = Length (Source)'Old + By'Length),
+ Global => null;
procedure Replace_Slice
(Source : in out Unbounded_String;
Low : Positive;
High : Natural;
- By : String);
+ By : String)
+ with
+ Pre =>
+ Low - 1 <= Length (Source)
+ and then (if High >= Low
+ then Low - 1
+ <= Natural'Last - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Natural'Last - By'Length),
+ Contract_Cases =>
+ (High >= Low =>
+ Length (Source)
+ = Low - 1 + By'Length + Natural'Max (Length (Source)'Old - High, 0),
+ others =>
+ Length (Source) = Length (Source)'Old + By'Length),
+ Global => null;
function Insert
(Source : Unbounded_String;
Before : Positive;
- New_Item : String) return Unbounded_String;
+ New_Item : String) return Unbounded_String
+ with
+ Pre => Before - 1 <= Length (Source)
+ and then New_Item'Length <= Natural'Last - Length (Source),
+ Post => Length (Insert'Result) = Length (Source) + New_Item'Length,
+ Global => null;
procedure Insert
(Source : in out Unbounded_String;
Before : Positive;
- New_Item : String);
+ New_Item : String)
+ with
+ Pre => Before - 1 <= Length (Source)
+ and then New_Item'Length <= Natural'Last - Length (Source),
+ Post => Length (Source) = Length (Source)'Old + New_Item'Length,
+ Global => null;
function Overwrite
(Source : Unbounded_String;
Position : Positive;
- New_Item : String) return Unbounded_String;
+ New_Item : String) return Unbounded_String
+ with
+ Pre => Position - 1 <= Length (Source)
+ and then (if New_Item'Length /= 0
+ then
+ New_Item'Length <= Natural'Last - (Position - 1)),
+ Post =>
+ Length (Overwrite'Result)
+ = Natural'Max (Length (Source), Position - 1 + New_Item'Length),
+ Global => null;
procedure Overwrite
(Source : in out Unbounded_String;
Position : Positive;
- New_Item : String);
+ New_Item : String)
+ with
+ Pre => Position - 1 <= Length (Source)
+ and then (if New_Item'Length /= 0
+ then
+ New_Item'Length <= Natural'Last - (Position - 1)),
+ Post =>
+ Length (Source)
+ = Natural'Max (Length (Source)'Old, Position - 1 + New_Item'Length),
+
+ Global => null;
function Delete
(Source : Unbounded_String;
From : Positive;
- Through : Natural) return Unbounded_String;
+ Through : Natural) return Unbounded_String
+ with
+ Pre => (if Through <= From then From - 1 <= Length (Source)),
+ Contract_Cases =>
+ (Through >= From =>
+ Length (Delete'Result) = Length (Source) - (Through - From + 1),
+ others =>
+ Length (Delete'Result) = Length (Source)),
+ Global => null;
procedure Delete
(Source : in out Unbounded_String;
From : Positive;
- Through : Natural);
+ Through : Natural)
+ with
+ Pre => (if Through <= From then From - 1 <= Length (Source)),
+ Contract_Cases =>
+ (Through >= From =>
+ Length (Source) = Length (Source)'Old - (Through - From + 1),
+ others =>
+ Length (Source) = Length (Source)'Old),
+ Global => null;
function Trim
(Source : Unbounded_String;
- Side : Trim_End) return Unbounded_String;
+ Side : Trim_End) return Unbounded_String
+ with
+ Post => Length (Trim'Result) <= Length (Source),
+ Global => null;
procedure Trim
(Source : in out Unbounded_String;
- Side : Trim_End);
+ Side : Trim_End)
+ with
+ Post => Length (Source) <= Length (Source)'Old,
+ Global => null;
function Trim
(Source : Unbounded_String;
Left : Maps.Character_Set;
- Right : Maps.Character_Set) return Unbounded_String;
+ Right : Maps.Character_Set) return Unbounded_String
+ with
+ Post => Length (Trim'Result) <= Length (Source),
+ Global => null;
procedure Trim
(Source : in out Unbounded_String;
Left : Maps.Character_Set;
- Right : Maps.Character_Set);
+ Right : Maps.Character_Set)
+ with
+ Post => Length (Source) <= Length (Source)'Old,
+ Global => null;
function Head
(Source : Unbounded_String;
Count : Natural;
- Pad : Character := Space) return Unbounded_String;
+ Pad : Character := Space) return Unbounded_String
+ with
+ Post => Length (Head'Result) = Count,
+ Global => null;
procedure Head
(Source : in out Unbounded_String;
Count : Natural;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+ Post => Length (Source) = Count,
+ Global => null;
function Tail
(Source : Unbounded_String;
Count : Natural;
- Pad : Character := Space) return Unbounded_String;
+ Pad : Character := Space) return Unbounded_String
+ with
+ Post => Length (Tail'Result) = Count,
+ Global => null;
procedure Tail
(Source : in out Unbounded_String;
Count : Natural;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+ Post => Length (Source) = Count,
+ Global => null;
function "*"
(Left : Natural;
- Right : Character) return Unbounded_String;
+ Right : Character) return Unbounded_String
+ with
+ Pre => Left <= Natural'Last,
+ Post => Length ("*"'Result) = Left,
+ Global => null;
function "*"
(Left : Natural;
- Right : String) return Unbounded_String;
+ Right : String) return Unbounded_String
+ with
+ Pre => (if Left /= 0 then Right'Length <= Natural'Last / Left),
+ Post => Length ("*"'Result) = Left * Right'Length,
+ Global => null;
function "*"
(Left : Natural;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => (if Left /= 0 then Length (Right) <= Natural'Last / Left),
+ Post => Length ("*"'Result) = Left * Length (Right),
+ Global => null;
+
+ -- Each of the transformation functions (Replace_Slice, Insert, Overwrite,
+ -- Delete), selector functions (Trim, Head, Tail), and constructor
+ -- functions ("*") is likewise analogous to its corresponding subprogram in
+ -- Strings.Fixed. For each of the subprograms, the corresponding
+ -- fixed-length string subprogram is applied to the string represented by
+ -- the Unbounded_String parameter, and To_Unbounded_String is applied the
+ -- result string.
+ --
+ -- For each of the procedures Translate, Replace_Slice, Insert, Overwrite,
+ -- Delete, Trim, Head, and Tail, the resulting string represented by the
+ -- Source parameter is given by the corresponding function for fixed-length
+ -- strings applied to the string represented by Source's original value.
private
pragma Inline (Length);
diff --git a/gcc/ada/libgnat/a-strunb__shared.ads b/gcc/ada/libgnat/a-strunb__shared.ads
index 385a9e6..17acd56 100644
--- a/gcc/ada/libgnat/a-strunb__shared.ads
+++ b/gcc/ada/libgnat/a-strunb__shared.ads
@@ -33,6 +33,12 @@
-- --
------------------------------------------------------------------------------
+-- Preconditions in this unit are meant for analysis only, not for run-time
+-- checking, so that the expected exceptions are raised. This is enforced by
+-- setting the corresponding assertion policy to Ignore.
+
+pragma Assertion_Policy (Pre => Ignore);
+
-- This package provides an implementation of Ada.Strings.Unbounded that uses
-- reference counts to implement copy on modification (rather than copy on
-- assignment). This is significantly more efficient on many targets.
@@ -73,7 +79,9 @@ with Ada.Strings.Maps;
private with Ada.Finalization;
private with System.Atomic_Counters;
-package Ada.Strings.Unbounded is
+package Ada.Strings.Unbounded with
+ Initial_Condition => Length (Null_Unbounded_String) = 0
+is
pragma Preelaborate;
type Unbounded_String is private;
@@ -81,7 +89,8 @@ package Ada.Strings.Unbounded is
Null_Unbounded_String : constant Unbounded_String;
- function Length (Source : Unbounded_String) return Natural;
+ function Length (Source : Unbounded_String) return Natural with
+ Global => null;
type String_Access is access all String;
@@ -92,136 +101,229 @@ package Ada.Strings.Unbounded is
--------------------------------------------------------
function To_Unbounded_String
- (Source : String) return Unbounded_String;
+ (Source : String) return Unbounded_String
+ with
+ Post => Length (To_Unbounded_String'Result) = Source'Length,
+ Global => null;
function To_Unbounded_String
- (Length : Natural) return Unbounded_String;
+ (Length : Natural) return Unbounded_String
+ with
+ Post =>
+ Ada.Strings.Unbounded.Length (To_Unbounded_String'Result) = Length,
+ Global => null;
- function To_String (Source : Unbounded_String) return String;
+ function To_String (Source : Unbounded_String) return String with
+ Post => To_String'Result'Length = Length (Source),
+ Global => null;
procedure Set_Unbounded_String
(Target : out Unbounded_String;
- Source : String);
+ Source : String)
+ with
+ Global => null;
pragma Ada_05 (Set_Unbounded_String);
procedure Append
(Source : in out Unbounded_String;
- New_Item : Unbounded_String);
+ New_Item : Unbounded_String)
+ with
+ Pre => Length (New_Item) <= Natural'Last - Length (Source),
+ Post => Length (Source) = Length (Source)'Old + Length (New_Item),
+ Global => null;
procedure Append
(Source : in out Unbounded_String;
- New_Item : String);
+ New_Item : String)
+ with
+ Pre => New_Item'Length <= Natural'Last - Length (Source),
+ Post => Length (Source) = Length (Source)'Old + New_Item'Length,
+ Global => null;
procedure Append
(Source : in out Unbounded_String;
- New_Item : Character);
+ New_Item : Character)
+ with
+ Pre => Length (Source) < Natural'Last,
+ Post => Length (Source) = Length (Source)'Old + 1,
+ Global => null;
function "&"
(Left : Unbounded_String;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => Length (Right) <= Natural'Last - Length (Left),
+ Post => Length ("&"'Result) = Length (Left) + Length (Right),
+ Global => null;
function "&"
(Left : Unbounded_String;
- Right : String) return Unbounded_String;
+ Right : String) return Unbounded_String
+ with
+ Pre => Right'Length <= Natural'Last - Length (Left),
+ Post => Length ("&"'Result) = Length (Left) + Right'Length,
+ Global => null;
function "&"
(Left : String;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => Left'Length <= Natural'Last - Length (Right),
+ Post => Length ("&"'Result) = Left'Length + Length (Right),
+ Global => null;
function "&"
(Left : Unbounded_String;
- Right : Character) return Unbounded_String;
+ Right : Character) return Unbounded_String
+ with
+ Pre => Length (Left) < Natural'Last,
+ Post => Length ("&"'Result) = Length (Left) + 1,
+ Global => null;
function "&"
(Left : Character;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => Length (Right) < Natural'Last,
+ Post => Length ("&"'Result) = Length (Right) + 1,
+ Global => null;
function Element
(Source : Unbounded_String;
- Index : Positive) return Character;
+ Index : Positive) return Character
+ with
+ Pre => Index <= Length (Source),
+ Global => null;
procedure Replace_Element
(Source : in out Unbounded_String;
Index : Positive;
- By : Character);
+ By : Character)
+ with
+ Pre => Index <= Length (Source),
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
function Slice
(Source : Unbounded_String;
Low : Positive;
- High : Natural) return String;
+ High : Natural) return String
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post => Slice'Result'Length = Natural'Max (0, High - Low + 1),
+ Global => null;
function Unbounded_Slice
(Source : Unbounded_String;
Low : Positive;
- High : Natural) return Unbounded_String;
+ High : Natural) return Unbounded_String
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post =>
+ Length (Unbounded_Slice'Result) = Natural'Max (0, High - Low + 1),
+ Global => null;
pragma Ada_05 (Unbounded_Slice);
procedure Unbounded_Slice
(Source : Unbounded_String;
Target : out Unbounded_String;
Low : Positive;
- High : Natural);
+ High : Natural)
+ with
+ Pre => Low - 1 <= Length (Source) and then High <= Length (Source),
+ Post => Length (Target) = Natural'Max (0, High - Low + 1),
+ Global => null;
pragma Ada_05 (Unbounded_Slice);
function "="
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "="
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "="
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<"
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<"
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "<"
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<="
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function "<="
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function "<="
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">"
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">"
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function ">"
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">="
(Left : Unbounded_String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
function ">="
(Left : Unbounded_String;
- Right : String) return Boolean;
+ Right : String) return Boolean
+ with
+ Global => null;
function ">="
(Left : String;
- Right : Unbounded_String) return Boolean;
+ Right : Unbounded_String) return Boolean
+ with
+ Global => null;
------------------------
-- Search Subprograms --
@@ -231,26 +333,39 @@ package Ada.Strings.Unbounded is
(Source : Unbounded_String;
Pattern : String;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Index
(Source : Unbounded_String;
Pattern : String;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Index
(Source : Unbounded_String;
Set : Maps.Character_Set;
Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
function Index
(Source : Unbounded_String;
Pattern : String;
From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => (if Length (Source) /= 0
+ then From <= Length (Source))
+ and then Pattern'Length /= 0,
+ Global => null;
pragma Ada_05 (Index);
function Index
@@ -258,7 +373,13 @@ package Ada.Strings.Unbounded is
Pattern : String;
From : Positive;
Going : Direction := Forward;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => (if Length (Source) /= 0
+ then From <= Length (Source))
+ and then Pattern'Length /= 0,
+ Global => null;
+
pragma Ada_05 (Index);
function Index
@@ -266,32 +387,48 @@ package Ada.Strings.Unbounded is
Set : Maps.Character_Set;
From : Positive;
Test : Membership := Inside;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_05 (Index);
function Index_Non_Blank
(Source : Unbounded_String;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Global => null;
function Index_Non_Blank
(Source : Unbounded_String;
From : Positive;
- Going : Direction := Forward) return Natural;
+ Going : Direction := Forward) return Natural
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_05 (Index_Non_Blank);
function Count
(Source : Unbounded_String;
Pattern : String;
- Mapping : Maps.Character_Mapping := Maps.Identity) return Natural;
+ Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Count
(Source : Unbounded_String;
Pattern : String;
- Mapping : Maps.Character_Mapping_Function) return Natural;
+ Mapping : Maps.Character_Mapping_Function) return Natural
+ with
+ Pre => Pattern'Length /= 0,
+ Global => null;
function Count
(Source : Unbounded_String;
- Set : Maps.Character_Set) return Natural;
+ Set : Maps.Character_Set) return Natural
+ with
+ Global => null;
procedure Find_Token
(Source : Unbounded_String;
@@ -299,7 +436,10 @@ package Ada.Strings.Unbounded is
From : Positive;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Pre => (if Length (Source) /= 0 then From <= Length (Source)),
+ Global => null;
pragma Ada_2012 (Find_Token);
procedure Find_Token
@@ -307,7 +447,9 @@ package Ada.Strings.Unbounded is
Set : Maps.Character_Set;
Test : Membership;
First : out Positive;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Global => null;
------------------------------------
-- String Translation Subprograms --
@@ -315,19 +457,31 @@ package Ada.Strings.Unbounded is
function Translate
(Source : Unbounded_String;
- Mapping : Maps.Character_Mapping) return Unbounded_String;
+ Mapping : Maps.Character_Mapping) return Unbounded_String
+ with
+ Post => Length (Translate'Result) = Length (Source),
+ Global => null;
procedure Translate
(Source : in out Unbounded_String;
- Mapping : Maps.Character_Mapping);
+ Mapping : Maps.Character_Mapping)
+ with
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
function Translate
(Source : Unbounded_String;
- Mapping : Maps.Character_Mapping_Function) return Unbounded_String;
+ Mapping : Maps.Character_Mapping_Function) return Unbounded_String
+ with
+ Post => Length (Translate'Result) = Length (Source),
+ Global => null;
procedure Translate
(Source : in out Unbounded_String;
- Mapping : Maps.Character_Mapping_Function);
+ Mapping : Maps.Character_Mapping_Function)
+ with
+ Post => Length (Source) = Length (Source)'Old,
+ Global => null;
---------------------------------------
-- String Transformation Subprograms --
@@ -337,93 +491,204 @@ package Ada.Strings.Unbounded is
(Source : Unbounded_String;
Low : Positive;
High : Natural;
- By : String) return Unbounded_String;
+ By : String) return Unbounded_String
+ with
+ Pre =>
+ Low - 1 <= Length (Source)
+ and then (if High >= Low
+ then Low - 1
+ <= Natural'Last - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Natural'Last - By'Length),
+ Contract_Cases =>
+ (High >= Low =>
+ Length (Replace_Slice'Result)
+ = Low - 1 + By'Length + Natural'Max (Length (Source)'Old - High, 0),
+ others =>
+ Length (Replace_Slice'Result) = Length (Source)'Old + By'Length),
+ Global => null;
procedure Replace_Slice
(Source : in out Unbounded_String;
Low : Positive;
High : Natural;
- By : String);
+ By : String)
+ with
+ Pre =>
+ Low - 1 <= Length (Source)
+ and then (if High >= Low
+ then Low - 1
+ <= Natural'Last - By'Length
+ - Natural'Max (Length (Source) - High, 0)
+ else Length (Source) <= Natural'Last - By'Length),
+ Contract_Cases =>
+ (High >= Low =>
+ Length (Source)
+ = Low - 1 + By'Length + Natural'Max (Length (Source)'Old - High, 0),
+ others =>
+ Length (Source) = Length (Source)'Old + By'Length),
+ Global => null;
function Insert
(Source : Unbounded_String;
Before : Positive;
- New_Item : String) return Unbounded_String;
+ New_Item : String) return Unbounded_String
+ with
+ Pre => Before - 1 <= Length (Source)
+ and then New_Item'Length <= Natural'Last - Length (Source),
+ Post => Length (Insert'Result) = Length (Source) + New_Item'Length,
+ Global => null;
procedure Insert
(Source : in out Unbounded_String;
Before : Positive;
- New_Item : String);
+ New_Item : String)
+ with
+ Pre => Before - 1 <= Length (Source)
+ and then New_Item'Length <= Natural'Last - Length (Source),
+ Post => Length (Source) = Length (Source)'Old + New_Item'Length,
+ Global => null;
function Overwrite
(Source : Unbounded_String;
Position : Positive;
- New_Item : String) return Unbounded_String;
+ New_Item : String) return Unbounded_String
+ with
+ Pre => Position - 1 <= Length (Source)
+ and then (if New_Item'Length /= 0
+ then
+ New_Item'Length <= Natural'Last - (Position - 1)),
+ Post =>
+ Length (Overwrite'Result)
+ = Natural'Max (Length (Source), Position - 1 + New_Item'Length),
+ Global => null;
procedure Overwrite
(Source : in out Unbounded_String;
Position : Positive;
- New_Item : String);
+ New_Item : String)
+ with
+ Pre => Position - 1 <= Length (Source)
+ and then (if New_Item'Length /= 0
+ then
+ New_Item'Length <= Natural'Last - (Position - 1)),
+ Post =>
+ Length (Source)
+ = Natural'Max (Length (Source)'Old, Position - 1 + New_Item'Length),
+
+ Global => null;
function Delete
(Source : Unbounded_String;
From : Positive;
- Through : Natural) return Unbounded_String;
+ Through : Natural) return Unbounded_String
+ with
+ Pre => (if Through <= From then From - 1 <= Length (Source)),
+ Contract_Cases =>
+ (Through >= From =>
+ Length (Delete'Result) = Length (Source) - (Through - From + 1),
+ others =>
+ Length (Delete'Result) = Length (Source)),
+ Global => null;
procedure Delete
(Source : in out Unbounded_String;
From : Positive;
- Through : Natural);
+ Through : Natural)
+ with
+ Pre => (if Through <= From then From - 1 <= Length (Source)),
+ Contract_Cases =>
+ (Through >= From =>
+ Length (Source) = Length (Source)'Old - (Through - From + 1),
+ others =>
+ Length (Source) = Length (Source)'Old),
+ Global => null;
function Trim
(Source : Unbounded_String;
- Side : Trim_End) return Unbounded_String;
+ Side : Trim_End) return Unbounded_String
+ with
+ Post => Length (Trim'Result) <= Length (Source),
+ Global => null;
procedure Trim
(Source : in out Unbounded_String;
- Side : Trim_End);
+ Side : Trim_End)
+ with
+ Post => Length (Source) <= Length (Source)'Old,
+ Global => null;
function Trim
(Source : Unbounded_String;
Left : Maps.Character_Set;
- Right : Maps.Character_Set) return Unbounded_String;
+ Right : Maps.Character_Set) return Unbounded_String
+ with
+ Post => Length (Trim'Result) <= Length (Source),
+ Global => null;
procedure Trim
(Source : in out Unbounded_String;
Left : Maps.Character_Set;
- Right : Maps.Character_Set);
+ Right : Maps.Character_Set)
+ with
+ Post => Length (Source) <= Length (Source)'Old,
+ Global => null;
function Head
(Source : Unbounded_String;
Count : Natural;
- Pad : Character := Space) return Unbounded_String;
+ Pad : Character := Space) return Unbounded_String
+ with
+ Post => Length (Head'Result) = Count,
+ Global => null;
procedure Head
(Source : in out Unbounded_String;
Count : Natural;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+ Post => Length (Source) = Count,
+ Global => null;
function Tail
(Source : Unbounded_String;
Count : Natural;
- Pad : Character := Space) return Unbounded_String;
+ Pad : Character := Space) return Unbounded_String
+ with
+ Post => Length (Tail'Result) = Count,
+ Global => null;
procedure Tail
(Source : in out Unbounded_String;
Count : Natural;
- Pad : Character := Space);
+ Pad : Character := Space)
+ with
+ Post => Length (Source) = Count,
+ Global => null;
function "*"
(Left : Natural;
- Right : Character) return Unbounded_String;
+ Right : Character) return Unbounded_String
+ with
+ Pre => Left <= Natural'Last,
+ Post => Length ("*"'Result) = Left,
+ Global => null;
function "*"
(Left : Natural;
- Right : String) return Unbounded_String;
+ Right : String) return Unbounded_String
+ with
+ Pre => (if Left /= 0 then Right'Length <= Natural'Last / Left),
+ Post => Length ("*"'Result) = Left * Right'Length,
+ Global => null;
function "*"
(Left : Natural;
- Right : Unbounded_String) return Unbounded_String;
+ Right : Unbounded_String) return Unbounded_String
+ with
+ Pre => (if Left /= 0 then Length (Right) <= Natural'Last / Left),
+ Post => Length ("*"'Result) = Left * Length (Right),
+ Global => null;
private
pragma Inline (Length);
diff --git a/gcc/ada/libgnat/a-textio.adb b/gcc/ada/libgnat/a-textio.adb
index 5b6e28a..276be12 100644
--- a/gcc/ada/libgnat/a-textio.adb
+++ b/gcc/ada/libgnat/a-textio.adb
@@ -43,7 +43,18 @@ with Ada.Unchecked_Deallocation;
pragma Elaborate_All (System.File_IO);
-- Needed because of calls to Chain_File in package body elaboration
-package body Ada.Text_IO is
+package body Ada.Text_IO with
+ Refined_State => (File_System => (Standard_In,
+ Standard_Out,
+ Standard_Err,
+ Current_In,
+ Current_Out,
+ Current_Err,
+ In_Name,
+ Out_Name,
+ Err_Name,
+ WC_Encoding))
+is
package FIO renames System.File_IO;
diff --git a/gcc/ada/libgnat/a-textio.ads b/gcc/ada/libgnat/a-textio.ads
index 32bbc6c..a2e1daf 100644
--- a/gcc/ada/libgnat/a-textio.ads
+++ b/gcc/ada/libgnat/a-textio.ads
@@ -33,6 +33,14 @@
-- --
------------------------------------------------------------------------------
+-- Preconditions in this unit are meant for analysis only, not for run-time
+-- checking, so that the expected exceptions are raised. This is enforced by
+-- setting the corresponding assertion policy to Ignore. These preconditions
+-- are partial and protect against Status_Error, Mode_Error, and Layout_Error,
+-- but not against other types of errors.
+
+pragma Assertion_Policy (Pre => Ignore);
+
-- Note: the generic subpackages of Text_IO (Integer_IO, Float_IO, Fixed_IO,
-- Modular_IO, Decimal_IO and Enumeration_IO) appear as private children in
-- GNAT. These children are with'ed automatically if they are referenced, so
@@ -46,10 +54,15 @@ with System;
with System.File_Control_Block;
with System.WCh_Con;
-package Ada.Text_IO is
+package Ada.Text_IO with
+ Abstract_State => (File_System),
+ Initializes => (File_System),
+ Initial_Condition => Line_Length = 0 and Page_Length = 0
+is
pragma Elaborate_Body;
- type File_Type is limited private with Default_Initial_Condition;
+ type File_Type is limited private with
+ Default_Initial_Condition => (not Is_Open (File_Type));
type File_Mode is (In_File, Out_File, Append_File);
-- The following representation clause allows the use of unchecked
@@ -87,50 +100,97 @@ package Ada.Text_IO is
(File : in out File_Type;
Mode : File_Mode := Out_File;
Name : String := "";
- Form : String := "");
+ Form : String := "")
+ with
+ Pre => not Is_Open (File),
+ Post =>
+ Is_Open (File)
+ and then Ada.Text_IO.Mode (File) = Mode
+ and then (if Mode /= In_File
+ then (Line_Length (File) = 0
+ and then Page_Length (File) = 0)),
+ Global => (In_Out => File_System);
procedure Open
(File : in out File_Type;
Mode : File_Mode;
Name : String;
- Form : String := "");
-
- procedure Close (File : in out File_Type);
- procedure Delete (File : in out File_Type);
- procedure Reset (File : in out File_Type; Mode : File_Mode);
- procedure Reset (File : in out File_Type);
-
- function Mode (File : File_Type) return File_Mode;
- function Name (File : File_Type) return String;
- function Form (File : File_Type) return String;
-
- function Is_Open (File : File_Type) return Boolean;
+ Form : String := "")
+ with
+ Pre => not Is_Open (File),
+ Post =>
+ Is_Open (File)
+ and then Ada.Text_IO.Mode (File) = Mode
+ and then (if Mode /= In_File
+ then (Line_Length (File) = 0
+ and then Page_Length (File) = 0)),
+ Global => (In_Out => File_System);
+
+ procedure Close (File : in out File_Type) with
+ Pre => Is_Open (File),
+ Post => not Is_Open (File),
+ Global => (In_Out => File_System);
+ procedure Delete (File : in out File_Type) with
+ Pre => Is_Open (File),
+ Post => not Is_Open (File),
+ Global => (In_Out => File_System);
+ procedure Reset (File : in out File_Type; Mode : File_Mode) with
+ Pre => Is_Open (File),
+ Post =>
+ Is_Open (File)
+ and then Ada.Text_IO.Mode (File) = Mode
+ and then (if Mode /= In_File
+ then (Line_Length (File) = 0
+ and then Page_Length (File) = 0)),
+ Global => (In_Out => File_System);
+ procedure Reset (File : in out File_Type) with
+ Pre => Is_Open (File),
+ Post =>
+ Is_Open (File)
+ and Mode (File)'Old = Mode (File)
+ and (if Mode (File) /= In_File
+ then (Line_Length (File) = 0
+ and then Page_Length (File) = 0)),
+ Global => (In_Out => File_System);
+
+ function Mode (File : File_Type) return File_Mode with
+ Pre => Is_Open (File),
+ Global => null;
+ function Name (File : File_Type) return String with
+ Pre => Is_Open (File),
+ Global => null;
+ function Form (File : File_Type) return String with
+ Pre => Is_Open (File),
+ Global => null;
+
+ function Is_Open (File : File_Type) return Boolean with
+ Global => null;
------------------------------------------------------
-- Control of default input, output and error files --
------------------------------------------------------
- procedure Set_Input (File : File_Type);
- procedure Set_Output (File : File_Type);
- procedure Set_Error (File : File_Type);
+ procedure Set_Input (File : File_Type) with SPARK_Mode => Off;
+ procedure Set_Output (File : File_Type) with SPARK_Mode => Off;
+ procedure Set_Error (File : File_Type) with SPARK_Mode => Off;
- function Standard_Input return File_Type;
- function Standard_Output return File_Type;
- function Standard_Error return File_Type;
+ function Standard_Input return File_Type with SPARK_Mode => Off;
+ function Standard_Output return File_Type with SPARK_Mode => Off;
+ function Standard_Error return File_Type with SPARK_Mode => Off;
- function Current_Input return File_Type;
- function Current_Output return File_Type;
- function Current_Error return File_Type;
+ function Current_Input return File_Type with SPARK_Mode => Off;
+ function Current_Output return File_Type with SPARK_Mode => Off;
+ function Current_Error return File_Type with SPARK_Mode => Off;
type File_Access is access constant File_Type;
- function Standard_Input return File_Access;
- function Standard_Output return File_Access;
- function Standard_Error return File_Access;
+ function Standard_Input return File_Access with SPARK_Mode => Off;
+ function Standard_Output return File_Access with SPARK_Mode => Off;
+ function Standard_Error return File_Access with SPARK_Mode => Off;
- function Current_Input return File_Access;
- function Current_Output return File_Access;
- function Current_Error return File_Access;
+ function Current_Input return File_Access with SPARK_Mode => Off;
+ function Current_Output return File_Access with SPARK_Mode => Off;
+ function Current_Error return File_Access with SPARK_Mode => Off;
--------------------
-- Buffer control --
@@ -139,129 +199,319 @@ package Ada.Text_IO is
-- Note: The parameter file is IN OUT in the RM, but this is clearly
-- an oversight, and was intended to be IN, see AI95-00057.
- procedure Flush (File : File_Type);
- procedure Flush;
+ procedure Flush (File : File_Type) with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
+ procedure Flush with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
--------------------------------------------
-- Specification of line and page lengths --
--------------------------------------------
- procedure Set_Line_Length (File : File_Type; To : Count);
- procedure Set_Line_Length (To : Count);
-
- procedure Set_Page_Length (File : File_Type; To : Count);
- procedure Set_Page_Length (To : Count);
-
- function Line_Length (File : File_Type) return Count;
- function Line_Length return Count;
-
- function Page_Length (File : File_Type) return Count;
- function Page_Length return Count;
+ procedure Set_Line_Length (File : File_Type; To : Count) with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File) = To
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
+ procedure Set_Line_Length (To : Count) with
+ Post =>
+ Line_Length = To
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+
+ procedure Set_Page_Length (File : File_Type; To : Count) with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Page_Length (File) = To
+ and Line_Length (File)'Old = Line_Length (File),
+ Global => (In_Out => File_System);
+ procedure Set_Page_Length (To : Count) with
+ Post =>
+ Page_Length = To
+ and Line_Length'Old = Line_Length,
+ Global => (In_Out => File_System);
+
+ function Line_Length (File : File_Type) return Count with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Global => (Input => File_System);
+ function Line_Length return Count with
+ Global => (Input => File_System);
+
+ function Page_Length (File : File_Type) return Count with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Global => (Input => File_System);
+ function Page_Length return Count with
+ Global => (Input => File_System);
------------------------------------
-- Column, Line, and Page Control --
------------------------------------
- procedure New_Line (File : File_Type; Spacing : Positive_Count := 1);
- procedure New_Line (Spacing : Positive_Count := 1);
-
- procedure Skip_Line (File : File_Type; Spacing : Positive_Count := 1);
- procedure Skip_Line (Spacing : Positive_Count := 1);
-
- function End_Of_Line (File : File_Type) return Boolean;
- function End_Of_Line return Boolean;
-
- procedure New_Page (File : File_Type);
- procedure New_Page;
-
- procedure Skip_Page (File : File_Type);
- procedure Skip_Page;
-
- function End_Of_Page (File : File_Type) return Boolean;
- function End_Of_Page return Boolean;
-
- function End_Of_File (File : File_Type) return Boolean;
- function End_Of_File return Boolean;
-
- procedure Set_Col (File : File_Type; To : Positive_Count);
- procedure Set_Col (To : Positive_Count);
-
- procedure Set_Line (File : File_Type; To : Positive_Count);
- procedure Set_Line (To : Positive_Count);
-
- function Col (File : File_Type) return Positive_Count;
- function Col return Positive_Count;
-
- function Line (File : File_Type) return Positive_Count;
- function Line return Positive_Count;
-
- function Page (File : File_Type) return Positive_Count;
- function Page return Positive_Count;
+ procedure New_Line (File : File_Type; Spacing : Positive_Count := 1) with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
+ procedure New_Line (Spacing : Positive_Count := 1) with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+
+ procedure Skip_Line (File : File_Type; Spacing : Positive_Count := 1) with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
+ procedure Skip_Line (Spacing : Positive_Count := 1) with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+
+ function End_Of_Line (File : File_Type) return Boolean with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (Input => File_System);
+ function End_Of_Line return Boolean with
+ Global => (Input => File_System);
+
+ procedure New_Page (File : File_Type) with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
+ procedure New_Page with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+
+ procedure Skip_Page (File : File_Type) with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
+ procedure Skip_Page with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+
+ function End_Of_Page (File : File_Type) return Boolean with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (Input => File_System);
+ function End_Of_Page return Boolean with
+ Global => (Input => File_System);
+
+ function End_Of_File (File : File_Type) return Boolean with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (Input => File_System);
+ function End_Of_File return Boolean with
+ Global => (Input => File_System);
+
+ procedure Set_Col (File : File_Type; To : Positive_Count) with
+ Pre =>
+ Is_Open (File)
+ and then (if Mode (File) /= In_File
+ then (Line_Length (File) = 0
+ or else To <= Line_Length (File))),
+ Contract_Cases =>
+ (Mode (File) /= In_File =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ others => True),
+ Global => (In_Out => File_System);
+ procedure Set_Col (To : Positive_Count) with
+ Pre => Line_Length = 0 or To <= Line_Length,
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+
+ procedure Set_Line (File : File_Type; To : Positive_Count) with
+ Pre =>
+ Is_Open (File)
+ and then (if Mode (File) /= In_File
+ then (Page_Length (File) = 0
+ or else To <= Page_Length (File))),
+ Contract_Cases =>
+ (Mode (File) /= In_File =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ others => True),
+ Global => (In_Out => File_System);
+ procedure Set_Line (To : Positive_Count) with
+ Pre => Page_Length = 0 or To <= Page_Length,
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+
+ function Col (File : File_Type) return Positive_Count with
+ Pre => Is_Open (File),
+ Global => (Input => File_System);
+ function Col return Positive_Count with
+ Global => (Input => File_System);
+
+ function Line (File : File_Type) return Positive_Count with
+ Pre => Is_Open (File),
+ Global => (Input => File_System);
+ function Line return Positive_Count with
+ Global => (Input => File_System);
+
+ function Page (File : File_Type) return Positive_Count with
+ Pre => Is_Open (File),
+ Global => (Input => File_System);
+ function Page return Positive_Count with
+ Global => (Input => File_System);
----------------------------
-- Character Input-Output --
----------------------------
- procedure Get (File : File_Type; Item : out Character);
- procedure Get (Item : out Character);
- procedure Put (File : File_Type; Item : Character);
- procedure Put (Item : Character);
+ procedure Get (File : File_Type; Item : out Character) with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
+ procedure Get (Item : out Character) with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+ procedure Put (File : File_Type; Item : Character) with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
+ procedure Put (Item : Character) with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Look_Ahead
(File : File_Type;
Item : out Character;
- End_Of_Line : out Boolean);
+ End_Of_Line : out Boolean)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (Input => File_System);
procedure Look_Ahead
(Item : out Character;
- End_Of_Line : out Boolean);
+ End_Of_Line : out Boolean)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (Input => File_System);
procedure Get_Immediate
(File : File_Type;
- Item : out Character);
+ Item : out Character)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
procedure Get_Immediate
- (Item : out Character);
+ (Item : out Character)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get_Immediate
(File : File_Type;
Item : out Character;
- Available : out Boolean);
+ Available : out Boolean)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
procedure Get_Immediate
(Item : out Character;
- Available : out Boolean);
+ Available : out Boolean)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
-------------------------
-- String Input-Output --
-------------------------
- procedure Get (File : File_Type; Item : out String);
- procedure Get (Item : out String);
- procedure Put (File : File_Type; Item : String);
- procedure Put (Item : String);
+ procedure Get (File : File_Type; Item : out String) with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
+ procedure Get (Item : out String) with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
+ procedure Put (File : File_Type; Item : String) with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
+ procedure Put (Item : String) with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get_Line
(File : File_Type;
Item : out String;
- Last : out Natural);
+ Last : out Natural)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Post => (if Item'Length > 0 then Last in Item'First - 1 .. Item'Last
+ else Last = Item'First - 1),
+ Global => (In_Out => File_System);
procedure Get_Line
(Item : out String;
- Last : out Natural);
-
- function Get_Line (File : File_Type) return String;
+ Last : out Natural)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length
+ and (if Item'Length > 0 then Last in Item'First - 1 .. Item'Last
+ else Last = Item'First - 1),
+ Global => (In_Out => File_System);
+
+ function Get_Line (File : File_Type) return String with SPARK_Mode => Off;
pragma Ada_05 (Get_Line);
- function Get_Line return String;
+ function Get_Line return String with SPARK_Mode => Off;
pragma Ada_05 (Get_Line);
procedure Put_Line
(File : File_Type;
- Item : String);
+ Item : String)
+ with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
procedure Put_Line
- (Item : String);
+ (Item : String)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
---------------------------------------
-- Generic packages for Input-Output --
@@ -447,14 +697,20 @@ private
Standard_Out_AFCB : aliased Text_AFCB;
Standard_Err_AFCB : aliased Text_AFCB;
- Standard_In : aliased File_Type := Standard_In_AFCB'Access;
- Standard_Out : aliased File_Type := Standard_Out_AFCB'Access;
- Standard_Err : aliased File_Type := Standard_Err_AFCB'Access;
+ Standard_In : aliased File_Type := Standard_In_AFCB'Access with
+ Part_Of => File_System;
+ Standard_Out : aliased File_Type := Standard_Out_AFCB'Access with
+ Part_Of => File_System;
+ Standard_Err : aliased File_Type := Standard_Err_AFCB'Access with
+ Part_Of => File_System;
-- Standard files
- Current_In : aliased File_Type := Standard_In;
- Current_Out : aliased File_Type := Standard_Out;
- Current_Err : aliased File_Type := Standard_Err;
+ Current_In : aliased File_Type := Standard_In with
+ Part_Of => File_System;
+ Current_Out : aliased File_Type := Standard_Out with
+ Part_Of => File_System;
+ Current_Err : aliased File_Type := Standard_Err with
+ Part_Of => File_System;
-- Current files
function EOF_Char return Integer;
diff --git a/gcc/ada/libgnat/a-tideio.ads b/gcc/ada/libgnat/a-tideio.ads
index c504707..efe52c5 100644
--- a/gcc/ada/libgnat/a-tideio.ads
+++ b/gcc/ada/libgnat/a-tideio.ads
@@ -52,35 +52,58 @@ package Ada.Text_IO.Decimal_IO is
procedure Get
(File : File_Type;
Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
procedure Get
(Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Put
(File : File_Type;
Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
procedure Put
(Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get
(From : String;
Item : out Num;
- Last : out Positive);
+ Last : out Positive)
+ with
+ Global => null;
procedure Put
(To : out String;
Item : Num;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Global => null;
private
pragma Inline (Get);
diff --git a/gcc/ada/libgnat/a-tienio.ads b/gcc/ada/libgnat/a-tienio.ads
index 68f4694..fb80abd 100644
--- a/gcc/ada/libgnat/a-tienio.ads
+++ b/gcc/ada/libgnat/a-tienio.ads
@@ -28,28 +28,49 @@ package Ada.Text_IO.Enumeration_IO is
Default_Width : Field := 0;
Default_Setting : Type_Set := Upper_Case;
- procedure Get (File : File_Type; Item : out Enum);
- procedure Get (Item : out Enum);
+ procedure Get (File : File_Type; Item : out Enum) with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
+ procedure Get (Item : out Enum) with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Put
(File : File_Type;
Item : Enum;
Width : Field := Default_Width;
- Set : Type_Set := Default_Setting);
+ Set : Type_Set := Default_Setting)
+ with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
procedure Put
(Item : Enum;
Width : Field := Default_Width;
- Set : Type_Set := Default_Setting);
+ Set : Type_Set := Default_Setting)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get
(From : String;
Item : out Enum;
- Last : out Positive);
+ Last : out Positive)
+ with
+ Global => null;
procedure Put
(To : out String;
Item : Enum;
- Set : Type_Set := Default_Setting);
+ Set : Type_Set := Default_Setting)
+ with
+ Global => null;
end Ada.Text_IO.Enumeration_IO;
diff --git a/gcc/ada/libgnat/a-tifiio.ads b/gcc/ada/libgnat/a-tifiio.ads
index 265600db..1acf67a 100644
--- a/gcc/ada/libgnat/a-tifiio.ads
+++ b/gcc/ada/libgnat/a-tifiio.ads
@@ -32,35 +32,58 @@ package Ada.Text_IO.Fixed_IO is
procedure Get
(File : File_Type;
Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
procedure Get
(Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Put
(File : File_Type;
Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
procedure Put
(Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get
(From : String;
Item : out Num;
- Last : out Positive);
+ Last : out Positive)
+ with
+ Global => null;
procedure Put
(To : out String;
Item : Num;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Global => null;
private
pragma Inline (Get);
diff --git a/gcc/ada/libgnat/a-tiflio.ads b/gcc/ada/libgnat/a-tiflio.ads
index dcc4856..16e65a5 100644
--- a/gcc/ada/libgnat/a-tiflio.ads
+++ b/gcc/ada/libgnat/a-tiflio.ads
@@ -52,35 +52,58 @@ package Ada.Text_IO.Float_IO is
procedure Get
(File : File_Type;
Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
procedure Get
(Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Put
(File : File_Type;
Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
procedure Put
(Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get
(From : String;
Item : out Num;
- Last : out Positive);
+ Last : out Positive)
+ with
+ Global => null;
procedure Put
(To : out String;
Item : Num;
Aft : Field := Default_Aft;
- Exp : Field := Default_Exp);
+ Exp : Field := Default_Exp)
+ with
+ Global => null;
private
pragma Inline (Get);
diff --git a/gcc/ada/libgnat/a-tiinio.ads b/gcc/ada/libgnat/a-tiinio.ads
index 429f3b1..28f8d54 100644
--- a/gcc/ada/libgnat/a-tiinio.ads
+++ b/gcc/ada/libgnat/a-tiinio.ads
@@ -51,32 +51,55 @@ package Ada.Text_IO.Integer_IO is
procedure Get
(File : File_Type;
Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
procedure Get
(Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Put
(File : File_Type;
Item : Num;
Width : Field := Default_Width;
- Base : Number_Base := Default_Base);
+ Base : Number_Base := Default_Base)
+ with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
procedure Put
(Item : Num;
Width : Field := Default_Width;
- Base : Number_Base := Default_Base);
+ Base : Number_Base := Default_Base)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get
(From : String;
Item : out Num;
- Last : out Positive);
+ Last : out Positive)
+ with
+ Global => null;
procedure Put
(To : out String;
Item : Num;
- Base : Number_Base := Default_Base);
+ Base : Number_Base := Default_Base)
+ with
+ Global => null;
private
pragma Inline (Get);
diff --git a/gcc/ada/libgnat/a-timoio.ads b/gcc/ada/libgnat/a-timoio.ads
index 5b8a72e..2d1ab91 100644
--- a/gcc/ada/libgnat/a-timoio.ads
+++ b/gcc/ada/libgnat/a-timoio.ads
@@ -51,32 +51,55 @@ package Ada.Text_IO.Modular_IO is
procedure Get
(File : File_Type;
Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Pre => Is_Open (File) and then Mode (File) = In_File,
+ Global => (In_Out => File_System);
procedure Get
(Item : out Num;
- Width : Field := 0);
+ Width : Field := 0)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Put
(File : File_Type;
Item : Num;
Width : Field := Default_Width;
- Base : Number_Base := Default_Base);
+ Base : Number_Base := Default_Base)
+ with
+ Pre => Is_Open (File) and then Mode (File) /= In_File,
+ Post =>
+ Line_Length (File)'Old = Line_Length (File)
+ and Page_Length (File)'Old = Page_Length (File),
+ Global => (In_Out => File_System);
procedure Put
(Item : Num;
Width : Field := Default_Width;
- Base : Number_Base := Default_Base);
+ Base : Number_Base := Default_Base)
+ with
+ Post =>
+ Line_Length'Old = Line_Length
+ and Page_Length'Old = Page_Length,
+ Global => (In_Out => File_System);
procedure Get
(From : String;
Item : out Num;
- Last : out Positive);
+ Last : out Positive)
+ with
+ Global => null;
procedure Put
(To : out String;
Item : Num;
- Base : Number_Base := Default_Base);
+ Base : Number_Base := Default_Base)
+ with
+ Global => null;
private
pragma Inline (Get);
diff --git a/gcc/ada/libgnat/a-wichha.ads b/gcc/ada/libgnat/a-wichha.ads
index 583308e..a906e02 100644
--- a/gcc/ada/libgnat/a-wichha.ads
+++ b/gcc/ada/libgnat/a-wichha.ads
@@ -25,28 +25,28 @@ package Ada.Wide_Characters.Handling is
function Is_Control (Item : Wide_Character) return Boolean;
pragma Inline (Is_Control);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- other_control, otherwise returns false.
+ -- other_control, otherwise returns False.
function Is_Letter (Item : Wide_Character) return Boolean;
pragma Inline (Is_Letter);
-- Returns True if the Wide_Character designated by Item is categorized as
-- letter_uppercase, letter_lowercase, letter_titlecase, letter_modifier,
- -- letter_other, or number_letter. Otherwise returns false.
+ -- letter_other, or number_letter. Otherwise returns False.
function Is_Lower (Item : Wide_Character) return Boolean;
pragma Inline (Is_Lower);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- letter_lowercase, otherwise returns false.
+ -- letter_lowercase, otherwise returns False.
function Is_Upper (Item : Wide_Character) return Boolean;
pragma Inline (Is_Upper);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- letter_uppercase, otherwise returns false.
+ -- letter_uppercase, otherwise returns False.
function Is_Digit (Item : Wide_Character) return Boolean;
pragma Inline (Is_Digit);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- number_decimal, otherwise returns false.
+ -- number_decimal, otherwise returns False.
function Is_Decimal_Digit (Item : Wide_Character) return Boolean
renames Is_Digit;
@@ -54,51 +54,51 @@ package Ada.Wide_Characters.Handling is
function Is_Hexadecimal_Digit (Item : Wide_Character) return Boolean;
-- Returns True if the Wide_Character designated by Item is categorized as
-- number_decimal, or is in the range 'A' .. 'F' or 'a' .. 'f', otherwise
- -- returns false.
+ -- returns False.
function Is_Alphanumeric (Item : Wide_Character) return Boolean;
pragma Inline (Is_Alphanumeric);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- number_decimal, or is in the range 'A' .. 'F' or 'a' .. 'f', otherwise
- -- returns false.
+ -- letter_uppercase, letter_lowercase, letter_titlecase, letter_modifier,
+ -- letter_other, number_letter, or number_decimal; otherwise returns False.
function Is_Special (Item : Wide_Character) return Boolean;
pragma Inline (Is_Special);
-- Returns True if the Wide_Character designated by Item is categorized
-- as graphic_character, but not categorized as letter_uppercase,
-- letter_lowercase, letter_titlecase, letter_modifier, letter_other,
- -- number_letter, or number_decimal. Otherwise returns false.
+ -- number_letter, or number_decimal. Otherwise returns False.
function Is_Line_Terminator (Item : Wide_Character) return Boolean;
pragma Inline (Is_Line_Terminator);
-- Returns True if the Wide_Character designated by Item is categorized as
-- separator_line or separator_paragraph, or if Item is a conventional line
- -- terminator character (CR, LF, VT, or FF). Otherwise returns false.
+ -- terminator character (CR, LF, VT, or FF). Otherwise returns False.
function Is_Mark (Item : Wide_Character) return Boolean;
pragma Inline (Is_Mark);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- mark_non_spacing or mark_spacing_combining, otherwise returns false.
+ -- mark_non_spacing or mark_spacing_combining, otherwise returns False.
function Is_Other_Format (Item : Wide_Character) return Boolean;
pragma Inline (Is_Other_Format);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- other_format, otherwise returns false.
+ -- other_format, otherwise returns False.
function Is_Punctuation_Connector (Item : Wide_Character) return Boolean;
pragma Inline (Is_Punctuation_Connector);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- punctuation_connector, otherwise returns false.
+ -- punctuation_connector, otherwise returns False.
function Is_Space (Item : Wide_Character) return Boolean;
pragma Inline (Is_Space);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- separator_space, otherwise returns false.
+ -- separator_space, otherwise returns False.
function Is_Graphic (Item : Wide_Character) return Boolean;
pragma Inline (Is_Graphic);
-- Returns True if the Wide_Character designated by Item is categorized as
- -- graphic_character, otherwise returns false.
+ -- graphic_character, otherwise returns False.
function To_Lower (Item : Wide_Character) return Wide_Character;
pragma Inline (To_Lower);
diff --git a/gcc/ada/libgnat/g-brapre.ads b/gcc/ada/libgnat/g-brapre.ads
new file mode 100644
index 0000000..9b88e35
--- /dev/null
+++ b/gcc/ada/libgnat/g-brapre.ads
@@ -0,0 +1,68 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- G N A T . B R A N C H _ P R E D I C T I O N --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2019, AdaCore --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides routines giving hints to the branch predictor of the
+-- code generator. These hints are useful when optimization is enabled and the
+-- branch probability heuristics are used (which is the default), but they are
+-- overridden when profile feedback-directed optimization is used instead.
+
+-- The canonical pattern is to use them as the condition of an If statement:
+--
+-- if Likely (X > 0) then
+-- Do_Something;
+-- end if;
+--
+-- when it is not obvious that one outcome of the condition is more likely
+-- than the other, or else to reverse the prediction made by the heuristics
+-- in very peculiar cases. In the other cases, it is better not to use them,
+-- because predicting how programs actually perform is notoriously hard.
+
+package GNAT.Branch_Prediction is
+ pragma Pure;
+
+ function Expect (Condition : Boolean; Outcome : Boolean) return Boolean;
+ pragma Import (Intrinsic, Expect, "__builtin_expect");
+ -- This function returns the value of its first parameter Condition and
+ -- tells the branch predictor that this value is expected to be Outcome.
+
+ function Likely (Condition : Boolean) return Boolean;
+ pragma Import (Intrinsic, Likely, "__builtin_likely");
+ -- This function returns the value of its parameter Condition and tells
+ -- the branch predictor that this value is expected to be True. Calling
+ -- it is strictly equivalent to calling Expect with Outcome set to True.
+
+ function Unlikely (Condition : Boolean) return Boolean;
+ pragma Import (Intrinsic, Unlikely, "__builtin_unlikely");
+ -- This function returns the value of its parameter Condition and tells
+ -- the branch predictor that this value is expected to be False. Calling
+ -- it is strictly equivalent to calling Expect with Outcome set to False.
+
+end GNAT.Branch_Prediction;
diff --git a/gcc/ada/libgnat/g-comlin.adb b/gcc/ada/libgnat/g-comlin.adb
index 0f527c6..29100af 100644
--- a/gcc/ada/libgnat/g-comlin.adb
+++ b/gcc/ada/libgnat/g-comlin.adb
@@ -443,7 +443,7 @@ package body GNAT.Command_Line is
Parser.Current_Argument := Parser.Current_Argument + 1;
- -- Could it be a file name with wild cards to expand?
+ -- Could it be a file name with wildcards to expand?
if Do_Expansion then
declare
diff --git a/gcc/ada/libgnat/g-comlin.ads b/gcc/ada/libgnat/g-comlin.ads
index 8306f9a..f1251b6 100644
--- a/gcc/ada/libgnat/g-comlin.ads
+++ b/gcc/ada/libgnat/g-comlin.ads
@@ -466,9 +466,9 @@ package GNAT.Command_Line is
-- function should not be called before Getopt has returned ASCII.NUL.
--
-- If Do_Expansion is True, then the parameter on the command line will
- -- be considered as a filename with wild cards, and will be expanded. The
+ -- be considered as a filename with wildcards, and will be expanded. The
-- matching file names will be returned one at a time. This is useful in
- -- non-Unix systems for obtaining normal expansion of wild card references.
+ -- non-Unix systems for obtaining normal expansion of wildcard references.
-- When there are no more arguments on the command line, this function
-- returns an empty string.
@@ -515,7 +515,7 @@ package GNAT.Command_Line is
Pattern : String;
Directory : String := "";
Basic_Regexp : Boolean := True);
- -- Initialize a wild card expansion. The next calls to Expansion will
+ -- Initialize a wildcard expansion. The next calls to Expansion will
-- return the next file name in Directory which match Pattern (Pattern
-- is a regular expression, using only the Unix shell and DOS syntax if
-- Basic_Regexp is True). When Directory is an empty string, the current
diff --git a/gcc/ada/libgnat/g-encstr.adb b/gcc/ada/libgnat/g-encstr.adb
index 81a73fd..b115c8a 100644
--- a/gcc/ada/libgnat/g-encstr.adb
+++ b/gcc/ada/libgnat/g-encstr.adb
@@ -79,12 +79,12 @@ package body GNAT.Encode_String is
Ptr : Natural;
begin
- Ptr := S'First;
+ Ptr := Result'First;
for J in S'Range loop
Encode_Wide_Character (S (J), Result, Ptr);
end loop;
- Length := Ptr - S'First;
+ Length := Ptr - Result'First;
end Encode_Wide_String;
-----------------------------
@@ -108,12 +108,12 @@ package body GNAT.Encode_String is
Ptr : Natural;
begin
- Ptr := S'First;
+ Ptr := Result'First;
for J in S'Range loop
Encode_Wide_Wide_Character (S (J), Result, Ptr);
end loop;
- Length := Ptr - S'First;
+ Length := Ptr - Result'First;
end Encode_Wide_Wide_String;
---------------------------
diff --git a/gcc/ada/libgnat/g-exptty.adb b/gcc/ada/libgnat/g-exptty.adb
index 1a977b5..728c5c6 100644
--- a/gcc/ada/libgnat/g-exptty.adb
+++ b/gcc/ada/libgnat/g-exptty.adb
@@ -38,6 +38,28 @@ package body GNAT.Expect.TTY is
On_Windows : constant Boolean := Directory_Separator = '\';
-- True when on Windows
+ function Waitpid (Process : System.Address; Blocking : Integer)
+ return Integer;
+ pragma Import (C, Waitpid, "__gnat_tty_waitpid");
+ -- Wait for a specific process id, and return its exit code
+
+ ------------------------
+ -- Is_Process_Running --
+ ------------------------
+
+ function Is_Process_Running
+ (Descriptor : in out TTY_Process_Descriptor)
+ return Boolean
+ is
+ begin
+ if Descriptor.Process = System.Null_Address then
+ return False;
+ end if;
+
+ Descriptor.Exit_Status := Waitpid (Descriptor.Process, Blocking => 0);
+ return Descriptor.Exit_Status = Still_Active;
+ end Is_Process_Running;
+
-----------
-- Close --
-----------
@@ -49,10 +71,6 @@ package body GNAT.Expect.TTY is
procedure Terminate_Process (Process : System.Address);
pragma Import (C, Terminate_Process, "__gnat_terminate_process");
- function Waitpid (Process : System.Address) return Integer;
- pragma Import (C, Waitpid, "__gnat_tty_waitpid");
- -- Wait for a specific process id, and return its exit code
-
procedure Free_Process (Process : System.Address);
pragma Import (C, Free_Process, "__gnat_free_process");
@@ -63,7 +81,7 @@ package body GNAT.Expect.TTY is
-- If we haven't already closed the process
if Descriptor.Process = System.Null_Address then
- Status := -1;
+ Status := Descriptor.Exit_Status;
else
-- Send a Ctrl-C to the process first. This way, if the launched
@@ -75,9 +93,6 @@ package body GNAT.Expect.TTY is
-- signal, so this needs to be done while the file descriptors are
-- still open (it used to be after the closes and that was wrong).
- Interrupt (Descriptor);
- delay (0.05);
-
if Descriptor.Input_Fd /= Invalid_FD then
Close (Descriptor.Input_Fd);
end if;
@@ -92,8 +107,23 @@ package body GNAT.Expect.TTY is
Close (Descriptor.Output_Fd);
end if;
- Terminate_Process (Descriptor.Process);
- Status := Waitpid (Descriptor.Process);
+ if Descriptor.Exit_Status = Still_Active then
+ Status := Waitpid (Descriptor.Process, Blocking => 0);
+
+ if Status = Still_Active then
+ -- In theory the process might hav died since the check. In
+ -- practice the following calls should not cause any issue.
+ Interrupt (Descriptor);
+ delay (0.05);
+ Terminate_Process (Descriptor.Process);
+ Status := Waitpid (Descriptor.Process, Blocking => 1);
+ Descriptor.Exit_Status := Status;
+ end if;
+ else
+ -- If Exit_Status is not STILL_ACTIVE just retrieve the saved
+ -- exit status
+ Status := Descriptor.Exit_Status;
+ end if;
if not On_Windows then
Close_TTY (Descriptor.Process);
@@ -258,6 +288,7 @@ package body GNAT.Expect.TTY is
pragma Import (C, Internal, "__gnat_setup_communication");
begin
+ Pid.Exit_Status := Still_Active;
if Internal (Pid.Process'Address) /= 0 then
raise Invalid_Process with "cannot setup communication.";
end if;
diff --git a/gcc/ada/libgnat/g-exptty.ads b/gcc/ada/libgnat/g-exptty.ads
index 3a90d8d..57aa8d7 100644
--- a/gcc/ada/libgnat/g-exptty.ads
+++ b/gcc/ada/libgnat/g-exptty.ads
@@ -92,6 +92,11 @@ package GNAT.Expect.TTY is
Columns : Natural);
-- Sets up the size of the terminal as reported to the spawned process
+ function Is_Process_Running
+ (Descriptor : in out TTY_Process_Descriptor)
+ return Boolean;
+ -- Return True is the process is still alive
+
private
-- All declarations in the private part must be fully commented ???
@@ -129,9 +134,14 @@ private
Cmd : String;
Args : System.Address);
+ Still_Active : constant Integer := -1;
+
type TTY_Process_Descriptor is new Process_Descriptor with record
- Process : System.Address; -- Underlying structure used in C
- Use_Pipes : Boolean := True;
+ Process : System.Address;
+ -- Underlying structure used in C
+ Exit_Status : Integer := Still_Active;
+ -- Hold the exit status of the process.
+ Use_Pipes : Boolean := True;
end record;
end GNAT.Expect.TTY;
diff --git a/gcc/ada/libgnat/g-lists.adb b/gcc/ada/libgnat/g-lists.adb
index f7447a5..817274a 100644
--- a/gcc/ada/libgnat/g-lists.adb
+++ b/gcc/ada/libgnat/g-lists.adb
@@ -337,6 +337,57 @@ package body GNAT.Lists is
end if;
end Ensure_Unlocked;
+ -----------
+ -- Equal --
+ -----------
+
+ function Equal
+ (Left : Doubly_Linked_List;
+ Right : Doubly_Linked_List) return Boolean
+ is
+ Left_Head : Node_Ptr;
+ Left_Nod : Node_Ptr;
+ Right_Head : Node_Ptr;
+ Right_Nod : Node_Ptr;
+
+ begin
+ -- Two non-existent lists are considered equal
+
+ if Left = Nil and then Right = Nil then
+ return True;
+
+ -- A non-existent list is never equal to an already created list
+
+ elsif Left = Nil or else Right = Nil then
+ return False;
+
+ -- The two lists must contain the same number of elements to be equal
+
+ elsif Size (Left) /= Size (Right) then
+ return False;
+ end if;
+
+ -- Compare the two lists element by element
+
+ Left_Head := Left.Nodes'Access;
+ Left_Nod := Left_Head.Next;
+ Right_Head := Right.Nodes'Access;
+ Right_Nod := Right_Head.Next;
+ while Is_Valid (Left_Nod, Left_Head)
+ and then
+ Is_Valid (Right_Nod, Right_Head)
+ loop
+ if Left_Nod.Elem /= Right_Nod.Elem then
+ return False;
+ end if;
+
+ Left_Nod := Left_Nod.Next;
+ Right_Nod := Right_Nod.Next;
+ end loop;
+
+ return True;
+ end Equal;
+
---------------
-- Find_Node --
---------------
diff --git a/gcc/ada/libgnat/g-lists.ads b/gcc/ada/libgnat/g-lists.ads
index b64ef08..fdcaed6 100644
--- a/gcc/ada/libgnat/g-lists.ads
+++ b/gcc/ada/libgnat/g-lists.ads
@@ -117,6 +117,12 @@ package GNAT.Lists is
-- end of a list's lifetime. This action will raise Iterated if the
-- list has outstanding iterators.
+ function Equal
+ (Left : Doubly_Linked_List;
+ Right : Doubly_Linked_List) return Boolean;
+ -- Determine whether lists Left and Right have the same characteristics
+ -- and contain the same elements.
+
function First (L : Doubly_Linked_List) return Element_Type;
-- Obtain an element from the start of list L. This action will raise
-- List_Empty if the list is empty.
diff --git a/gcc/ada/libgnat/g-regexp.ads b/gcc/ada/libgnat/g-regexp.ads
index 50c992d..162738b 100644
--- a/gcc/ada/libgnat/g-regexp.ads
+++ b/gcc/ada/libgnat/g-regexp.ads
@@ -50,7 +50,7 @@
-- matching with the restriction that it matches entire strings. It
-- is particularly useful for file name matching, and in particular
-- it provides "globbing patterns" that are useful in implementing
--- unix or DOS style wild card matching for file names.
+-- unix or DOS style wildcard matching for file names.
-- GNAT.Regpat (files g-regpat.ads/s-regpat.ads/g-regpat.adb)
-- This is a more complete implementation of Unix-style regular
diff --git a/gcc/ada/libgnat/g-regpat.ads b/gcc/ada/libgnat/g-regpat.ads
index bac4d74..62fc2e8 100644
--- a/gcc/ada/libgnat/g-regpat.ads
+++ b/gcc/ada/libgnat/g-regpat.ads
@@ -53,7 +53,7 @@
-- matching with the restriction that it matches entire strings. It
-- is particularly useful for file name matching, and in particular
-- it provides "globbing patterns" that are useful in implementing
--- unix or DOS style wild card matching for file names.
+-- unix or DOS style wildcard matching for file names.
-- GNAT.Regpat (files g-regpat.ads/s-regpat.ads/s-regpat.adb)
-- This is a more complete implementation of Unix-style regular
diff --git a/gcc/ada/libgnat/g-sercom.adb b/gcc/ada/libgnat/g-sercom.adb
index c3bed83..ccf5239 100644
--- a/gcc/ada/libgnat/g-sercom.adb
+++ b/gcc/ada/libgnat/g-sercom.adb
@@ -103,6 +103,15 @@ package body GNAT.Serial_Communications is
Unimplemented;
end Read;
+ ------------
+ -- To_Ada --
+ ------------
+
+ procedure To_Ada (Port : out Serial_Port; Fd : Serial_Port_Descriptor) is
+ begin
+ Unimplemented;
+ end To_Ada;
+
-----------
-- Write --
-----------
diff --git a/gcc/ada/libgnat/g-sercom.ads b/gcc/ada/libgnat/g-sercom.ads
index 8550e8d..52447db 100644
--- a/gcc/ada/libgnat/g-sercom.ads
+++ b/gcc/ada/libgnat/g-sercom.ads
@@ -33,6 +33,7 @@
with Ada.Streams;
with Interfaces.C;
+with System.OS_Constants;
package GNAT.Serial_Communications is
@@ -100,8 +101,13 @@ package GNAT.Serial_Communications is
-- cases, an explicit port name can be passed directly to Open.
type Data_Rate is
- (B75, B110, B150, B300, B600, B1200, B2400, B4800, B9600,
- B19200, B38400, B57600, B115200);
+ (B75, B110, B150, B300, B600, B1200,
+ B2400, B4800, B9600,
+ B19200, B38400, B57600, B115200,
+ B230400, B460800, B500000, B576000, B921600,
+ B1000000, B1152000, B1500000,
+ B2000000, B2500000, B3000000,
+ B3500000, B4000000);
-- Speed of the communication
type Data_Bits is (CS8, CS7);
@@ -117,6 +123,11 @@ package GNAT.Serial_Communications is
-- No flow control, hardware flow control, software flow control
type Serial_Port is new Ada.Streams.Root_Stream_Type with private;
+ -- Serial port stream type
+
+ type Serial_Port_Descriptor is
+ new System.OS_Constants.Serial_Port_Descriptor;
+ -- OS specific serial port descriptor
procedure Open
(Port : out Serial_Port;
@@ -163,28 +174,52 @@ package GNAT.Serial_Communications is
procedure Close (Port : in out Serial_Port);
-- Close port
-private
+ procedure To_Ada (Port : out Serial_Port; Fd : Serial_Port_Descriptor)
+ with Inline;
+ -- Convert a serial port descriptor to Serial_Port. This is useful when a
+ -- serial port descriptor is obtained from an external library call.
- type Port_Data;
- type Port_Data_Access is access Port_Data;
+ function To_C
+ (Port : Serial_Port) return Serial_Port_Descriptor with Inline;
+ -- Return a serial port descriptor to be used by external subprograms.
+ -- This is useful for C functions that are not yet interfaced in this
+ -- package.
+
+private
type Serial_Port is new Ada.Streams.Root_Stream_Type with record
- H : Port_Data_Access;
+ H : Serial_Port_Descriptor := -1;
end record;
Data_Rate_Value : constant array (Data_Rate) of Interfaces.C.unsigned :=
- (B75 => 75,
- B110 => 110,
- B150 => 150,
- B300 => 300,
- B600 => 600,
- B1200 => 1_200,
- B2400 => 2_400,
- B4800 => 4_800,
- B9600 => 9_600,
- B19200 => 19_200,
- B38400 => 38_400,
- B57600 => 57_600,
- B115200 => 115_200);
+ (B75 => 75,
+ B110 => 110,
+ B150 => 150,
+ B300 => 300,
+ B600 => 600,
+ B1200 => 1_200,
+ B2400 => 2_400,
+ B4800 => 4_800,
+ B9600 => 9_600,
+ B19200 => 19_200,
+ B38400 => 38_400,
+ B57600 => 57_600,
+ B115200 => 115_200,
+ B230400 => 230_400,
+ B460800 => 460_800,
+ B500000 => 500_000,
+ B576000 => 576_000,
+ B921600 => 921_600,
+ B1000000 => 1_000_000,
+ B1152000 => 1_152_000,
+ B1500000 => 1_500_000,
+ B2000000 => 2_000_000,
+ B2500000 => 2_500_000,
+ B3000000 => 3_000_000,
+ B3500000 => 3_500_000,
+ B4000000 => 4_000_000);
+
+ function To_C (Port : Serial_Port) return Serial_Port_Descriptor is
+ (Port.H);
end GNAT.Serial_Communications;
diff --git a/gcc/ada/libgnat/g-sercom__linux.adb b/gcc/ada/libgnat/g-sercom__linux.adb
index 93bc793..87143e2 100644
--- a/gcc/ada/libgnat/g-sercom__linux.adb
+++ b/gcc/ada/libgnat/g-sercom__linux.adb
@@ -33,12 +33,10 @@
with Ada.Streams; use Ada.Streams;
with Ada; use Ada;
-with Ada.Unchecked_Deallocation;
with System; use System;
with System.Communication; use System.Communication;
with System.CRTL; use System.CRTL;
-with System.OS_Constants;
with GNAT.OS_Lib; use GNAT.OS_Lib;
@@ -48,8 +46,6 @@ package body GNAT.Serial_Communications is
use type Interfaces.C.unsigned;
- type Port_Data is new int;
-
subtype unsigned is Interfaces.C.unsigned;
subtype char is Interfaces.C.char;
subtype unsigned_char is Interfaces.C.unsigned_char;
@@ -58,19 +54,32 @@ package body GNAT.Serial_Communications is
pragma Import (C, fcntl, "fcntl");
C_Data_Rate : constant array (Data_Rate) of unsigned :=
- (B75 => OSC.B75,
- B110 => OSC.B110,
- B150 => OSC.B150,
- B300 => OSC.B300,
- B600 => OSC.B600,
- B1200 => OSC.B1200,
- B2400 => OSC.B2400,
- B4800 => OSC.B4800,
- B9600 => OSC.B9600,
- B19200 => OSC.B19200,
- B38400 => OSC.B38400,
- B57600 => OSC.B57600,
- B115200 => OSC.B115200);
+ (B75 => OSC.B75,
+ B110 => OSC.B110,
+ B150 => OSC.B150,
+ B300 => OSC.B300,
+ B600 => OSC.B600,
+ B1200 => OSC.B1200,
+ B2400 => OSC.B2400,
+ B4800 => OSC.B4800,
+ B9600 => OSC.B9600,
+ B19200 => OSC.B19200,
+ B38400 => OSC.B38400,
+ B57600 => OSC.B57600,
+ B115200 => OSC.B115200,
+ B230400 => OSC.B230400,
+ B460800 => OSC.B460800,
+ B500000 => OSC.B500000,
+ B576000 => OSC.B576000,
+ B921600 => OSC.B921600,
+ B1000000 => OSC.B1000000,
+ B1152000 => OSC.B1152000,
+ B1500000 => OSC.B1500000,
+ B2000000 => OSC.B2000000,
+ B2500000 => OSC.B2500000,
+ B3000000 => OSC.B3000000,
+ B3500000 => OSC.B3500000,
+ B4000000 => OSC.B4000000);
C_Bits : constant array (Data_Bits) of unsigned :=
(CS7 => OSC.CS7, CS8 => OSC.CS8);
@@ -111,20 +120,16 @@ package body GNAT.Serial_Communications is
Res : int;
begin
- if Port.H = null then
- Port.H := new Port_Data;
- end if;
-
- Port.H.all := Port_Data (open
+ Port.H := Serial_Port_Descriptor (open
(C_Name (C_Name'First)'Address, int (O_RDWR + O_NOCTTY + O_NDELAY)));
- if Port.H.all = -1 then
+ if Port.H = -1 then
Raise_Error ("open: open failed");
end if;
-- By default we are in blocking mode
- Res := fcntl (int (Port.H.all), F_SETFL, 0);
+ Res := fcntl (int (Port.H), F_SETFL, 0);
if Res = -1 then
Raise_Error ("open: fcntl failed");
@@ -156,11 +161,11 @@ package body GNAT.Serial_Communications is
Res : ssize_t;
begin
- if Port.H = null then
+ if Port.H = -1 then
Raise_Error ("read: port not opened", 0);
end if;
- Res := read (Integer (Port.H.all), Buffer'Address, Len);
+ Res := read (Integer (Port.H), Buffer'Address, Len);
if Res = -1 then
Raise_Error ("read failed");
@@ -215,13 +220,13 @@ package body GNAT.Serial_Communications is
-- Warnings off, since we don't always test the result
begin
- if Port.H = null then
+ if Port.H = -1 then
Raise_Error ("set: port not opened", 0);
end if;
-- Get current port settings
- Res := tcgetattr (int (Port.H.all), Current'Address);
+ Res := tcgetattr (int (Port.H), Current'Address);
-- Change settings now
@@ -256,18 +261,27 @@ package body GNAT.Serial_Communications is
-- Set port settings
- Res := tcflush (int (Port.H.all), TCIFLUSH);
- Res := tcsetattr (int (Port.H.all), TCSANOW, Current'Address);
+ Res := tcflush (int (Port.H), TCIFLUSH);
+ Res := tcsetattr (int (Port.H), TCSANOW, Current'Address);
-- Block
- Res := fcntl (int (Port.H.all), F_SETFL, (if Block then 0 else FNDELAY));
+ Res := fcntl (int (Port.H), F_SETFL, (if Block then 0 else FNDELAY));
if Res = -1 then
Raise_Error ("set: fcntl failed");
end if;
end Set;
+ ------------
+ -- To_Ada --
+ ------------
+
+ procedure To_Ada (Port : out Serial_Port; Fd : Serial_Port_Descriptor) is
+ begin
+ Port.H := Fd;
+ end To_Ada;
+
-----------
-- Write --
-----------
@@ -280,11 +294,11 @@ package body GNAT.Serial_Communications is
Res : ssize_t;
begin
- if Port.H = null then
+ if Port.H = -1 then
Raise_Error ("write: port not opened", 0);
end if;
- Res := write (int (Port.H.all), Buffer'Address, Len);
+ Res := write (int (Port.H), Buffer'Address, Len);
if Res = -1 then
Raise_Error ("write failed");
@@ -298,16 +312,12 @@ package body GNAT.Serial_Communications is
-----------
procedure Close (Port : in out Serial_Port) is
- procedure Unchecked_Free is
- new Unchecked_Deallocation (Port_Data, Port_Data_Access);
-
Res : int;
pragma Unreferenced (Res);
begin
- if Port.H /= null then
- Res := close (int (Port.H.all));
- Unchecked_Free (Port.H);
+ if Port.H /= -1 then
+ Res := close (int (Port.H));
end if;
end Close;
diff --git a/gcc/ada/libgnat/g-sercom__mingw.adb b/gcc/ada/libgnat/g-sercom__mingw.adb
index 88a23ea..c13e7b3 100644
--- a/gcc/ada/libgnat/g-sercom__mingw.adb
+++ b/gcc/ada/libgnat/g-sercom__mingw.adb
@@ -31,13 +31,11 @@
-- This is the Windows implementation of this package
-with Ada.Streams; use Ada.Streams;
-with Ada.Unchecked_Deallocation; use Ada;
+with Ada.Streams; use Ada.Streams, Ada;
with System; use System;
with System.Communication; use System.Communication;
with System.CRTL; use System.CRTL;
-with System.OS_Constants;
with System.Win32; use System.Win32;
with System.Win32.Ext; use System.Win32.Ext;
@@ -49,8 +47,6 @@ package body GNAT.Serial_Communications is
-- Common types
- type Port_Data is new HANDLE;
-
C_Bits : constant array (Data_Bits) of Interfaces.C.unsigned := (8, 7);
C_Parity : constant array (Parity_Check) of Interfaces.C.unsigned :=
(None => NOPARITY, Odd => ODDPARITY, Even => EVENPARITY);
@@ -69,15 +65,11 @@ package body GNAT.Serial_Communications is
-----------
procedure Close (Port : in out Serial_Port) is
- procedure Unchecked_Free is
- new Unchecked_Deallocation (Port_Data, Port_Data_Access);
-
Success : BOOL;
begin
- if Port.H /= null then
- Success := CloseHandle (HANDLE (Port.H.all));
- Unchecked_Free (Port.H);
+ if Port.H /= -1 then
+ Success := CloseHandle (HANDLE (Port.H));
if Success = Win32.FALSE then
Raise_Error ("error closing the port");
@@ -114,13 +106,11 @@ package body GNAT.Serial_Communications is
pragma Unreferenced (Success);
begin
- if Port.H = null then
- Port.H := new Port_Data;
- else
- Success := CloseHandle (HANDLE (Port.H.all));
+ if Port.H /= -1 then
+ Success := CloseHandle (HANDLE (Port.H));
end if;
- Port.H.all := CreateFileA
+ Port.H := CreateFileA
(lpFileName => C_Name (C_Name'First)'Address,
dwDesiredAccess => GENERIC_READ or GENERIC_WRITE,
dwShareMode => 0,
@@ -129,7 +119,9 @@ package body GNAT.Serial_Communications is
dwFlagsAndAttributes => 0,
hTemplateFile => 0);
- if Port.H.all = Port_Data (INVALID_HANDLE_VALUE) then
+ pragma Assert (INVALID_HANDLE_VALUE = -1);
+
+ if Port.H = Serial_Port_Descriptor (INVALID_HANDLE_VALUE) then
Raise_Error ("cannot open com port");
end if;
end Open;
@@ -159,13 +151,13 @@ package body GNAT.Serial_Communications is
Read_Last : aliased DWORD;
begin
- if Port.H = null then
+ if Port.H = -1 then
Raise_Error ("read: port not opened", 0);
end if;
Success :=
ReadFile
- (hFile => HANDLE (Port.H.all),
+ (hFile => HANDLE (Port.H),
lpBuffer => Buffer (Buffer'First)'Address,
nNumberOfBytesToRead => DWORD (Buffer'Length),
lpNumberOfBytesRead => Read_Last'Access,
@@ -200,15 +192,14 @@ package body GNAT.Serial_Communications is
Com_Settings : aliased DCB;
begin
- if Port.H = null then
+ if Port.H = -1 then
Raise_Error ("set: port not opened", 0);
end if;
- Success := GetCommState (HANDLE (Port.H.all), Com_Settings'Access);
+ Success := GetCommState (HANDLE (Port.H), Com_Settings'Access);
if Success = Win32.FALSE then
- Success := CloseHandle (HANDLE (Port.H.all));
- Port.H.all := 0;
+ Success := CloseHandle (HANDLE (Port.H));
Raise_Error ("set: cannot get comm state");
end if;
@@ -240,11 +231,10 @@ package body GNAT.Serial_Communications is
Com_Settings.Parity := BYTE (C_Parity (Parity));
Com_Settings.StopBits := BYTE (C_Stop_Bits (Stop_Bits));
- Success := SetCommState (HANDLE (Port.H.all), Com_Settings'Access);
+ Success := SetCommState (HANDLE (Port.H), Com_Settings'Access);
if Success = Win32.FALSE then
- Success := CloseHandle (HANDLE (Port.H.all));
- Port.H.all := 0;
+ Success := CloseHandle (HANDLE (Port.H));
Raise_Error ("cannot set comm state");
end if;
@@ -274,7 +264,7 @@ package body GNAT.Serial_Communications is
Success :=
SetCommTimeouts
- (hFile => HANDLE (Port.H.all),
+ (hFile => HANDLE (Port.H),
lpCommTimeouts => Com_Time_Out'Access);
if Success = Win32.FALSE then
@@ -282,6 +272,15 @@ package body GNAT.Serial_Communications is
end if;
end Set;
+ ------------
+ -- To_Ada --
+ ------------
+
+ procedure To_Ada (Port : out Serial_Port; Fd : Serial_Port_Descriptor) is
+ begin
+ Port.H := Fd;
+ end To_Ada;
+
-----------
-- Write --
-----------
@@ -294,13 +293,13 @@ package body GNAT.Serial_Communications is
Temp_Last : aliased DWORD;
begin
- if Port.H = null then
+ if Port.H = -1 then
Raise_Error ("write: port not opened", 0);
end if;
Success :=
WriteFile
- (hFile => HANDLE (Port.H.all),
+ (hFile => HANDLE (Port.H),
lpBuffer => Buffer'Address,
nNumberOfBytesToWrite => DWORD (Buffer'Length),
lpNumberOfBytesWritten => Temp_Last'Access,
diff --git a/gcc/ada/libgnat/g-socket.adb b/gcc/ada/libgnat/g-socket.adb
index 476a213..ceb2cb0 100644
--- a/gcc/ada/libgnat/g-socket.adb
+++ b/gcc/ada/libgnat/g-socket.adb
@@ -73,11 +73,15 @@ package body GNAT.Sockets is
IP_Protocol_For_IP_Level => SOSC.IPPROTO_IP,
IP_Protocol_For_IPv6_Level => SOSC.IPPROTO_IPV6,
IP_Protocol_For_UDP_Level => SOSC.IPPROTO_UDP,
- IP_Protocol_For_TCP_Level => SOSC.IPPROTO_TCP);
+ IP_Protocol_For_TCP_Level => SOSC.IPPROTO_TCP,
+ IP_Protocol_For_ICMP_Level => SOSC.IPPROTO_ICMP,
+ IP_Protocol_For_IGMP_Level => SOSC.IPPROTO_IGMP,
+ IP_Protocol_For_RAW_Level => SOSC.IPPROTO_RAW);
Modes : constant array (Mode_Type) of C.int :=
(Socket_Stream => SOSC.SOCK_STREAM,
- Socket_Datagram => SOSC.SOCK_DGRAM);
+ Socket_Datagram => SOSC.SOCK_DGRAM,
+ Socket_Raw => SOSC.SOCK_RAW);
Shutmodes : constant array (Shutmode_Type) of C.int :=
(Shut_Read => SOSC.SHUT_RD,
@@ -1369,7 +1373,7 @@ package body GNAT.Sockets is
function Get_Socket_Option
(Socket : Socket_Type;
- Level : Level_Type := Socket_Level;
+ Level : Level_Type;
Name : Option_Name;
Optname : Interfaces.C.int := -1) return Option_Type
is
@@ -2539,7 +2543,7 @@ package body GNAT.Sockets is
procedure Set_Socket_Option
(Socket : Socket_Type;
- Level : Level_Type := Socket_Level;
+ Level : Level_Type;
Option : Option_Type)
is
use type C.unsigned;
@@ -2643,21 +2647,29 @@ package body GNAT.Sockets is
=>
if Is_Windows then
- -- On Windows, the timeout is a DWORD in milliseconds, and
- -- the actual timeout is 500 ms + the given value (unless it
- -- is 0).
+ -- On Windows, the timeout is a DWORD in milliseconds
- U4 := C.unsigned (Option.Timeout / 0.001);
+ Len := U4'Size / 8;
+ Add := U4'Address;
- if U4 > 500 then
- U4 := U4 - 500;
+ U4 := C.unsigned (Option.Timeout / 0.001);
- elsif U4 > 0 then
+ if Option.Timeout > 0.0 and then U4 = 0 then
+ -- Avoid round to zero. Zero timeout mean unlimited.
U4 := 1;
end if;
- Len := U4'Size / 8;
- Add := U4'Address;
+ -- Old windows versions actual timeout is 500 ms + the given
+ -- value (unless it is 0).
+
+ if Minus_500ms_Windows_Timeout /= 0 then
+ if U4 > 500 then
+ U4 := U4 - 500;
+
+ elsif U4 > 0 then
+ U4 := 1;
+ end if;
+ end if;
else
VT := To_Timeval (Option.Timeout);
diff --git a/gcc/ada/libgnat/g-socket.ads b/gcc/ada/libgnat/g-socket.ads
index 3024433..acd72f1 100644
--- a/gcc/ada/libgnat/g-socket.ads
+++ b/gcc/ada/libgnat/g-socket.ads
@@ -475,16 +475,17 @@ package GNAT.Sockets is
-- The order of the enumeration elements should not be changed unilaterally
-- because the IPv6_TCP_Preferred routine rely on it.
- type Mode_Type is (Socket_Stream, Socket_Datagram);
+ type Mode_Type is (Socket_Stream, Socket_Datagram, Socket_Raw);
-- Stream sockets provide connection-oriented byte streams. Datagram
- -- sockets support unreliable connectionless message based communication.
+ -- sockets support unreliable connectionless message-based communication.
+ -- Raw sockets provide raw network-protocol access.
-- The order of the enumeration elements should not be changed unilaterally
- -- because the IPv6_TCP_Preferred routine rely on it.
+ -- because the IPv6_TCP_Preferred routine relies on it.
type Shutmode_Type is (Shut_Read, Shut_Write, Shut_Read_Write);
-- When a process closes a socket, the policy is to retain any data queued
-- until either a delivery or a timeout expiration (in this case, the data
- -- are discarded). A finer control is available through shutdown. With
+ -- are discarded). Finer control is available through shutdown. With
-- Shut_Read, no more data can be received from the socket. With_Write, no
-- more data can be transmitted. Neither transmission nor reception can be
-- performed with Shut_Read_Write.
@@ -772,37 +773,119 @@ package GNAT.Sockets is
IP_Protocol_For_IP_Level,
IP_Protocol_For_IPv6_Level,
IP_Protocol_For_UDP_Level,
- IP_Protocol_For_TCP_Level);
+ IP_Protocol_For_TCP_Level,
+ IP_Protocol_For_ICMP_Level,
+ IP_Protocol_For_IGMP_Level,
+ IP_Protocol_For_RAW_Level);
-- There are several options available to manipulate sockets. Each option
- -- has a name and several values available. Most of the time, the value is
- -- a boolean to enable or disable this option.
+ -- has a name and several values available. Most of the time, the value
+ -- is a boolean to enable or disable this option. Each socket option is
+ -- provided with an appropriate C name taken from the sockets API comments.
+ -- The C name can be used to find a detailed description in the OS-specific
+ -- documentation. The options are grouped by main Level_Type value, which
+ -- can be used together with this option in calls to the Set_Socket_Option
+ -- and Get_Socket_Option routines. Note that some options can be used with
+ -- more than one level.
type Option_Name is
(Generic_Option,
- Keep_Alive, -- Enable sending of keep-alive messages
- Reuse_Address, -- Allow bind to reuse local address
- Broadcast, -- Enable datagram sockets to recv/send broadcasts
- Send_Buffer, -- Set/get the maximum socket send buffer in bytes
- Receive_Buffer, -- Set/get the maximum socket recv buffer in bytes
- Linger, -- Shutdown wait for msg to be sent or timeout occur
- Error, -- Get and clear the pending socket error
- No_Delay, -- Do not delay send to coalesce data (TCP_NODELAY)
- Add_Membership_V4, -- Join a multicast group
- Add_Membership_V6, -- Idem for IPv6 socket
- Drop_Membership_V4, -- Leave a multicast group
- Drop_Membership_V6, -- Idem for IPv6 socket
- Multicast_If_V4, -- Set default out interface for multicast packets
- Multicast_If_V6, -- Idem for IPv6 socket
- Multicast_Loop_V4, -- Sent multicast packets are looped to local socket
- Multicast_Loop_V6, -- Idem for IPv6 socket
- Multicast_TTL, -- Set the time-to-live of sent multicast packets
- Multicast_Hops, -- Set the multicast hop limit for the IPv6 socket
- Receive_Packet_Info, -- Receive low level packet info as ancillary data
- Send_Timeout, -- Set timeout value for output
- Receive_Timeout, -- Set timeout value for input
- IPv6_Only, -- Restricted to IPv6 communications only
- Busy_Polling); -- Set busy polling mode
+ -- Can be used to set/get any socket option via an OS-specific option
+ -- code with an integer value.
+
+ ------------------
+ -- Socket_Level --
+ ------------------
+
+ Keep_Alive, -- SO_KEEPALIVE
+ -- Enable sending of keep-alive messages on connection-oriented sockets
+
+ Reuse_Address, -- SO_REUSEADDR
+ -- Enable binding to an address and port already in use
+
+ Broadcast, -- SO_BROADCAST
+ -- Enable sending broadcast datagrams on the socket
+
+ Send_Buffer, -- SO_SNDBUF
+ -- Set/get the maximum socket send buffer in bytes
+
+ Receive_Buffer, -- SO_RCVBUF
+ -- Set/get the maximum socket receive buffer in bytes
+
+ Linger, -- SO_LINGER
+ -- When enabled, a Close_Socket or Shutdown_Socket will wait until all
+ -- queued messages for the socket have been successfully sent or the
+ -- linger timeout has been reached.
+
+ Error, -- SO_ERROR
+ -- Get and clear the pending socket error integer code
+
+ Send_Timeout, -- SO_SNDTIMEO
+ -- Specify sending timeout until reporting an error
+
+ Receive_Timeout, -- SO_RCVTIMEO
+ -- Specify receiving timeout until reporting an error
+
+ Busy_Polling, -- SO_BUSY_POLL
+ -- Sets the approximate time in microseconds to busy poll on a blocking
+ -- receive when there is no data.
+
+ -------------------------------
+ -- IP_Protocol_For_TCP_Level --
+ -------------------------------
+
+ No_Delay, -- TCP_NODELAY
+ -- Disable the Nagle algorithm. This means that output buffer content
+ -- is always sent as soon as possible, even if there is only a small
+ -- amount of data.
+
+ ------------------------------
+ -- IP_Protocol_For_IP_Level --
+ ------------------------------
+
+ Add_Membership_V4, -- IP_ADD_MEMBERSHIP
+ -- Join a multicast group
+
+ Drop_Membership_V4, -- IP_DROP_MEMBERSHIP
+ -- Leave a multicast group
+
+ Multicast_If_V4, -- IP_MULTICAST_IF
+ -- Set/Get outgoing interface for sending multicast packets
+
+ Multicast_Loop_V4, -- IP_MULTICAST_LOOP
+ -- This boolean option determines whether sent multicast packets should
+ -- be looped back to the local sockets.
+
+ Multicast_TTL, -- IP_MULTICAST_TTL
+ -- Set/Get the time-to-live of sent multicast packets
+
+ Receive_Packet_Info, -- IP_PKTINFO
+ -- Receive low-level packet info as ancillary data
+
+ --------------------------------
+ -- IP_Protocol_For_IPv6_Level --
+ --------------------------------
+
+ Add_Membership_V6, -- IPV6_ADD_MEMBERSHIP
+ -- Join IPv6 multicast group
+
+ Drop_Membership_V6, -- IPV6_DROP_MEMBERSHIP
+ -- Leave IPv6 multicast group
+
+ Multicast_If_V6, -- IPV6_MULTICAST_IF
+ -- Set/Get outgoing interface index for sending multicast packets
+
+ Multicast_Loop_V6, -- IPV6_MULTICAST_LOOP
+ -- This boolean option determines whether sent multicast IPv6 packets
+ -- should be looped back to the local sockets.
+
+ IPv6_Only, -- IPV6_V6ONLY
+ -- Restricted to IPv6 communications only
+
+ Multicast_Hops -- IPV6_MULTICAST_HOPS
+ -- Set the multicast hop limit for the IPv6 socket
+ );
+
subtype Specific_Option_Name is
Option_Name range Keep_Alive .. Option_Name'Last;
@@ -1084,7 +1167,7 @@ package GNAT.Sockets is
function Get_Socket_Option
(Socket : Socket_Type;
- Level : Level_Type := Socket_Level;
+ Level : Level_Type;
Name : Option_Name;
Optname : Interfaces.C.int := -1) return Option_Type;
-- Get the options associated with a socket. Raises Socket_Error on error.
@@ -1199,7 +1282,7 @@ package GNAT.Sockets is
procedure Set_Socket_Option
(Socket : Socket_Type;
- Level : Level_Type := Socket_Level;
+ Level : Level_Type;
Option : Option_Type);
-- Manipulate socket options. Raises Socket_Error on error
diff --git a/gcc/ada/libgnat/g-sothco.ads b/gcc/ada/libgnat/g-sothco.ads
index dc47f92..c62161d 100644
--- a/gcc/ada/libgnat/g-sothco.ads
+++ b/gcc/ada/libgnat/g-sothco.ads
@@ -438,6 +438,11 @@ package GNAT.Sockets.Thin_Common is
renames Short_To_Network;
-- Symmetric operation
+ function Minus_500ms_Windows_Timeout return C.int;
+ -- Microsoft Windows desktop older then 8.0 and Microsoft Windows Server
+ -- older than 2019 need timeout correction for 500 milliseconds. This
+ -- routine returns 1 for such versions.
+
private
pragma Import (C, Get_Socket_From_Set, "__gnat_get_socket_from_set");
pragma Import (C, Is_Socket_In_Set, "__gnat_is_socket_in_set");
@@ -470,4 +475,6 @@ private
pragma Import (C, Hostent_H_Length, "__gnat_hostent_h_length");
pragma Import (C, Hostent_H_Addr, "__gnat_hostent_h_addr");
+ pragma Import (C, Minus_500ms_Windows_Timeout, "__gnat_minus_500ms");
+
end GNAT.Sockets.Thin_Common;
diff --git a/gcc/ada/libgnat/g-spipat.ads b/gcc/ada/libgnat/g-spipat.ads
index 4d6a7f8..4dfc25a 100644
--- a/gcc/ada/libgnat/g-spipat.ads
+++ b/gcc/ada/libgnat/g-spipat.ads
@@ -48,7 +48,7 @@
-- matching with the restriction that it matches entire strings. It
-- is particularly useful for file name matching, and in particular
-- it provides "globbing patterns" that are useful in implementing
--- unix or DOS style wild card matching for file names.
+-- unix or DOS style wildcard matching for file names.
-- GNAT.Regpat (files g-regpat.ads/g-regpat.adb)
-- This is a more complete implementation of Unix-style regular
diff --git a/gcc/ada/libgnat/g-traceb.adb b/gcc/ada/libgnat/g-traceb.adb
index cc52e57..9cf04de 100644
--- a/gcc/ada/libgnat/g-traceb.adb
+++ b/gcc/ada/libgnat/g-traceb.adb
@@ -47,4 +47,16 @@ package body GNAT.Traceback is
System.Traceback.Call_Chain (Traceback, Traceback'Length, Len);
end Call_Chain;
+ function Call_Chain
+ (Max_Len : Positive;
+ Skip_Frames : Natural := 1) return Tracebacks_Array
+ is
+ Traceback : Tracebacks_Array (1 .. Max_Len);
+ Len : Natural;
+ begin
+ System.Traceback.Call_Chain
+ (Traceback, Max_Len, Len, Skip_Frames => Skip_Frames + 1);
+ return Traceback (1 .. Len);
+ end Call_Chain;
+
end GNAT.Traceback;
diff --git a/gcc/ada/libgnat/g-traceb.ads b/gcc/ada/libgnat/g-traceb.ads
index aeb3b0a..6a565c9 100644
--- a/gcc/ada/libgnat/g-traceb.ads
+++ b/gcc/ada/libgnat/g-traceb.ads
@@ -98,4 +98,14 @@ package GNAT.Traceback is
-- shorter, in which case positions in Traceback past the Len position
-- are undefined on return.
+ function Call_Chain
+ (Max_Len : Positive;
+ Skip_Frames : Natural := 1) return Tracebacks_Array;
+ -- Returns up to Max_Len tracebacks corresponding to the current call
+ -- chain. Result array order is the same as in above procedure Call_Chain
+ -- except that Skip_Frames says how many of the most recent calls should be
+ -- excluded from the result, starting with this procedure itself: 1 means
+ -- exclude the frame for this procedure, 2 means 1 + exclude the frame for
+ -- this procedure's caller, ...
+
end GNAT.Traceback;
diff --git a/gcc/ada/libgnat/s-imenne.adb b/gcc/ada/libgnat/s-imenne.adb
index 2ea9fc7..30df1a4 100644
--- a/gcc/ada/libgnat/s-imenne.adb
+++ b/gcc/ada/libgnat/s-imenne.adb
@@ -49,7 +49,8 @@ package body System.Img_Enum_New is
pragma Assert (S'First = 1);
type Natural_8 is range 0 .. 2 ** 7 - 1;
- type Index_Table is array (Natural) of Natural_8;
+ subtype Index is Natural range Natural'First .. Names'Length;
+ type Index_Table is array (Index) of Natural_8;
type Index_Table_Ptr is access Index_Table;
function To_Index_Table_Ptr is
@@ -79,7 +80,8 @@ package body System.Img_Enum_New is
pragma Assert (S'First = 1);
type Natural_16 is range 0 .. 2 ** 15 - 1;
- type Index_Table is array (Natural) of Natural_16;
+ subtype Index is Natural range Natural'First .. Names'Length;
+ type Index_Table is array (Index) of Natural_16;
type Index_Table_Ptr is access Index_Table;
function To_Index_Table_Ptr is
@@ -109,7 +111,8 @@ package body System.Img_Enum_New is
pragma Assert (S'First = 1);
type Natural_32 is range 0 .. 2 ** 31 - 1;
- type Index_Table is array (Natural) of Natural_32;
+ subtype Index is Natural range Natural'First .. Names'Length;
+ type Index_Table is array (Index) of Natural_32;
type Index_Table_Ptr is access Index_Table;
function To_Index_Table_Ptr is
diff --git a/gcc/ada/libgnat/s-memory.adb b/gcc/ada/libgnat/s-memory.adb
index f34a92b..ebc168e 100644
--- a/gcc/ada/libgnat/s-memory.adb
+++ b/gcc/ada/libgnat/s-memory.adb
@@ -33,13 +33,10 @@
-- This implementation assumes that the underlying malloc/free/realloc
-- implementation is thread safe, and thus, no additional lock is required.
--- Note that we still need to defer abort because on most systems, an
--- asynchronous signal (as used for implementing asynchronous abort of
--- task) cannot safely be handled while malloc is executing.
-
--- If you are not using Ada constructs containing the "abort" keyword, then
--- you can remove the calls to Abort_Defer.all and Abort_Undefer.all from
--- this unit.
+-- Note that when using sjlj exception handling, we still need to defer abort
+-- because an asynchronous signal (as used for implementing asynchronous abort
+-- of task on sjlj runtimes) cannot safely be handled while malloc is
+-- executing.
pragma Compiler_Unit_Warning;
@@ -80,7 +77,7 @@ package body System.Memory is
raise Storage_Error with "object too large";
end if;
- if Parameters.No_Abort then
+ if ZCX_By_Default or else Parameters.No_Abort then
Result := c_malloc (System.CRTL.size_t (Size));
else
Abort_Defer.all;
@@ -121,7 +118,7 @@ package body System.Memory is
procedure Free (Ptr : System.Address) is
begin
- if Parameters.No_Abort then
+ if ZCX_By_Default or else Parameters.No_Abort then
c_free (Ptr);
else
Abort_Defer.all;
@@ -145,7 +142,7 @@ package body System.Memory is
raise Storage_Error with "object too large";
end if;
- if Parameters.No_Abort then
+ if ZCX_By_Default or else Parameters.No_Abort then
Result := c_realloc (Ptr, System.CRTL.size_t (Size));
else
Abort_Defer.all;
diff --git a/gcc/ada/libgnat/s-os_lib.adb b/gcc/ada/libgnat/s-os_lib.adb
index 7efddf7..c3c1979 100644
--- a/gcc/ada/libgnat/s-os_lib.adb
+++ b/gcc/ada/libgnat/s-os_lib.adb
@@ -1629,10 +1629,12 @@ package body System.OS_Lib is
pragma Import (C, C_Kill, "__gnat_kill");
begin
- if Hard_Kill then
- C_Kill (Pid, SIGKILL, 1);
- else
- C_Kill (Pid, SIGINT, 1);
+ if Pid /= Invalid_Pid then
+ if Hard_Kill then
+ C_Kill (Pid, SIGKILL, 1);
+ else
+ C_Kill (Pid, SIGINT, 1);
+ end if;
end if;
end Kill;
diff --git a/gcc/ada/libgnat/s-os_lib.ads b/gcc/ada/libgnat/s-os_lib.ads
index 8b21aa7..3e8c21d 100644
--- a/gcc/ada/libgnat/s-os_lib.ads
+++ b/gcc/ada/libgnat/s-os_lib.ads
@@ -246,7 +246,7 @@ package System.OS_Lib is
Success : out Boolean;
Mode : Copy_Mode := Copy;
Preserve : Attribute := Time_Stamps);
- -- Copy a file. Name must designate a single file (no wild cards allowed).
+ -- Copy a file. Name must designate a single file (no wildcards allowed).
-- Pathname can be a filename or directory name. In the latter case Name
-- is copied into the directory preserving the same file name. Mode
-- defines the kind of copy, see above with the default being a normal
diff --git a/gcc/ada/libgnat/s-regexp.ads b/gcc/ada/libgnat/s-regexp.ads
index f521f91..4d9fb5b 100644
--- a/gcc/ada/libgnat/s-regexp.ads
+++ b/gcc/ada/libgnat/s-regexp.ads
@@ -77,7 +77,7 @@ package System.Regexp is
-- See also regexp(1) man page on Unix systems for further details
-- A second kind of regular expressions is provided. This one is more
- -- like the wild card patterns used in file names by the Unix shell (or
+ -- like the wildcard patterns used in file names by the Unix shell (or
-- DOS prompt) command lines. The grammar is the following:
-- regexp ::= term
diff --git a/gcc/ada/libgnat/s-stratt.ads b/gcc/ada/libgnat/s-stratt.ads
index 20dc4e6..e050bc1 100644
--- a/gcc/ada/libgnat/s-stratt.ads
+++ b/gcc/ada/libgnat/s-stratt.ads
@@ -154,7 +154,7 @@ package System.Stream_Attributes is
function Block_IO_OK return Boolean;
-- Package System.Stream_Attributes has several bodies - the default one
- -- distributed with GNAT, and s-stratt-xdr.adb, which is based on the XDR
+ -- distributed with GNAT, and s-stratt__xdr.adb, which is based on the XDR
-- standard. Both bodies share the same spec. The role of this function is
-- to indicate whether the current version of System.Stream_Attributes
-- supports block IO. See System.Strings.Stream_Ops (s-ststop) for details.
diff --git a/gcc/ada/libgnat/s-ststop.adb b/gcc/ada/libgnat/s-ststop.adb
index 9f5c6ec..cf594b0 100644
--- a/gcc/ada/libgnat/s-ststop.adb
+++ b/gcc/ada/libgnat/s-ststop.adb
@@ -31,8 +31,8 @@
pragma Compiler_Unit_Warning;
+with Ada.IO_Exceptions; use Ada.IO_Exceptions;
with Ada.Streams; use Ada.Streams;
-with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Unchecked_Conversion;
with System; use System;
diff --git a/gcc/ada/libgnat/s-valboo.ads b/gcc/ada/libgnat/s-valboo.ads
index bed1ae3..f900621 100644
--- a/gcc/ada/libgnat/s-valboo.ads
+++ b/gcc/ada/libgnat/s-valboo.ads
@@ -30,7 +30,7 @@
------------------------------------------------------------------------------
package System.Val_Bool is
- pragma Pure;
+ pragma Preelaborate;
function Value_Boolean (Str : String) return Boolean;
-- Computes Boolean'Value (Str)
diff --git a/gcc/ada/libgnat/s-valcha.ads b/gcc/ada/libgnat/s-valcha.ads
index 0d3edfc..b9d5373 100644
--- a/gcc/ada/libgnat/s-valcha.ads
+++ b/gcc/ada/libgnat/s-valcha.ads
@@ -30,7 +30,7 @@
------------------------------------------------------------------------------
package System.Val_Char is
- pragma Pure;
+ pragma Preelaborate;
function Value_Character (Str : String) return Character;
-- Computes Character'Value (Str)
diff --git a/gcc/ada/libgnat/s-valdec.ads b/gcc/ada/libgnat/s-valdec.ads
index 9d47333..ec10490 100644
--- a/gcc/ada/libgnat/s-valdec.ads
+++ b/gcc/ada/libgnat/s-valdec.ads
@@ -34,7 +34,7 @@
-- Decimal_IO, and the Value attribute for such decimal types.
package System.Val_Dec is
- pragma Pure;
+ pragma Preelaborate;
function Scan_Decimal
(Str : String;
diff --git a/gcc/ada/libgnat/s-valenu.ads b/gcc/ada/libgnat/s-valenu.ads
index 343acf3..e2a3a15 100644
--- a/gcc/ada/libgnat/s-valenu.ads
+++ b/gcc/ada/libgnat/s-valenu.ads
@@ -34,7 +34,7 @@
-- details of the format of constructed image tables.
package System.Val_Enum is
- pragma Pure;
+ pragma Preelaborate;
function Value_Enumeration_8
(Names : String;
diff --git a/gcc/ada/libgnat/s-valint.ads b/gcc/ada/libgnat/s-valint.ads
index b4be1e4..d9f15ed 100644
--- a/gcc/ada/libgnat/s-valint.ads
+++ b/gcc/ada/libgnat/s-valint.ads
@@ -33,7 +33,7 @@
-- in Text_IO.Integer_IO, and the Value attribute.
package System.Val_Int is
- pragma Pure;
+ pragma Preelaborate;
function Scan_Integer
(Str : String;
diff --git a/gcc/ada/libgnat/s-vallld.ads b/gcc/ada/libgnat/s-vallld.ads
index 1ff561e..17db078 100644
--- a/gcc/ada/libgnat/s-vallld.ads
+++ b/gcc/ada/libgnat/s-vallld.ads
@@ -34,7 +34,7 @@
-- Decimal_IO, and the Value attribute for such decimal types.
package System.Val_LLD is
- pragma Pure;
+ pragma Preelaborate;
function Scan_Long_Long_Decimal
(Str : String;
diff --git a/gcc/ada/libgnat/s-vallli.ads b/gcc/ada/libgnat/s-vallli.ads
index 2f510ca..ee75bdc 100644
--- a/gcc/ada/libgnat/s-vallli.ads
+++ b/gcc/ada/libgnat/s-vallli.ads
@@ -33,7 +33,7 @@
-- values for use in Text_IO.Integer_IO, and the Value attribute.
package System.Val_LLI is
- pragma Pure;
+ pragma Preelaborate;
function Scan_Long_Long_Integer
(Str : String;
diff --git a/gcc/ada/libgnat/s-valllu.ads b/gcc/ada/libgnat/s-valllu.ads
index c518492..ddb8414 100644
--- a/gcc/ada/libgnat/s-valllu.ads
+++ b/gcc/ada/libgnat/s-valllu.ads
@@ -35,7 +35,7 @@
with System.Unsigned_Types;
package System.Val_LLU is
- pragma Pure;
+ pragma Preelaborate;
function Scan_Raw_Long_Long_Unsigned
(Str : String;
diff --git a/gcc/ada/libgnat/s-valrea.adb b/gcc/ada/libgnat/s-valrea.adb
index 9039f99..99c7360 100644
--- a/gcc/ada/libgnat/s-valrea.adb
+++ b/gcc/ada/libgnat/s-valrea.adb
@@ -71,16 +71,13 @@ package body System.Val_Real is
After_Point : Natural := 0;
-- Set to 1 after the point
- Num_Saved_Zeroes : Natural := 0;
- -- This counts zeroes after the decimal point. A non-zero value means
- -- that this number of previously scanned digits are zero. If the end
- -- of the number is reached, these zeroes are simply discarded, which
- -- ensures that trailing zeroes after the point never affect the value
- -- (which might otherwise happen as a result of rounding). With this
- -- processing in place, we can ensure that, for example, we get the
- -- same exact result from 1.0E+49 and 1.0000000E+49. This is not
- -- necessarily required in a case like this where the result is not
- -- a machine number, but it is certainly a desirable behavior.
+ Precision_Limit : constant Long_Long_Float :=
+ 2.0 ** (Long_Long_Float'Machine_Mantissa - 1);
+ -- This is an upper bound for the number of bits used to represent the
+ -- mantissa. Beyond that number, any digits parsed by Scanf are useless.
+ -- Thus, only the scale should be updated. This ensures that infinity is
+ -- not reached by the temporary Uval, which could lead to erroneous
+ -- rounding (for example: 0.4444444... or 1<n zero>E-n).
procedure Scanf;
-- Scans integer literal value starting at current character position.
@@ -96,56 +93,50 @@ package body System.Val_Real is
-----------
procedure Scanf is
- Digit : Natural;
-
+ Digit : Natural;
+ Uval_Tmp : Long_Long_Float;
+ Precision_Limit_Reached : Boolean := False;
begin
loop
Digit := Character'Pos (Str (P)) - Character'Pos ('0');
- P := P + 1;
-
- -- Save up trailing zeroes after the decimal point
-
- if Digit = 0 and then After_Point = 1 then
- Num_Saved_Zeroes := Num_Saved_Zeroes + 1;
-
- -- Here for a non-zero digit
-
- else
- -- First deal with any previously saved zeroes
-
- if Num_Saved_Zeroes /= 0 then
- while Num_Saved_Zeroes > Maxpow loop
- Uval := Uval * Powten (Maxpow);
- Num_Saved_Zeroes := Num_Saved_Zeroes - Maxpow;
- Scale := Scale - Maxpow;
- end loop;
- Uval := Uval * Powten (Num_Saved_Zeroes);
- Scale := Scale - Num_Saved_Zeroes;
+ if not Precision_Limit_Reached then
+ -- Compute potential new value
+ Uval_Tmp := Uval * 10.0 + Long_Long_Float (Digit);
- Num_Saved_Zeroes := 0;
+ if Uval_Tmp > Precision_Limit then
+ Precision_Limit_Reached := True;
end if;
+ end if;
- -- Accumulate new digit
-
- Uval := Uval * 10.0 + Long_Long_Float (Digit);
+ if Precision_Limit_Reached then
+ -- If beyond the precision of the mantissa then just ignore the
+ -- digit, to avoid rounding issues.
+ if After_Point = 0 then
+ Scale := Scale + 1;
+ end if;
+ else
+ Uval := Uval_Tmp;
Scale := Scale - After_Point;
end if;
- -- Done if end of input field
+ -- Check next character
+ P := P + 1;
if P > Max then
+ -- Done if end of input field
return;
- -- Check next character
-
elsif Str (P) not in Digs then
+ -- If next character is not a digit, check if this is an
+ -- underscore. If this is not the case, then return.
if Str (P) = '_' then
Scan_Underscore (Str, P, Ptr, Max, False);
else
return;
end if;
end if;
+
end loop;
end Scanf;
@@ -198,7 +189,8 @@ package body System.Val_Real is
Base_Char : constant Character := Str (P);
Digit : Natural;
Fdigit : Long_Long_Float;
-
+ Uval_Tmp : Long_Long_Float;
+ Precision_Limit_Reached : Boolean := False;
begin
-- Set bad base if out of range, and use safe base of 16.0,
-- to guard against division by zero in the loop below.
@@ -243,22 +235,24 @@ package body System.Val_Real is
Bad_Value (Str);
end if;
- -- Save up trailing zeroes after the decimal point
+ if not Precision_Limit_Reached then
+ -- Compute potential new value
+ Uval_Tmp := Uval * Base + Long_Long_Float (Digit);
- if Digit = 0 and then After_Point = 1 then
- Num_Saved_Zeroes := Num_Saved_Zeroes + 1;
+ if Uval_Tmp > Precision_Limit then
+ Precision_Limit_Reached := True;
+ end if;
+ end if;
- -- Here for a non-zero digit
+ if Precision_Limit_Reached then
+ -- If beyond precision of the mantissa then just update
+ -- the scale and discard remaining digits.
- else
- -- First deal with any previously saved zeroes
-
- if Num_Saved_Zeroes /= 0 then
- Uval := Uval * Base ** Num_Saved_Zeroes;
- Scale := Scale - Num_Saved_Zeroes;
- Num_Saved_Zeroes := 0;
+ if After_Point = 0 then
+ Scale := Scale + 1;
end if;
+ else
-- Now accumulate the new digit
Fdigit := Long_Long_Float (Digit);
@@ -267,7 +261,7 @@ package body System.Val_Real is
Bad_Base := True;
else
Scale := Scale - After_Point;
- Uval := Uval * Base + Fdigit;
+ Uval := Uval_Tmp;
end if;
end if;
diff --git a/gcc/ada/libgnat/s-valrea.ads b/gcc/ada/libgnat/s-valrea.ads
index 49607ed..b59f345 100644
--- a/gcc/ada/libgnat/s-valrea.ads
+++ b/gcc/ada/libgnat/s-valrea.ads
@@ -30,7 +30,7 @@
------------------------------------------------------------------------------
package System.Val_Real is
- pragma Pure;
+ pragma Preelaborate;
function Scan_Real
(Str : String;
diff --git a/gcc/ada/libgnat/s-valuns.ads b/gcc/ada/libgnat/s-valuns.ads
index 741ae6f..7d261b1 100644
--- a/gcc/ada/libgnat/s-valuns.ads
+++ b/gcc/ada/libgnat/s-valuns.ads
@@ -35,7 +35,7 @@
with System.Unsigned_Types;
package System.Val_Uns is
- pragma Pure;
+ pragma Preelaborate;
function Scan_Raw_Unsigned
(Str : String;
diff --git a/gcc/ada/libgnat/s-valwch.ads b/gcc/ada/libgnat/s-valwch.ads
index 5a72295..5179517 100644
--- a/gcc/ada/libgnat/s-valwch.ads
+++ b/gcc/ada/libgnat/s-valwch.ads
@@ -34,7 +34,7 @@
with System.WCh_Con;
package System.Val_WChar is
- pragma Pure;
+ pragma Preelaborate;
function Value_Wide_Character
(Str : String;
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index 750e62f..805addb 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -502,7 +502,7 @@ package body Make is
-- linker). For the sake of convenience, some program specific switches
-- can be passed directly on the gnatmake command line. This procedure
-- records these switches so that gnatmake can pass them to the right
- -- program. S is the switch to be added at the end of the command line
+ -- program. S is the switch to be added at the end of the command line
-- for Program if Append_Switch is True. If Append_Switch is False S is
-- added at the beginning of the command line.
diff --git a/gcc/ada/mkdir.c b/gcc/ada/mkdir.c
index d061476..e0efcce 100644
--- a/gcc/ada/mkdir.c
+++ b/gcc/ada/mkdir.c
@@ -35,8 +35,7 @@
#endif /* __vxworks */
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
+#include "runtime.h"
#include <sys/stat.h>
#else
#include "config.h"
diff --git a/gcc/ada/namet.ads b/gcc/ada/namet.ads
index a54735a..bdd3dad 100644
--- a/gcc/ada/namet.ads
+++ b/gcc/ada/namet.ads
@@ -431,7 +431,7 @@ package Namet is
-- Uhh encoding (hh = hex code), other 16-bit wide character values are
-- stored using the Whhhh (hhhh = hex code) encoding, and other 32-bit wide
-- wide character values are stored using the WWhhhhhhhh (hhhhhhhh = hex
- -- code). Note that this procedure does not fold upper case letters (they
+ -- code). Note that this procedure does not fold upper case letters (they
-- are stored using the Uhh encoding).
procedure Set_Character_Literal_Name
diff --git a/gcc/ada/opt.adb b/gcc/ada/opt.adb
index 43d340b..4ceffb0 100644
--- a/gcc/ada/opt.adb
+++ b/gcc/ada/opt.adb
@@ -248,7 +248,14 @@ package body Opt is
SPARK_Mode_Pragma := SPARK_Mode_Pragma_Config;
else
- if GNAT_Mode_Config then
+ -- In GNATprove mode assertions should be always enabled, even
+ -- when analysing internal units.
+
+ if GNATprove_Mode then
+ pragma Assert (Assertions_Enabled);
+ null;
+
+ elsif GNAT_Mode_Config then
Assertions_Enabled := Assertions_Enabled_Config;
else
Assertions_Enabled := False;
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 16b5cba..4d3e87e 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -947,6 +947,11 @@ package Opt is
-- Set to True when the pre-18.x access-before-elaboration model is to be
-- used. Modified by use of -gnatH.
+ Legacy_Elaboration_Order : Boolean := False;
+ -- GNATBIND
+ -- Set to True when the pre-20.x elaboration-order model is to be used.
+ -- Modified by use of -H.
+
Link_Only : Boolean := False;
-- GNATMAKE, GPRBUILD
-- Set to True to skip compile and bind steps (except when Bind_Only is
@@ -1115,6 +1120,12 @@ package Opt is
-- Maximum number of processes that should be spawned to carry out
-- compilations.
+ Minimal_Binder : Boolean := False;
+ -- GNATBIND
+ -- Set to True to suppress the generation of objects by the binder that
+ -- are not strictly required for a program to run. Intended for ZFP
+ -- applications that have tight memory constraints.
+
Minimal_Recompilation : Boolean := False;
-- GNATMAKE
-- Set to True if minimal recompilation mode requested
@@ -1979,7 +1990,7 @@ package Opt is
-- set by the command line switches -gnat83/95/2005/2012, and possibly
-- modified by the use of configuration pragmas Ada_*. This switch is used
-- to set the initial value for Ada_Version mode at the start of analysis
- -- of a unit. Note however that the setting of this flag is ignored for
+ -- of a unit. Note however that the setting of this flag is ignored for
-- internal and predefined units (which are always compiled in the most up
-- to date version of Ada).
diff --git a/gcc/ada/osint-c.adb b/gcc/ada/osint-c.adb
index 8af5aa0..9fb9ee3 100644
--- a/gcc/ada/osint-c.adb
+++ b/gcc/ada/osint-c.adb
@@ -385,6 +385,21 @@ package body Osint.C is
end if;
end loop;
+ -- If we are in multiple-units-per-file mode, then add a ~nnn extension
+ -- to the name.
+
+ if Multiple_Unit_Index /= 0 then
+ declare
+ Exten : constant String := Name_Buffer (Dot_Index .. Name_Len);
+ begin
+ Name_Len := Dot_Index - 1;
+ Add_Char_To_Name_Buffer (Multi_Unit_Index_Character);
+ Add_Nat_To_Name_Buffer (Multiple_Unit_Index);
+ Dot_Index := Name_Len + 1;
+ Add_Str_To_Name_Buffer (Exten);
+ end;
+ end if;
+
-- Make sure that the output file name matches the source file name.
-- To compare them, remove file name directories and extensions.
@@ -395,21 +410,6 @@ package body Osint.C is
Name_Buffer (Dot_Index) := '.';
- -- If we are in multiple unit per file mode, then add ~nnn
- -- extension to the name before doing the comparison.
-
- if Multiple_Unit_Index /= 0 then
- declare
- Exten : constant String := Name_Buffer (Dot_Index .. Name_Len);
- begin
- Name_Len := Dot_Index - 1;
- Add_Char_To_Name_Buffer (Multi_Unit_Index_Character);
- Add_Nat_To_Name_Buffer (Multiple_Unit_Index);
- Dot_Index := Name_Len + 1;
- Add_Str_To_Name_Buffer (Exten);
- end;
- end if;
-
-- Remove extension preparing to replace it
declare
diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
index 9de9a60..b9b0214 100644
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -2262,7 +2262,7 @@ package body Ch4 is
-- capacity-exceeded error. The purpose of this trick is to avoid
-- creating a deeply nested tree, which would cause deep recursion
-- during semantics, causing stack overflow. This way, we can handle
- -- enormous concatenations in the normal case of predefined "&". We
+ -- enormous concatenations in the normal case of predefined "&". We
-- first build up the normal tree, and then rewrite it if
-- appropriate.
diff --git a/gcc/ada/par-ch6.adb b/gcc/ada/par-ch6.adb
index 0c4672c..0fc7109 100644
--- a/gcc/ada/par-ch6.adb
+++ b/gcc/ada/par-ch6.adb
@@ -1442,7 +1442,7 @@ package body Ch6 is
Look_Ahead : loop
-- If we run into a semicolon, then assume that a
- -- colon was missing, e.g. Parms (X Y; ...). Also
+ -- colon was missing, e.g. Parms (X Y; ...). Also
-- assume missing colon on EOF (a real disaster)
-- and on a right paren, e.g. Parms (X Y), and also
-- on an assignment symbol, e.g. Parms (X Y := ..)
diff --git a/gcc/ada/par-labl.adb b/gcc/ada/par-labl.adb
index 1edc803..899905e 100644
--- a/gcc/ada/par-labl.adb
+++ b/gcc/ada/par-labl.adb
@@ -79,7 +79,7 @@ procedure Labl is
-- then we have an error.
-- Note that in the worst case, this is quadratic in the number
- -- of labels. However, labels are not all that common, and this
+ -- of labels. However, labels are not all that common, and this
-- is only called for explicit labels.
-- ???Nonetheless, the efficiency could be improved. For example,
diff --git a/gcc/ada/par-load.adb b/gcc/ada/par-load.adb
index cb95500..70bc5cb 100644
--- a/gcc/ada/par-load.adb
+++ b/gcc/ada/par-load.adb
@@ -36,7 +36,6 @@ with Uname; use Uname;
with Osint; use Osint;
with Sinput.L; use Sinput.L;
with Stylesw; use Stylesw;
-with Validsw; use Validsw;
with GNAT.Spelling_Checker; use GNAT.Spelling_Checker;
@@ -61,10 +60,6 @@ procedure Load is
Save_Style_Checks : Style_Check_Options;
-- Save style check so it can be restored later
- Save_Validity_Check : Boolean;
- Save_Validity_Checks : Validity_Check_Options;
- -- Save validity check so it can be restored later
-
With_Cunit : Node_Id;
-- Compilation unit node for withed unit
@@ -134,9 +129,6 @@ begin
Save_Style_Check_Options (Save_Style_Checks);
Save_Style_Check := Opt.Style_Check;
- Save_Validity_Check_Options (Save_Validity_Checks);
- Save_Validity_Check := Opt.Validity_Checks_On;
-
-- If main unit, set Main_Unit_Entity (this will get overwritten if
-- the main unit has a separate spec, that happens later on in Load)
@@ -318,11 +310,10 @@ begin
or else Nkind (Unit (Curunit)) in N_Generic_Instantiation
or else Nkind (Unit (Curunit)) in N_Renaming_Declaration
then
- -- Turn style and validity checks off for parent unit
+ -- Turn style checks off for parent unit
if not GNAT_Mode then
Reset_Style_Check_Options;
- Reset_Validity_Check_Options;
end if;
Spec_Name := Get_Parent_Spec_Name (Unit_Name (Cur_Unum));
@@ -356,11 +347,10 @@ begin
end if;
end if;
- -- Now we load with'ed units, with style/validity checks turned off
+ -- Now we load with'ed units, with style checks turned off
if not GNAT_Mode then
Reset_Style_Check_Options;
- Reset_Validity_Check_Options;
end if;
-- Load the context items in two rounds: the first round handles normal
@@ -470,6 +460,4 @@ begin
Set_Style_Check_Options (Save_Style_Checks);
Opt.Style_Check := Save_Style_Check;
- Set_Validity_Check_Options (Save_Validity_Checks);
- Opt.Validity_Checks_On := Save_Validity_Check;
end Load;
diff --git a/gcc/ada/prep.adb b/gcc/ada/prep.adb
index 42ff57b..8549f79 100644
--- a/gcc/ada/prep.adb
+++ b/gcc/ada/prep.adb
@@ -825,7 +825,7 @@ package body Prep is
------------------
procedure List_Symbols (Foreword : String) is
- Order : array (0 .. Integer (Symbol_Table.Last (Mapping)))
+ Order : array (0 .. Integer (Symbol_Table.Last (Mapping)))
of Symbol_Id;
-- After alphabetical sorting, this array stores the indexes of the
-- symbols in the order they are displayed.
diff --git a/gcc/ada/raise-gcc.c b/gcc/ada/raise-gcc.c
index 6092a87..c15547d 100644
--- a/gcc/ada/raise-gcc.c
+++ b/gcc/ada/raise-gcc.c
@@ -39,11 +39,11 @@
/* Don't use fancy_abort. */
# undef abort
#else
-# ifndef CERT
+# if !defined(CERT) && !defined(STANDALONE)
# include "tconfig.h"
# include "tsystem.h"
# else
-# define ATTRIBUTE_UNUSED __attribute__((unused))
+# include "runtime.h"
# define HAVE_GETIPINFO 1
# endif
#endif
@@ -115,6 +115,10 @@ extern void __gnat_unhandled_except_handler (_Unwind_Exception *);
/* Called in case of error during propagation. */
extern void __gnat_raise_abort (void) __attribute__ ((noreturn));
#define abort() __gnat_raise_abort()
+
+#elif defined(STANDALONE)
+#include <stdlib.h>
+#define inhibit_libc
#endif
#include "unwind-pe.h"
diff --git a/gcc/ada/raise.c b/gcc/ada/raise.c
index 480a0ea..bf8a879 100644
--- a/gcc/ada/raise.c
+++ b/gcc/ada/raise.c
@@ -33,8 +33,7 @@
is shared between all exception handling mechanisms. */
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
+#include "runtime.h"
#else
#include "config.h"
#include "system.h"
@@ -56,16 +55,6 @@ extern "C" {
void
__gnat_unhandled_terminate (void)
{
-#ifdef VMS
- /* Special termination handling for VMS */
- long prvhnd;
-
- /* Remove the exception vector so it won't intercept any errors
- in the call to exit, and go into and endless loop */
-
- SYS$SETEXV (1, 0, 3, &prvhnd);
-#endif
-
/* Default termination handling */
__gnat_os_exit (1);
}
diff --git a/gcc/ada/repinfo-input.adb b/gcc/ada/repinfo-input.adb
new file mode 100644
index 0000000..92ca510
--- /dev/null
+++ b/gcc/ada/repinfo-input.adb
@@ -0,0 +1,1350 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- R E P I N F O - I N P U T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2018-2019, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Alloc;
+with Csets; use Csets;
+with Hostparm; use Hostparm;
+with Namet; use Namet;
+with Output; use Output;
+with Snames; use Snames;
+with Table;
+
+package body Repinfo.Input is
+
+ SSU : constant := 8;
+ -- Value for Storage_Unit, we do not want to get this from TTypes, since
+ -- this introduces problematic dependencies in ASIS, and in any case this
+ -- value is assumed to be 8 for the implementation of the DDA.
+
+ type JSON_Entity_Kind is (JE_Record_Type, JE_Array_Type, JE_Other);
+ -- Kind of an entiy
+
+ type JSON_Entity_Node (Kind : JSON_Entity_Kind := JE_Other) is record
+ Esize : Node_Ref_Or_Val;
+ RM_Size : Node_Ref_Or_Val;
+ case Kind is
+ when JE_Record_Type => Variant : Nat;
+ when JE_Array_Type => Component_Size : Node_Ref_Or_Val;
+ when JE_Other => Dummy : Boolean;
+ end case;
+ end record;
+ pragma Unchecked_Union (JSON_Entity_Node);
+ -- Record to represent an entity
+
+ package JSON_Entity_Table is new Table.Table (
+ Table_Component_Type => JSON_Entity_Node,
+ Table_Index_Type => Nat,
+ Table_Low_Bound => 1,
+ Table_Initial => Alloc.Rep_JSON_Table_Initial,
+ Table_Increment => Alloc.Rep_JSON_Table_Increment,
+ Table_Name => "JSON_Entity_Table");
+ -- Table of entities
+
+ type JSON_Component_Node is record
+ Bit_Offset : Node_Ref_Or_Val;
+ Esize : Node_Ref_Or_Val;
+ end record;
+ -- Record to represent a component
+
+ package JSON_Component_Table is new Table.Table (
+ Table_Component_Type => JSON_Component_Node,
+ Table_Index_Type => Nat,
+ Table_Low_Bound => 1,
+ Table_Initial => Alloc.Rep_JSON_Table_Initial,
+ Table_Increment => Alloc.Rep_JSON_Table_Increment,
+ Table_Name => "JSON_Component_Table");
+ -- Table of components
+
+ type JSON_Variant_Node is record
+ Present : Node_Ref_Or_Val;
+ Variant : Nat;
+ Next : Nat;
+ end record;
+ -- Record to represent a variant
+
+ package JSON_Variant_Table is new Table.Table (
+ Table_Component_Type => JSON_Variant_Node,
+ Table_Index_Type => Nat,
+ Table_Low_Bound => 1,
+ Table_Initial => Alloc.Rep_JSON_Table_Initial,
+ Table_Increment => Alloc.Rep_JSON_Table_Increment,
+ Table_Name => "JSON_Variant_Table");
+ -- Table of variants
+
+ -------------------------------------
+ -- Get_JSON_Component_Bit_Offset --
+ -------------------------------------
+
+ function Get_JSON_Component_Bit_Offset
+ (Name : String;
+ Record_Name : String) return Node_Ref_Or_Val
+ is
+ Namid : constant Valid_Name_Id := Name_Find (Record_Name & '.' & Name);
+ Index : constant Int := Get_Name_Table_Int (Namid);
+
+ begin
+ -- Return No_Uint if no information is available for the component
+
+ if Index = 0 then
+ return No_Uint;
+ end if;
+
+ return JSON_Component_Table.Table (Index).Bit_Offset;
+ end Get_JSON_Component_Bit_Offset;
+
+ -------------------------------
+ -- Get_JSON_Component_Size --
+ -------------------------------
+
+ function Get_JSON_Component_Size (Name : String) return Node_Ref_Or_Val is
+ Namid : constant Valid_Name_Id := Name_Find (Name);
+ Index : constant Int := Get_Name_Table_Int (Namid);
+
+ begin
+ -- Return No_Uint if no information is available for the component
+
+ if Index = 0 then
+ return No_Uint;
+ end if;
+
+ return JSON_Entity_Table.Table (Index).Component_Size;
+ end Get_JSON_Component_Size;
+
+ ----------------------
+ -- Get_JSON_Esize --
+ ----------------------
+
+ function Get_JSON_Esize (Name : String) return Node_Ref_Or_Val is
+ Namid : constant Valid_Name_Id := Name_Find (Name);
+ Index : constant Int := Get_Name_Table_Int (Namid);
+
+ begin
+ -- Return No_Uint if no information is available for the entity
+
+ if Index = 0 then
+ return No_Uint;
+ end if;
+
+ return JSON_Entity_Table.Table (Index).Esize;
+ end Get_JSON_Esize;
+
+ ----------------------
+ -- Get_JSON_Esize --
+ ----------------------
+
+ function Get_JSON_Esize
+ (Name : String;
+ Record_Name : String) return Node_Ref_Or_Val
+ is
+ Namid : constant Valid_Name_Id := Name_Find (Record_Name & '.' & Name);
+ Index : constant Int := Get_Name_Table_Int (Namid);
+
+ begin
+ -- Return No_Uint if no information is available for the entity
+
+ if Index = 0 then
+ return No_Uint;
+ end if;
+
+ return JSON_Component_Table.Table (Index).Esize;
+ end Get_JSON_Esize;
+
+ ------------------------
+ -- Get_JSON_RM_Size --
+ ------------------------
+
+ function Get_JSON_RM_Size (Name : String) return Node_Ref_Or_Val is
+ Namid : constant Valid_Name_Id := Name_Find (Name);
+ Index : constant Int := Get_Name_Table_Int (Namid);
+
+ begin
+ -- Return No_Uint if no information is available for the entity
+
+ if Index = 0 then
+ return No_Uint;
+ end if;
+
+ return JSON_Entity_Table.Table (Index).RM_Size;
+ end Get_JSON_RM_Size;
+
+ -----------------------
+ -- Read_JSON_Stream --
+ -----------------------
+
+ procedure Read_JSON_Stream (Text : Text_Buffer; File_Name : String) is
+
+ type Text_Position is record
+ Index : Text_Ptr := 0;
+ Line : Natural := 0;
+ Column : Natural := 0;
+ end record;
+ -- Record to represent position in the text
+
+ type Token_Kind is
+ (J_NULL,
+ J_TRUE,
+ J_FALSE,
+ J_NUMBER,
+ J_INTEGER,
+ J_STRING,
+ J_ARRAY,
+ J_OBJECT,
+ J_ARRAY_END,
+ J_OBJECT_END,
+ J_COMMA,
+ J_COLON,
+ J_EOF);
+ -- JSON Token kind. Note that in ECMA 404 there is no notion of integer.
+ -- Only numbers are supported. In our implementation we return J_INTEGER
+ -- if there is no decimal part in the number. The semantic is that this
+ -- is a J_NUMBER token that might be represented as an integer. Special
+ -- token J_EOF means that end of stream has been reached.
+
+ function Decode_Integer (Lo, Hi : Text_Ptr) return Uint;
+ -- Decode and return the integer in Text (Lo .. Hi)
+
+ function Decode_Name (Lo, Hi : Text_Ptr) return Valid_Name_Id;
+ -- Decode and return the name in Text (Lo .. Hi)
+
+ function Decode_Symbol (Lo, Hi : Text_Ptr) return TCode;
+ -- Decode and return the expression symbol in Text (Lo .. Hi)
+
+ procedure Error (Msg : String);
+ pragma No_Return (Error);
+ -- Print an error message and raise an exception
+
+ procedure Read_Entity;
+ -- Read an entity
+
+ function Read_Name return Valid_Name_Id;
+ -- Read a name
+
+ function Read_Name_With_Prefix return Valid_Name_Id;
+ -- Read a name and prepend a prefix
+
+ function Read_Number return Uint;
+ -- Read a number
+
+ function Read_Numerical_Expr return Node_Ref_Or_Val;
+ -- Read a numerical expression
+
+ procedure Read_Record;
+ -- Read a record
+
+ function Read_String return Valid_Name_Id;
+ -- Read a string
+
+ procedure Read_Token
+ (Kind : out Token_Kind;
+ Token_Start : out Text_Position;
+ Token_End : out Text_Position);
+ -- Read a token and return it (this is a standard JSON lexer)
+
+ procedure Read_Token_And_Error
+ (TK : Token_Kind;
+ Token_Start : out Text_Position;
+ Token_End : out Text_Position);
+ pragma Inline (Read_Token_And_Error);
+ -- Read a specified token and error out on failure
+
+ function Read_Variant_Part return Nat;
+ -- Read a variant part
+
+ procedure Skip_Value;
+ -- Skip a value
+
+ Pos : Text_Position := (Text'First, 1, 1);
+ -- The current position in the text buffer
+
+ Name_Buffer : Bounded_String (4 * Max_Name_Length);
+ -- The buffer used to build full qualifed names
+
+ Prefix_Len : Natural := 0;
+ -- The length of the prefix present in Name_Buffer
+
+ ----------------------
+ -- Decode_Integer --
+ ----------------------
+
+ function Decode_Integer (Lo, Hi : Text_Ptr) return Uint is
+ Len : constant Nat := Int (Hi) - Int (Lo) + 1;
+
+ begin
+ -- Decode up to 9 characters manually, otherwise call into Uint
+
+ if Len < 10 then
+ declare
+ Val : Int := 0;
+
+ begin
+ for J in Lo .. Hi loop
+ Val := Val * 10
+ + Character'Pos (Text (J)) - Character'Pos ('0');
+ end loop;
+ return UI_From_Int (Val);
+ end;
+
+ else
+ declare
+ Val : Uint := Uint_0;
+
+ begin
+ for J in Lo .. Hi loop
+ Val := Val * 10
+ + Character'Pos (Text (J)) - Character'Pos ('0');
+ end loop;
+ return Val;
+ end;
+ end if;
+ end Decode_Integer;
+
+ -------------------
+ -- Decode_Name --
+ -------------------
+
+ function Decode_Name (Lo, Hi : Text_Ptr) return Valid_Name_Id is
+ begin
+ -- Names are stored in lower case so fold them if need be
+
+ if Is_Upper_Case_Letter (Text (Lo)) then
+ declare
+ S : String (Integer (Lo) .. Integer (Hi));
+
+ begin
+ for J in Lo .. Hi loop
+ S (Integer (J)) := Fold_Lower (Text (J));
+ end loop;
+
+ return Name_Find (S);
+ end;
+
+ else
+ declare
+ S : String (Integer (Lo) .. Integer (Hi));
+ for S'Address use Text (Lo)'Address;
+
+ begin
+ return Name_Find (S);
+ end;
+ end if;
+ end Decode_Name;
+
+ ---------------------
+ -- Decode_Symbol --
+ ---------------------
+
+ function Decode_Symbol (Lo, Hi : Text_Ptr) return TCode is
+
+ function Cmp12 (A, B : Character) return Boolean;
+ pragma Inline (Cmp12);
+ -- Compare Text (Lo + 1 .. Lo + 2) with A & B.
+
+ -------------
+ -- Cmp12 --
+ -------------
+
+ function Cmp12 (A, B : Character) return Boolean is
+ begin
+ return Text (Lo + 1) = A and then Text (Lo + 2) = B;
+ end Cmp12;
+
+ Len : constant Nat := Int (Hi) - Int (Lo) + 1;
+
+ -- Start of processing for Decode_Symbol
+
+ begin
+ case Len is
+ when 1 =>
+ case Text (Lo) is
+ when '+' =>
+ return Plus_Expr;
+ when '-' =>
+ return Minus_Expr; -- or Negate_Expr
+ when '*' =>
+ return Mult_Expr;
+ when '<' =>
+ return Lt_Expr;
+ when '>' =>
+ return Gt_Expr;
+ when '&' =>
+ return Bit_And_Expr;
+ when '#' =>
+ return Discrim_Val;
+ when others =>
+ null;
+ end case;
+ when 2 =>
+ if Text (Lo) = '/' then
+ case Text (Lo + 1) is
+ when 't' =>
+ return Trunc_Div_Expr;
+ when 'c' =>
+ return Ceil_Div_Expr;
+ when 'f' =>
+ return Floor_Div_Expr;
+ when 'e' =>
+ return Exact_Div_Expr;
+ when others =>
+ null;
+ end case;
+ elsif Text (Lo + 1) = '=' then
+ case Text (Lo) is
+ when '<' =>
+ return Le_Expr;
+ when '>' =>
+ return Ge_Expr;
+ when '=' =>
+ return Eq_Expr;
+ when '!' =>
+ return Ne_Expr;
+ when others =>
+ null;
+ end case;
+ elsif Text (Lo) = 'o' and then Text (Lo + 1) = 'r' then
+ return Truth_Or_Expr;
+ end if;
+ when 3 =>
+ case Text (Lo) is
+ when '?' =>
+ if Cmp12 ('<', '>') then
+ return Cond_Expr;
+ end if;
+ when 'a' =>
+ if Cmp12 ('b', 's') then
+ return Abs_Expr;
+ elsif Cmp12 ('n', 'd') then
+ return Truth_And_Expr;
+ end if;
+ when 'm' =>
+ if Cmp12 ('a', 'x') then
+ return Max_Expr;
+ elsif Cmp12 ('i', 'n') then
+ return Min_Expr;
+ end if;
+ when 'n' =>
+ if Cmp12 ('o', 't') then
+ return Truth_Not_Expr;
+ end if;
+ when 'x' =>
+ if Cmp12 ('o', 'r') then
+ return Truth_Xor_Expr;
+ end if;
+ when 'v' =>
+ if Cmp12 ('a', 'r') then
+ return Dynamic_Val;
+ end if;
+ when others =>
+ null;
+ end case;
+ when 4 =>
+ if Text (Lo) = 'm'
+ and then Text (Lo + 1) = 'o'
+ and then Text (Lo + 2) = 'd'
+ then
+ case Text (Lo + 3) is
+ when 't' =>
+ return Trunc_Mod_Expr;
+ when 'c' =>
+ return Ceil_Mod_Expr;
+ when 'f' =>
+ return Floor_Mod_Expr;
+ when others =>
+ null;
+ end case;
+ end if;
+
+ pragma Annotate
+ (CodePeer, Intentional,
+ "condition predetermined", "Error called as defensive code");
+
+ when others =>
+ null;
+ end case;
+
+ Error ("unknown symbol");
+ end Decode_Symbol;
+
+ -----------
+ -- Error --
+ -----------
+
+ procedure Error (Msg : String) is
+ L : constant String := Pos.Line'Img;
+ C : constant String := Pos.Column'Img;
+
+ begin
+ Set_Standard_Error;
+ Write_Eol;
+ Write_Str (File_Name);
+ Write_Char (':');
+ Write_Str (L (L'First + 1 .. L'Last));
+ Write_Char (':');
+ Write_Str (C (C'First + 1 .. C'Last));
+ Write_Char (':');
+ Write_Line (Msg);
+ raise Invalid_JSON_Stream;
+ end Error;
+
+ ------------------
+ -- Read_Entity --
+ ------------------
+
+ procedure Read_Entity is
+ Ent : JSON_Entity_Node;
+ Nam : Name_Id := No_Name;
+ Siz : Node_Ref_Or_Val;
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+ TK : Token_Kind;
+
+ begin
+ Ent.Esize := No_Uint;
+ Ent.RM_Size := No_Uint;
+ Ent.Component_Size := No_Uint;
+
+ -- Read the members as string : value pairs
+
+ loop
+ case Read_String is
+ when Name_Name =>
+ Nam := Read_Name;
+ when Name_Record =>
+ if Nam = No_Name then
+ Error ("name expected");
+ end if;
+ Ent.Variant := 0;
+ Prefix_Len := Natural (Length_Of_Name (Nam));
+ Name_Buffer.Chars (1 .. Prefix_Len) := Get_Name_String (Nam);
+ Read_Record;
+ when Name_Variant =>
+ Ent.Variant := Read_Variant_Part;
+ when Name_Size =>
+ Siz := Read_Numerical_Expr;
+ Ent.Esize := Siz;
+ Ent.RM_Size := Siz;
+ when Name_Object_Size =>
+ Ent.Esize := Read_Numerical_Expr;
+ when Name_Value_Size =>
+ Ent.RM_Size := Read_Numerical_Expr;
+ when Name_Component_Size =>
+ Ent.Component_Size := Read_Numerical_Expr;
+ when others =>
+ Skip_Value;
+ end case;
+
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_OBJECT_END then
+ exit;
+ elsif TK /= J_COMMA then
+ Error ("comma expected");
+ end if;
+ end loop;
+
+ -- Store the entity into the table
+
+ JSON_Entity_Table.Append (Ent);
+
+ -- Associate the name with the entity
+
+ if Nam = No_Name then
+ Error ("name expected");
+ end if;
+
+ Set_Name_Table_Int (Nam, JSON_Entity_Table.Last);
+ end Read_Entity;
+
+ -----------------
+ -- Read_Name --
+ -----------------
+
+ function Read_Name return Valid_Name_Id is
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+
+ begin
+ -- Read a single string
+
+ Read_Token_And_Error (J_STRING, Token_Start, Token_End);
+
+ return Decode_Name (Token_Start.Index + 1, Token_End.Index - 1);
+ end Read_Name;
+
+ -----------------------------
+ -- Read_Name_With_Prefix --
+ -----------------------------
+
+ function Read_Name_With_Prefix return Valid_Name_Id is
+ Len : Natural;
+ Lo, Hi : Text_Ptr;
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+
+ begin
+ -- Read a single string
+
+ Read_Token_And_Error (J_STRING, Token_Start, Token_End);
+ Lo := Token_Start.Index + 1;
+ Hi := Token_End.Index - 1;
+
+ -- Prepare for the concatenation with the prefix
+
+ Len := Integer (Hi) - Integer (Lo) + 1;
+ if Prefix_Len + 1 + Len > Name_Buffer.Max_Length then
+ Error ("Name buffer too small");
+ end if;
+
+ Name_Buffer.Length := Prefix_Len + 1 + Len;
+ Name_Buffer.Chars (Prefix_Len + 1) := '.';
+
+ -- Names are stored in lower case so fold them if need be
+
+ if Is_Upper_Case_Letter (Text (Lo)) then
+ for J in Lo .. Hi loop
+ Name_Buffer.Chars (Prefix_Len + 2 + Integer (J - Lo)) :=
+ Fold_Lower (Text (J));
+ end loop;
+
+ else
+ declare
+ S : String (Integer (Lo) .. Integer (Hi));
+ for S'Address use Text (Lo)'Address;
+
+ begin
+ Name_Buffer.Chars (Prefix_Len + 2 .. Prefix_Len + 1 + Len) := S;
+ end;
+ end if;
+
+ return Name_Find (Name_Buffer);
+ end Read_Name_With_Prefix;
+
+ ------------------
+ -- Read_Number --
+ ------------------
+
+ function Read_Number return Uint is
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+
+ begin
+ -- Only integers are to be expected here
+
+ Read_Token_And_Error (J_INTEGER, Token_Start, Token_End);
+
+ return Decode_Integer (Token_Start.Index, Token_End.Index);
+ end Read_Number;
+
+ --------------------------
+ -- Read_Numerical_Expr --
+ --------------------------
+
+ function Read_Numerical_Expr return Node_Ref_Or_Val is
+ Code : TCode;
+ Nop : Integer;
+ Ops : array (1 .. 3) of Node_Ref_Or_Val;
+ TK : Token_Kind;
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+
+ begin
+ -- Read either an integer or an expression
+
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_INTEGER then
+ return Decode_Integer (Token_Start.Index, Token_End.Index);
+
+ elsif TK = J_OBJECT then
+ -- Read the code of the expression and decode it
+
+ if Read_String /= Name_Code then
+ Error ("name expected");
+ end if;
+
+ Read_Token_And_Error (J_STRING, Token_Start, Token_End);
+ Code := Decode_Symbol (Token_Start.Index + 1, Token_End.Index - 1);
+ Read_Token_And_Error (J_COMMA, Token_Start, Token_End);
+
+ -- Read the array of operands
+
+ if Read_String /= Name_Operands then
+ Error ("operands expected");
+ end if;
+
+ Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);
+
+ Nop := 0;
+ Ops := (others => No_Uint);
+ loop
+ Nop := Nop + 1;
+ Ops (Nop) := Read_Numerical_Expr;
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_ARRAY_END then
+ exit;
+ elsif TK /= J_COMMA then
+ Error ("comma expected");
+ end if;
+ end loop;
+
+ Read_Token_And_Error (J_OBJECT_END, Token_Start, Token_End);
+
+ -- Resolve the ambiguity for '-' now
+
+ if Code = Minus_Expr and then Nop = 1 then
+ Code := Negate_Expr;
+ end if;
+
+ return Create_Node (Code, Ops (1), Ops (2), Ops (3));
+
+ else
+ Error ("numerical expression expected");
+ end if;
+ end Read_Numerical_Expr;
+
+ -------------------
+ -- Read_Record --
+ -------------------
+
+ procedure Read_Record is
+ Comp : JSON_Component_Node;
+ First_Bit : Node_Ref_Or_Val := No_Uint;
+ Is_First : Boolean := True;
+ Nam : Name_Id := No_Name;
+ Position : Node_Ref_Or_Val := No_Uint;
+ TK : Token_Kind;
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+
+ begin
+ -- Read a possibly empty array of components
+
+ Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);
+
+ loop
+ Read_Token (TK, Token_Start, Token_End);
+ if Is_First and then TK = J_ARRAY_END then
+ exit;
+ elsif TK /= J_OBJECT then
+ Error ("object expected");
+ end if;
+
+ -- Read the members as string : value pairs
+
+ loop
+ case Read_String is
+ when Name_Name =>
+ Nam := Read_Name_With_Prefix;
+ when Name_Discriminant =>
+ Skip_Value;
+ when Name_Position =>
+ Position := Read_Numerical_Expr;
+ when Name_First_Bit =>
+ First_Bit := Read_Number;
+ when Name_Size =>
+ Comp.Esize := Read_Numerical_Expr;
+ when others =>
+ Error ("invalid component");
+ end case;
+
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_OBJECT_END then
+ exit;
+ elsif TK /= J_COMMA then
+ Error ("comma expected");
+ end if;
+ end loop;
+
+ -- Compute Component_Bit_Offset from Position and First_Bit,
+ -- either symbolically or literally depending on Position.
+
+ if Position = No_Uint or else First_Bit = No_Uint then
+ Error ("bit offset expected");
+ end if;
+
+ if Position < Uint_0 then
+ declare
+ Bit_Position : constant Node_Ref_Or_Val :=
+ Create_Node (Mult_Expr, Position, UI_From_Int (SSU));
+ begin
+ if First_Bit = Uint_0 then
+ Comp.Bit_Offset := Bit_Position;
+ else
+ Comp.Bit_Offset :=
+ Create_Node (Plus_Expr, Bit_Position, First_Bit);
+ end if;
+ end;
+ else
+ Comp.Bit_Offset := Position * SSU + First_Bit;
+ end if;
+
+ -- Store the component into the table
+
+ JSON_Component_Table.Append (Comp);
+
+ -- Associate the name with the component
+
+ if Nam = No_Name then
+ Error ("name expected");
+ end if;
+
+ Set_Name_Table_Int (Nam, JSON_Component_Table.Last);
+
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_ARRAY_END then
+ exit;
+ elsif TK /= J_COMMA then
+ Error ("comma expected");
+ end if;
+
+ Is_First := False;
+ end loop;
+ end Read_Record;
+
+ ------------------
+ -- Read_String --
+ ------------------
+
+ function Read_String return Valid_Name_Id is
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+ Nam : Valid_Name_Id;
+
+ begin
+ -- Read the string and the following colon
+
+ Read_Token_And_Error (J_STRING, Token_Start, Token_End);
+ Nam := Decode_Name (Token_Start.Index + 1, Token_End.Index - 1);
+ Read_Token_And_Error (J_COLON, Token_Start, Token_End);
+
+ return Nam;
+ end Read_String;
+
+ ------------------
+ -- Read_Token --
+ ------------------
+
+ procedure Read_Token
+ (Kind : out Token_Kind;
+ Token_Start : out Text_Position;
+ Token_End : out Text_Position)
+ is
+ procedure Next_Char;
+ -- Update Pos to point to next char
+
+ function Is_Whitespace return Boolean;
+ pragma Inline (Is_Whitespace);
+ -- Return True of current character is a whitespace
+
+ function Is_Structural_Token return Boolean;
+ pragma Inline (Is_Structural_Token);
+ -- Return True if current character is one of the structural tokens
+
+ function Is_Token_Sep return Boolean;
+ pragma Inline (Is_Token_Sep);
+ -- Return True if current character is a token separator
+
+ procedure Delimit_Keyword (Kw : String);
+ -- Helper function to parse tokens such as null, false and true
+
+ ---------------
+ -- Next_Char --
+ ---------------
+
+ procedure Next_Char is
+ begin
+ if Pos.Index > Text'Last then
+ Pos.Column := Pos.Column + 1;
+ elsif Text (Pos.Index) = ASCII.LF then
+ Pos.Column := 1;
+ Pos.Line := Pos.Line + 1;
+ else
+ Pos.Column := Pos.Column + 1;
+ end if;
+ Pos.Index := Pos.Index + 1;
+ end Next_Char;
+
+ -------------------
+ -- Is_Whitespace --
+ -------------------
+
+ function Is_Whitespace return Boolean is
+ begin
+ return
+ Pos.Index <= Text'Last
+ and then
+ (Text (Pos.Index) = ASCII.LF
+ or else
+ Text (Pos.Index) = ASCII.CR
+ or else
+ Text (Pos.Index) = ASCII.HT
+ or else
+ Text (Pos.Index) = ' ');
+ end Is_Whitespace;
+
+ -------------------------
+ -- Is_Structural_Token --
+ -------------------------
+
+ function Is_Structural_Token return Boolean is
+ begin
+ return
+ Pos.Index <= Text'Last
+ and then
+ (Text (Pos.Index) = '['
+ or else
+ Text (Pos.Index) = ']'
+ or else
+ Text (Pos.Index) = '{'
+ or else
+ Text (Pos.Index) = '}'
+ or else
+ Text (Pos.Index) = ','
+ or else
+ Text (Pos.Index) = ':');
+ end Is_Structural_Token;
+
+ ------------------
+ -- Is_Token_Sep --
+ ------------------
+
+ function Is_Token_Sep return Boolean is
+ begin
+ return
+ Pos.Index > Text'Last
+ or else
+ Is_Whitespace
+ or else
+ Is_Structural_Token;
+ end Is_Token_Sep;
+
+ ---------------------
+ -- Delimit_Keyword --
+ ---------------------
+
+ procedure Delimit_Keyword (Kw : String) is
+ pragma Unreferenced (Kw);
+ begin
+ while not Is_Token_Sep loop
+ Token_End := Pos;
+ Next_Char;
+ end loop;
+ end Delimit_Keyword;
+
+ CC : Character;
+ Can_Be_Integer : Boolean := True;
+
+ -- Start of processing for Read_Token
+
+ begin
+ -- Skip leading whitespaces
+
+ while Is_Whitespace loop
+ Next_Char;
+ end loop;
+
+ -- Initialize token delimiters
+
+ Token_Start := Pos;
+ Token_End := Pos;
+
+ -- End of stream reached
+
+ if Pos.Index > Text'Last then
+ Kind := J_EOF;
+ return;
+ end if;
+
+ CC := Text (Pos.Index);
+
+ if CC = '[' then
+ Next_Char;
+ Kind := J_ARRAY;
+ return;
+ elsif CC = ']' then
+ Next_Char;
+ Kind := J_ARRAY_END;
+ return;
+ elsif CC = '{' then
+ Next_Char;
+ Kind := J_OBJECT;
+ return;
+ elsif CC = '}' then
+ Next_Char;
+ Kind := J_OBJECT_END;
+ return;
+ elsif CC = ',' then
+ Next_Char;
+ Kind := J_COMMA;
+ return;
+ elsif CC = ':' then
+ Next_Char;
+ Kind := J_COLON;
+ return;
+ elsif CC = 'n' then
+ Delimit_Keyword ("null");
+ Kind := J_NULL;
+ return;
+ elsif CC = 'f' then
+ Delimit_Keyword ("false");
+ Kind := J_FALSE;
+ return;
+ elsif CC = 't' then
+ Delimit_Keyword ("true");
+ Kind := J_TRUE;
+ return;
+ elsif CC = '"' then
+ -- We expect a string
+ -- Just scan till the end the of the string but do not attempt
+ -- to decode it. This means that even if we get a string token
+ -- it might not be a valid string from the ECMA 404 point of
+ -- view.
+
+ Next_Char;
+ while Pos.Index <= Text'Last and then Text (Pos.Index) /= '"' loop
+ if Text (Pos.Index) in ASCII.NUL .. ASCII.US then
+ Error ("control character not allowed in string");
+ end if;
+
+ if Text (Pos.Index) = '\' then
+ Next_Char;
+ if Pos.Index > Text'Last then
+ Error ("non terminated string token");
+ end if;
+
+ case Text (Pos.Index) is
+ when 'u' =>
+ for Idx in 1 .. 4 loop
+ Next_Char;
+ if Pos.Index > Text'Last
+ or else (Text (Pos.Index) not in 'a' .. 'f'
+ and then
+ Text (Pos.Index) not in 'A' .. 'F'
+ and then
+ Text (Pos.Index) not in '0' .. '9')
+ then
+ Error ("invalid unicode escape sequence");
+ end if;
+ end loop;
+ when '\' | '/' | '"' | 'b' | 'f' | 'n' | 'r' | 't' =>
+ null;
+ when others =>
+ Error ("invalid escape sequence");
+ end case;
+ end if;
+ Next_Char;
+ end loop;
+
+ -- No quote found report and error
+
+ if Pos.Index > Text'Last then
+ Error ("non terminated string token");
+ end if;
+
+ Token_End := Pos;
+
+ -- Go to next char and ensure that this is separator. Indeed
+ -- construction such as "string1""string2" are not allowed
+
+ Next_Char;
+ if not Is_Token_Sep then
+ Error ("invalid syntax");
+ end if;
+ Kind := J_STRING;
+ return;
+ elsif CC = '-' or else CC in '0' .. '9' then
+ -- We expect a number
+ if CC = '-' then
+ Next_Char;
+ end if;
+
+ if Pos.Index > Text'Last then
+ Error ("invalid number");
+ end if;
+
+ -- Parse integer part of a number. Superfluous leading zeros are
+ -- not allowed.
+
+ if Text (Pos.Index) = '0' then
+ Token_End := Pos;
+ Next_Char;
+ elsif Text (Pos.Index) in '1' .. '9' then
+ Token_End := Pos;
+ Next_Char;
+ while Pos.Index <= Text'Last
+ and then Text (Pos.Index) in '0' .. '9'
+ loop
+ Token_End := Pos;
+ Next_Char;
+ end loop;
+ else
+ Error ("invalid number");
+ end if;
+
+ if Is_Token_Sep then
+ -- Valid integer number
+
+ Kind := J_INTEGER;
+ return;
+ elsif Text (Pos.Index) /= '.'
+ and then Text (Pos.Index) /= 'e'
+ and then Text (Pos.Index) /= 'E'
+ then
+ Error ("invalid number");
+ end if;
+
+ -- Check for a fractional part
+
+ if Text (Pos.Index) = '.' then
+ Can_Be_Integer := False;
+ Token_End := Pos;
+ Next_Char;
+ if Pos.Index > Text'Last
+ or else Text (Pos.Index) not in '0' .. '9'
+ then
+ Error ("invalid number");
+ end if;
+
+ while Pos.Index <= Text'Last
+ and then Text (Pos.Index) in '0' .. '9'
+ loop
+ Token_End := Pos;
+ Next_Char;
+ end loop;
+
+ end if;
+
+ -- Check for exponent part
+
+ if Pos.Index <= Text'Last
+ and then (Text (Pos.Index) = 'e' or else Text (Pos.Index) = 'E')
+ then
+ Token_End := Pos;
+ Next_Char;
+ if Pos.Index > Text'Last then
+ Error ("invalid number");
+ end if;
+
+ if Text (Pos.Index) = '-' then
+ -- Also a few corner cases can lead to an integer, assume
+ -- that the number is not an integer.
+
+ Can_Be_Integer := False;
+ end if;
+
+ if Text (Pos.Index) = '-' or else Text (Pos.Index) = '+' then
+ Next_Char;
+ end if;
+
+ if Pos.Index > Text'Last
+ or else Text (Pos.Index) not in '0' .. '9'
+ then
+ Error ("invalid number");
+ end if;
+
+ while Pos.Index <= Text'Last
+ and then Text (Pos.Index) in '0' .. '9'
+ loop
+ Token_End := Pos;
+ Next_Char;
+ end loop;
+ end if;
+
+ if Is_Token_Sep then
+ -- Valid decimal number
+
+ if Can_Be_Integer then
+ Kind := J_INTEGER;
+ else
+ Kind := J_NUMBER;
+ end if;
+ return;
+ else
+ Error ("invalid number");
+ end if;
+ elsif CC = EOF then
+ Kind := J_EOF;
+ else
+ Error ("Unexpected character");
+ end if;
+ end Read_Token;
+
+ ----------------------------
+ -- Read_Token_And_Error --
+ ----------------------------
+
+ procedure Read_Token_And_Error
+ (TK : Token_Kind;
+ Token_Start : out Text_Position;
+ Token_End : out Text_Position)
+ is
+ Kind : Token_Kind;
+
+ begin
+ -- Read a token and errout out if not of the expected kind
+
+ Read_Token (Kind, Token_Start, Token_End);
+ if Kind /= TK then
+ Error ("specific token expected");
+ end if;
+ end Read_Token_And_Error;
+
+ -------------------------
+ -- Read_Variant_Part --
+ -------------------------
+
+ function Read_Variant_Part return Nat is
+ Next : Nat := 0;
+ TK : Token_Kind;
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+ Var : JSON_Variant_Node;
+
+ begin
+ -- Read a non-empty array of components
+
+ Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);
+
+ loop
+ Read_Token_And_Error (J_OBJECT, Token_Start, Token_End);
+
+ Var.Variant := 0;
+
+ -- Read the members as string : value pairs
+
+ loop
+ case Read_String is
+ when Name_Present =>
+ Var.Present := Read_Numerical_Expr;
+ when Name_Record =>
+ Read_Record;
+ when Name_Variant =>
+ Var.Variant := Read_Variant_Part;
+ when others =>
+ Error ("invalid variant");
+ end case;
+
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_OBJECT_END then
+ exit;
+ elsif TK /= J_COMMA then
+ Error ("comma expected");
+ end if;
+ end loop;
+
+ -- Chain the variant and store it into the table
+
+ Var.Next := Next;
+ JSON_Variant_Table.Append (Var);
+ Next := JSON_Variant_Table.Last;
+
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_ARRAY_END then
+ exit;
+ elsif TK /= J_COMMA then
+ Error ("comma expected");
+ end if;
+ end loop;
+
+ return Next;
+ end Read_Variant_Part;
+
+ ------------------
+ -- Skip_Value --
+ ------------------
+
+ procedure Skip_Value is
+ Array_Depth : Natural := 0;
+ Object_Depth : Natural := 0;
+ TK : Token_Kind;
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+
+ begin
+ -- Read a value without recursing
+
+ loop
+ Read_Token (TK, Token_Start, Token_End);
+
+ case TK is
+ when J_STRING | J_INTEGER | J_NUMBER =>
+ null;
+ when J_ARRAY =>
+ Array_Depth := Array_Depth + 1;
+ when J_ARRAY_END =>
+ Array_Depth := Array_Depth - 1;
+ when J_OBJECT =>
+ Object_Depth := Object_Depth + 1;
+ when J_OBJECT_END =>
+ Object_Depth := Object_Depth - 1;
+ when J_COLON | J_COMMA =>
+ if Array_Depth = 0 and then Object_Depth = 0 then
+ Error ("value expected");
+ end if;
+ when others =>
+ Error ("value expected");
+ end case;
+
+ exit when Array_Depth = 0 and then Object_Depth = 0;
+ end loop;
+ end Skip_Value;
+
+ Token_Start : Text_Position;
+ Token_End : Text_Position;
+ TK : Token_Kind;
+ Is_First : Boolean := True;
+
+ -- Start of processing for Read_JSON_Stream
+
+ begin
+ -- Read a possibly empty array of entities
+
+ Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);
+
+ loop
+ Read_Token (TK, Token_Start, Token_End);
+ if Is_First and then TK = J_ARRAY_END then
+ exit;
+ elsif TK /= J_OBJECT then
+ Error ("object expected");
+ end if;
+
+ Read_Entity;
+
+ Read_Token (TK, Token_Start, Token_End);
+ if TK = J_ARRAY_END then
+ exit;
+ elsif TK /= J_COMMA then
+ Error ("comma expected");
+ end if;
+
+ Is_First := False;
+ end loop;
+ end Read_JSON_Stream;
+
+end Repinfo.Input;
diff --git a/gcc/ada/repinfo-input.ads b/gcc/ada/repinfo-input.ads
new file mode 100644
index 0000000..e418feb
--- /dev/null
+++ b/gcc/ada/repinfo-input.ads
@@ -0,0 +1,78 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- R E P I N F O - I N P U T --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2018-2019, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides an alternate way of populating the internal tables
+-- of Repinfo from a JSON input rather than the binary blob of the tree file.
+-- Note that this is an additive mechanism, i.e. nothing is destroyed in the
+-- internal state of the unit when it is used.
+
+-- The first step is to feed the unit with a JSON stream of a specified format
+-- (see the spec of Repinfo for its description) by means of Read_JSON_Stream.
+-- Then, for each entity whose representation information is present in the
+-- JSON stream, the appropriate Get_JSON_* routines can be invoked to override
+-- the eponymous fields of the entity in the tree.
+
+package Repinfo.Input is
+
+ function Get_JSON_Esize (Name : String) return Node_Ref_Or_Val;
+ -- Returns the Esize value of the entity specified by Name, which is not
+ -- the component of a record type, or else No_Uint if no representation
+ -- information was supplied for the entity. Name is the full qualified name
+ -- of the entity in lower case letters.
+
+ function Get_JSON_RM_Size (Name : String) return Node_Ref_Or_Val;
+ -- Likewise for the RM_Size
+
+ function Get_JSON_Component_Size (Name : String) return Node_Ref_Or_Val;
+ -- Likewise for the Component_Size of an array type
+
+ function Get_JSON_Component_Bit_Offset
+ (Name : String;
+ Record_Name : String) return Node_Ref_Or_Val;
+ -- Returns the Component_Bit_Offset of the component specified by Name,
+ -- which is declared in the record type specified by Record_Name, or else
+ -- No_Uint if no representation information was supplied for the component.
+ -- Name is the unqualified name of the component whereas Record_Name is the
+ -- full qualified name of the record type, both in lower case letters.
+
+ function Get_JSON_Esize
+ (Name : String;
+ Record_Name : String) return Node_Ref_Or_Val;
+ -- Likewise for the Esize
+
+ Invalid_JSON_Stream : exception;
+ -- Raised if a format error is detected in the JSON stream
+
+ procedure Read_JSON_Stream (Text : Text_Buffer; File_Name : String);
+ -- Reads a JSON stream and populates internal tables from it. File_Name is
+ -- only used in error messages issued by the JSON parser.
+
+end Repinfo.Input;
diff --git a/gcc/ada/repinfo.adb b/gcc/ada/repinfo.adb
index 007fe39..77b5c21 100644
--- a/gcc/ada/repinfo.adb
+++ b/gcc/ada/repinfo.adb
@@ -115,10 +115,9 @@ package body Repinfo is
-- Identifier casing for current unit. This is set by List_Rep_Info for
-- each unit, before calling subprograms which may read it.
- Need_Blank_Line : Boolean;
- -- Set True if a blank line is needed before outputting any information for
- -- the current entity. Set True when a new entity is processed, and false
- -- when the blank line is output.
+ Need_Separator : Boolean;
+ -- Set True if a separator is needed before outputting any information for
+ -- the current entity.
------------------------------
-- Set of Relevant Entities --
@@ -151,10 +150,6 @@ package body Repinfo is
-- is used rather than checking the configuration parameter because we do
-- not want Repinfo to depend on Targparm (for ASIS)
- procedure Blank_Line;
- -- Called before outputting anything for an entity. Ensures that
- -- a blank line precedes the output for a particular entity.
-
procedure List_Entities
(Ent : Entity_Id;
Bytes_Big_Endian : Boolean;
@@ -172,6 +167,9 @@ package body Repinfo is
procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean);
-- List representation info for array type Ent
+ procedure List_Common_Type_Info (Ent : Entity_Id);
+ -- List common type info (name, size, alignment) for type Ent
+
procedure List_Linker_Section (Ent : Entity_Id);
-- List linker section for Ent (caller has checked that Ent is an entity
-- for which the Linker_Section_Pragma field is defined).
@@ -179,10 +177,6 @@ package body Repinfo is
procedure List_Location (Ent : Entity_Id);
-- List location information for Ent
- procedure List_Mechanisms (Ent : Entity_Id);
- -- List mechanism information for parameters of Ent, which is subprogram,
- -- subprogram type, or an entry or entry family.
-
procedure List_Object_Info (Ent : Entity_Id);
-- List representation info for object Ent
@@ -195,6 +189,9 @@ package body Repinfo is
-- List scalar storage order information for record or array type Ent.
-- Also includes bit order information for record types, if necessary.
+ procedure List_Subprogram_Info (Ent : Entity_Id);
+ -- List subprogram info for subprogram Ent
+
procedure List_Type_Info (Ent : Entity_Id);
-- List type info for type Ent
@@ -215,6 +212,10 @@ package body Repinfo is
procedure Write_Mechanism (M : Mechanism_Type);
-- Writes symbolic string for mechanism represented by M
+ procedure Write_Separator;
+ -- Called before outputting anything for an entity. Ensures that
+ -- a separator precedes the output for a particular entity.
+
procedure Write_Unknown_Val;
-- Writes symbolic string for an unknown or non-representable value
@@ -236,18 +237,6 @@ package body Repinfo is
return Rep_Table.Last > 0;
end Back_End_Layout;
- ----------------
- -- Blank_Line --
- ----------------
-
- procedure Blank_Line is
- begin
- if Need_Blank_Line then
- Write_Eol;
- Need_Blank_Line := False;
- end if;
- end Blank_Line;
-
------------------------
-- Create_Discrim_Ref --
------------------------
@@ -340,13 +329,13 @@ package body Repinfo is
procedure List_Array_Info (Ent : Entity_Id; Bytes_Big_Endian : Boolean) is
begin
- Blank_Line;
+ Write_Separator;
if List_Representation_Info_To_JSON then
Write_Line ("{");
end if;
- List_Type_Info (Ent);
+ List_Common_Type_Info (Ent);
if List_Representation_Info_To_JSON then
Write_Line (",");
@@ -370,6 +359,81 @@ package body Repinfo is
end if;
end List_Array_Info;
+ ---------------------------
+ -- List_Common_Type_Info --
+ ---------------------------
+
+ procedure List_Common_Type_Info (Ent : Entity_Id) is
+ begin
+ if List_Representation_Info_To_JSON then
+ Write_Str (" ""name"": """);
+ List_Name (Ent);
+ Write_Line (""",");
+ List_Location (Ent);
+ end if;
+
+ -- Do not list size info for unconstrained arrays, not meaningful
+
+ if Is_Array_Type (Ent) and then not Is_Constrained (Ent) then
+ null;
+
+ else
+ -- If Esize and RM_Size are the same, list as Size. This is a common
+ -- case, which we may as well list in simple form.
+
+ if Esize (Ent) = RM_Size (Ent) then
+ if List_Representation_Info_To_JSON then
+ Write_Str (" ""Size"": ");
+ Write_Val (Esize (Ent));
+ Write_Line (",");
+ else
+ Write_Str ("for ");
+ List_Name (Ent);
+ Write_Str ("'Size use ");
+ Write_Val (Esize (Ent));
+ Write_Line (";");
+ end if;
+
+ -- Otherwise list size values separately
+
+ else
+ if List_Representation_Info_To_JSON then
+ Write_Str (" ""Object_Size"": ");
+ Write_Val (Esize (Ent));
+ Write_Line (",");
+
+ Write_Str (" ""Value_Size"": ");
+ Write_Val (RM_Size (Ent));
+ Write_Line (",");
+
+ else
+ Write_Str ("for ");
+ List_Name (Ent);
+ Write_Str ("'Object_Size use ");
+ Write_Val (Esize (Ent));
+ Write_Line (";");
+
+ Write_Str ("for ");
+ List_Name (Ent);
+ Write_Str ("'Value_Size use ");
+ Write_Val (RM_Size (Ent));
+ Write_Line (";");
+ end if;
+ end if;
+ end if;
+
+ if List_Representation_Info_To_JSON then
+ Write_Str (" ""Alignment"": ");
+ Write_Val (Alignment (Ent));
+ else
+ Write_Str ("for ");
+ List_Name (Ent);
+ Write_Str ("'Alignment use ");
+ Write_Val (Alignment (Ent));
+ Write_Line (";");
+ end if;
+ end List_Common_Type_Info;
+
-------------------
-- List_Entities --
-------------------
@@ -427,14 +491,11 @@ package body Repinfo is
or else Ekind (Ent) = E_Entry_Family)
and then not In_Subprogram
then
- Need_Blank_Line := True;
- List_Mechanisms (Ent);
+ List_Subprogram_Info (Ent);
end if;
E := First_Entity (Ent);
while Present (E) loop
- Need_Blank_Line := True;
-
-- We list entities that come from source (excluding private or
-- incomplete types or deferred constants, for which we will list
-- the information for the full view). If requested, we also list
@@ -457,22 +518,19 @@ package body Repinfo is
then
if Is_Subprogram (E) then
if List_Representation_Info_Mechanisms then
- List_Mechanisms (E);
+ List_Subprogram_Info (E);
end if;
-- Recurse into entities local to subprogram
List_Entities (E, Bytes_Big_Endian, True);
- elsif Is_Formal (E) and then In_Subprogram then
- null;
-
elsif Ekind_In (E, E_Entry,
E_Entry_Family,
E_Subprogram_Type)
then
if List_Representation_Info_Mechanisms then
- List_Mechanisms (E);
+ List_Subprogram_Info (E);
end if;
elsif Is_Record_Type (E) then
@@ -496,24 +554,22 @@ package body Repinfo is
elsif Is_Type (E) then
if List_Representation_Info >= 2 then
- Blank_Line;
- if List_Representation_Info_To_JSON then
- Write_Line ("{");
- end if;
List_Type_Info (E);
- List_Linker_Section (E);
- if List_Representation_Info_To_JSON then
- Write_Eol;
- Write_Line ("}");
- end if;
end if;
- elsif Ekind_In (E, E_Variable, E_Constant) then
- if List_Representation_Info >= 2 then
- List_Object_Info (E);
+ -- Note that formals are not annotated so we skip them here
+
+ elsif Ekind_In (E, E_Constant,
+ E_Loop_Parameter,
+ E_Variable)
+ then
+ -- The type is relevant for an object
+
+ if List_Representation_Info = 4 and then Is_Itype (Etype (E))
+ then
+ Relevant_Entities.Set (Etype (E), True);
end if;
- elsif Ekind (E) = E_Loop_Parameter or else Is_Formal (E) then
if List_Representation_Info >= 2 then
List_Object_Info (E);
end if;
@@ -530,12 +586,12 @@ package body Repinfo is
-- Recurse into bodies
- elsif Ekind_In (E, E_Protected_Type,
- E_Task_Type,
+ elsif Ekind_In (E, E_Package_Body,
+ E_Protected_Body,
+ E_Protected_Type,
E_Subprogram_Body,
- E_Package_Body,
E_Task_Body,
- E_Protected_Body)
+ E_Task_Type)
then
List_Entities (E, Bytes_Big_Endian);
@@ -842,193 +898,13 @@ package body Repinfo is
Write_Line (""",");
end List_Location;
- ---------------------
- -- List_Mechanisms --
- ---------------------
-
- procedure List_Mechanisms (Ent : Entity_Id) is
- First : Boolean := True;
- Plen : Natural;
- Form : Entity_Id;
-
- begin
- Blank_Line;
-
- if List_Representation_Info_To_JSON then
- Write_Line ("{");
- Write_Str (" ""name"": """);
- List_Name (Ent);
- Write_Line (""",");
- List_Location (Ent);
-
- Write_Str (" ""Convention"": """);
- else
- case Ekind (Ent) is
- when E_Function =>
- Write_Str ("function ");
-
- when E_Operator =>
- Write_Str ("operator ");
-
- when E_Procedure =>
- Write_Str ("procedure ");
-
- when E_Subprogram_Type =>
- Write_Str ("type ");
-
- when E_Entry
- | E_Entry_Family
- =>
- Write_Str ("entry ");
-
- when others =>
- raise Program_Error;
- end case;
-
- List_Name (Ent);
- Write_Str (" declared at ");
- Write_Location (Sloc (Ent));
- Write_Eol;
-
- Write_Str ("convention : ");
- end if;
-
- case Convention (Ent) is
- when Convention_Ada =>
- Write_Str ("Ada");
-
- when Convention_Ada_Pass_By_Copy =>
- Write_Str ("Ada_Pass_By_Copy");
-
- when Convention_Ada_Pass_By_Reference =>
- Write_Str ("Ada_Pass_By_Reference");
-
- when Convention_Intrinsic =>
- Write_Str ("Intrinsic");
-
- when Convention_Entry =>
- Write_Str ("Entry");
-
- when Convention_Protected =>
- Write_Str ("Protected");
-
- when Convention_Assembler =>
- Write_Str ("Assembler");
-
- when Convention_C =>
- Write_Str ("C");
-
- when Convention_COBOL =>
- Write_Str ("COBOL");
-
- when Convention_CPP =>
- Write_Str ("C++");
-
- when Convention_Fortran =>
- Write_Str ("Fortran");
-
- when Convention_Stdcall =>
- Write_Str ("Stdcall");
-
- when Convention_Stubbed =>
- Write_Str ("Stubbed");
- end case;
-
- if List_Representation_Info_To_JSON then
- Write_Line (""",");
- Write_Str (" ""formal"": [");
- else
- Write_Eol;
- end if;
-
- -- Find max length of formal name
-
- Plen := 0;
- Form := First_Formal (Ent);
- while Present (Form) loop
- Get_Unqualified_Decoded_Name_String (Chars (Form));
-
- if Name_Len > Plen then
- Plen := Name_Len;
- end if;
-
- Next_Formal (Form);
- end loop;
-
- -- Output formals and mechanisms
-
- Form := First_Formal (Ent);
- while Present (Form) loop
- Get_Unqualified_Decoded_Name_String (Chars (Form));
- Set_Casing (Unit_Casing);
-
- if List_Representation_Info_To_JSON then
- if First then
- Write_Eol;
- First := False;
- else
- Write_Line (",");
- end if;
-
- Write_Line (" {");
- Write_Str (" ""name"": """);
- Write_Str (Name_Buffer (1 .. Name_Len));
- Write_Line (""",");
-
- Write_Str (" ""mechanism"": """);
- Write_Mechanism (Mechanism (Form));
- Write_Line ("""");
- Write_Str (" }");
- else
- while Name_Len <= Plen loop
- Name_Len := Name_Len + 1;
- Name_Buffer (Name_Len) := ' ';
- end loop;
-
- Write_Str (" ");
- Write_Str (Name_Buffer (1 .. Plen + 1));
- Write_Str (": passed by ");
-
- Write_Mechanism (Mechanism (Form));
- Write_Eol;
- end if;
-
- Next_Formal (Form);
- end loop;
-
- if List_Representation_Info_To_JSON then
- Write_Eol;
- Write_Str (" ]");
- end if;
-
- if Ekind (Ent) = E_Function then
- if List_Representation_Info_To_JSON then
- Write_Line (",");
- Write_Str (" ""mechanism"": """);
- Write_Mechanism (Mechanism (Ent));
- Write_Str ("""");
- else
- Write_Str ("returns by ");
- Write_Mechanism (Mechanism (Ent));
- Write_Eol;
- end if;
- end if;
-
- if not Is_Entry (Ent) then
- List_Linker_Section (Ent);
- end if;
-
- if List_Representation_Info_To_JSON then
- Write_Eol;
- Write_Line ("}");
- end if;
- end List_Mechanisms;
-
---------------
-- List_Name --
---------------
procedure List_Name (Ent : Entity_Id) is
+ C : Character;
+
begin
-- List the qualified name recursively, except
-- at compilation unit level in default mode.
@@ -1044,7 +920,16 @@ package body Repinfo is
Get_Unqualified_Decoded_Name_String (Chars (Ent));
Set_Casing (Unit_Casing);
- Write_Str (Name_Buffer (1 .. Name_Len));
+
+ -- The name of operators needs to be properly escaped for JSON
+
+ for J in 1 .. Name_Len loop
+ C := Name_Buffer (J);
+ if C = '"' and then List_Representation_Info_To_JSON then
+ Write_Char ('\');
+ end if;
+ Write_Char (C);
+ end loop;
end List_Name;
---------------------
@@ -1053,7 +938,7 @@ package body Repinfo is
procedure List_Object_Info (Ent : Entity_Id) is
begin
- Blank_Line;
+ Write_Separator;
if List_Representation_Info_To_JSON then
Write_Line ("{");
@@ -1125,6 +1010,12 @@ package body Repinfo is
Indent : Natural := 0);
-- Internal recursive procedure to display the structural layout
+ Incomplete_Layout : exception;
+ -- Exception raised if the layout is incomplete in -gnatc mode
+
+ Not_In_Extended_Main : exception;
+ -- Exception raised when an ancestor is not declared in the main unit
+
Max_Name_Length : Natural := 0;
Max_Spos_Length : Natural := 0;
@@ -1259,7 +1150,7 @@ package body Repinfo is
if Ekind (Ent) = E_Discriminant then
Spaces (Indent);
Write_Str (" ""discriminant"": ");
- UI_Write (Discriminant_Number (Ent));
+ UI_Write (Discriminant_Number (Ent), Decimal);
Write_Line (",");
end if;
Spaces (Indent);
@@ -1290,7 +1181,7 @@ package body Repinfo is
Spaces (Max_Spos_Length - 2);
if Starting_Position /= Uint_0 then
- UI_Write (Starting_Position);
+ UI_Write (Starting_Position, Decimal);
Write_Str (" + ");
end if;
@@ -1314,7 +1205,7 @@ package body Repinfo is
Sbit := Sbit - SSU;
end if;
- UI_Write (Sbit);
+ UI_Write (Sbit, Decimal);
if List_Representation_Info_To_JSON then
Write_Line (", ");
@@ -1336,13 +1227,13 @@ package body Repinfo is
Lbit := Sbit + Esiz - 1;
if List_Representation_Info_To_JSON then
- UI_Write (Esiz);
+ UI_Write (Esiz, Decimal);
else
if Lbit >= 0 and then Lbit < 10 then
Write_Char (' ');
end if;
- UI_Write (Lbit);
+ UI_Write (Lbit, Decimal);
end if;
-- The test for Esize (Ent) not Uint_0 here is an annoying special
@@ -1564,14 +1455,29 @@ package body Repinfo is
Disc : Entity_Id;
Listed_Disc : Entity_Id;
+ Parent_Type : Entity_Id;
begin
-- If this is an extension, first list the layout of the parent
-- and then proceed to the extension part, if any.
if Is_Extension then
- List_Structural_Record_Layout
- (Base_Type (Parent_Subtype (Ent)), Outer_Ent);
+ Parent_Type := Parent_Subtype (Ent);
+ if No (Parent_Type) then
+ raise Incomplete_Layout;
+ end if;
+
+ if Is_Private_Type (Parent_Type) then
+ Parent_Type := Full_View (Parent_Type);
+ pragma Assert (Present (Parent_Type));
+ end if;
+
+ Parent_Type := Base_Type (Parent_Type);
+ if not In_Extended_Main_Source_Unit (Parent_Type) then
+ raise Not_In_Extended_Main;
+ end if;
+
+ List_Structural_Record_Layout (Parent_Type, Outer_Ent);
First := False;
if Present (Record_Extension_Part (Definition)) then
@@ -1714,13 +1620,13 @@ package body Repinfo is
-- Start of processing for List_Record_Info
begin
- Blank_Line;
+ Write_Separator;
if List_Representation_Info_To_JSON then
Write_Line ("{");
end if;
- List_Type_Info (Ent);
+ List_Common_Type_Info (Ent);
-- First find out max line length and max starting position
-- length, for the purpose of lining things up nicely.
@@ -1733,8 +1639,23 @@ package body Repinfo is
Write_Line (",");
Write_Str (" ""record"": [");
+ -- ??? We can output structural layout only for base types fully
+ -- declared in the extended main source unit for the time being,
+ -- because otherwise declarations might not be processed at all.
+
if Is_Base_Type (Ent) then
- List_Structural_Record_Layout (Ent, Ent);
+ begin
+ List_Structural_Record_Layout (Ent, Ent);
+
+ exception
+ when Incomplete_Layout
+ | Not_In_Extended_Main
+ =>
+ List_Record_Layout (Ent);
+
+ when others =>
+ raise Program_Error;
+ end;
else
List_Record_Layout (Ent);
end if;
@@ -1772,6 +1693,15 @@ package body Repinfo is
if List_Representation_Info /= 0
or else List_Representation_Info_Mechanisms
then
+ -- For the normal case, we output a single JSON stream
+
+ if not List_Representation_Info_To_File
+ and then List_Representation_Info_To_JSON
+ then
+ Write_Line ("[");
+ Need_Separator := False;
+ end if;
+
for U in Main_Unit .. Last_Unit loop
if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
Unit_Casing := Identifier_Casing (Source_Index (U));
@@ -1795,6 +1725,7 @@ package body Repinfo is
end loop;
Write_Eol;
+ Need_Separator := True;
end if;
List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
@@ -1805,12 +1736,25 @@ package body Repinfo is
Create_Repinfo_File_Access.all
(Get_Name_String (File_Name (Source_Index (U))));
Set_Special_Output (Write_Info_Line'Access);
+ if List_Representation_Info_To_JSON then
+ Write_Line ("[");
+ end if;
+ Need_Separator := False;
List_Entities (Cunit_Entity (U), Bytes_Big_Endian);
+ if List_Representation_Info_To_JSON then
+ Write_Line ("]");
+ end if;
Cancel_Special_Output;
Close_Repinfo_File_Access.all;
end if;
end if;
end loop;
+
+ if not List_Representation_Info_To_File
+ and then List_Representation_Info_To_JSON
+ then
+ Write_Line ("]");
+ end if;
end if;
end List_Rep_Info;
@@ -1889,79 +1833,201 @@ package body Repinfo is
end if;
end List_Scalar_Storage_Order;
- --------------------
- -- List_Type_Info --
- --------------------
+ --------------------------
+ -- List_Subprogram_Info --
+ --------------------------
+
+ procedure List_Subprogram_Info (Ent : Entity_Id) is
+ First : Boolean := True;
+ Plen : Natural;
+ Form : Entity_Id;
- procedure List_Type_Info (Ent : Entity_Id) is
begin
+ Write_Separator;
+
if List_Representation_Info_To_JSON then
+ Write_Line ("{");
Write_Str (" ""name"": """);
List_Name (Ent);
Write_Line (""",");
List_Location (Ent);
+
+ Write_Str (" ""Convention"": """);
+ else
+ case Ekind (Ent) is
+ when E_Function =>
+ Write_Str ("function ");
+
+ when E_Operator =>
+ Write_Str ("operator ");
+
+ when E_Procedure =>
+ Write_Str ("procedure ");
+
+ when E_Subprogram_Type =>
+ Write_Str ("type ");
+
+ when E_Entry
+ | E_Entry_Family
+ =>
+ Write_Str ("entry ");
+
+ when others =>
+ raise Program_Error;
+ end case;
+
+ List_Name (Ent);
+ Write_Str (" declared at ");
+ Write_Location (Sloc (Ent));
+ Write_Eol;
+
+ Write_Str ("convention : ");
end if;
- -- Do not list size info for unconstrained arrays, not meaningful
+ case Convention (Ent) is
+ when Convention_Ada =>
+ Write_Str ("Ada");
- if Is_Array_Type (Ent) and then not Is_Constrained (Ent) then
- null;
+ when Convention_Ada_Pass_By_Copy =>
+ Write_Str ("Ada_Pass_By_Copy");
+
+ when Convention_Ada_Pass_By_Reference =>
+ Write_Str ("Ada_Pass_By_Reference");
+
+ when Convention_Intrinsic =>
+ Write_Str ("Intrinsic");
+
+ when Convention_Entry =>
+ Write_Str ("Entry");
+
+ when Convention_Protected =>
+ Write_Str ("Protected");
+ when Convention_Assembler =>
+ Write_Str ("Assembler");
+
+ when Convention_C =>
+ Write_Str ("C");
+
+ when Convention_COBOL =>
+ Write_Str ("COBOL");
+
+ when Convention_CPP =>
+ Write_Str ("C++");
+
+ when Convention_Fortran =>
+ Write_Str ("Fortran");
+
+ when Convention_Stdcall =>
+ Write_Str ("Stdcall");
+
+ when Convention_Stubbed =>
+ Write_Str ("Stubbed");
+ end case;
+
+ if List_Representation_Info_To_JSON then
+ Write_Line (""",");
+ Write_Str (" ""formal"": [");
else
- -- If Esize and RM_Size are the same, list as Size. This is a common
- -- case, which we may as well list in simple form.
+ Write_Eol;
+ end if;
- if Esize (Ent) = RM_Size (Ent) then
- if List_Representation_Info_To_JSON then
- Write_Str (" ""Size"": ");
- Write_Val (Esize (Ent));
- Write_Line (",");
+ -- Find max length of formal name
+
+ Plen := 0;
+ Form := First_Formal (Ent);
+ while Present (Form) loop
+ Get_Unqualified_Decoded_Name_String (Chars (Form));
+
+ if Name_Len > Plen then
+ Plen := Name_Len;
+ end if;
+
+ Next_Formal (Form);
+ end loop;
+
+ -- Output formals and mechanisms
+
+ Form := First_Formal (Ent);
+ while Present (Form) loop
+ Get_Unqualified_Decoded_Name_String (Chars (Form));
+ Set_Casing (Unit_Casing);
+
+ if List_Representation_Info_To_JSON then
+ if First then
+ Write_Eol;
+ First := False;
else
- Write_Str ("for ");
- List_Name (Ent);
- Write_Str ("'Size use ");
- Write_Val (Esize (Ent));
- Write_Line (";");
+ Write_Line (",");
end if;
- -- Otherwise list size values separately
+ Write_Line (" {");
+ Write_Str (" ""name"": """);
+ Write_Str (Name_Buffer (1 .. Name_Len));
+ Write_Line (""",");
+ Write_Str (" ""mechanism"": """);
+ Write_Mechanism (Mechanism (Form));
+ Write_Line ("""");
+ Write_Str (" }");
else
- if List_Representation_Info_To_JSON then
- Write_Str (" ""Object_Size"": ");
- Write_Val (Esize (Ent));
- Write_Line (",");
+ while Name_Len <= Plen loop
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := ' ';
+ end loop;
- Write_Str (" ""Value_Size"": ");
- Write_Val (RM_Size (Ent));
- Write_Line (",");
+ Write_Str (" ");
+ Write_Str (Name_Buffer (1 .. Plen + 1));
+ Write_Str (": passed by ");
- else
- Write_Str ("for ");
- List_Name (Ent);
- Write_Str ("'Object_Size use ");
- Write_Val (Esize (Ent));
- Write_Line (";");
+ Write_Mechanism (Mechanism (Form));
+ Write_Eol;
+ end if;
- Write_Str ("for ");
- List_Name (Ent);
- Write_Str ("'Value_Size use ");
- Write_Val (RM_Size (Ent));
- Write_Line (";");
- end if;
+ Next_Formal (Form);
+ end loop;
+
+ if List_Representation_Info_To_JSON then
+ Write_Eol;
+ Write_Str (" ]");
+ end if;
+
+ if Ekind (Ent) = E_Function then
+ if List_Representation_Info_To_JSON then
+ Write_Line (",");
+ Write_Str (" ""mechanism"": """);
+ Write_Mechanism (Mechanism (Ent));
+ Write_Str ("""");
+ else
+ Write_Str ("returns by ");
+ Write_Mechanism (Mechanism (Ent));
+ Write_Eol;
end if;
end if;
+ if not Is_Entry (Ent) then
+ List_Linker_Section (Ent);
+ end if;
+
if List_Representation_Info_To_JSON then
- Write_Str (" ""Alignment"": ");
- Write_Val (Alignment (Ent));
- else
- Write_Str ("for ");
- List_Name (Ent);
- Write_Str ("'Alignment use ");
- Write_Val (Alignment (Ent));
- Write_Line (";");
+ Write_Eol;
+ Write_Line ("}");
end if;
+ end List_Subprogram_Info;
+
+ --------------------
+ -- List_Type_Info --
+ --------------------
+
+ procedure List_Type_Info (Ent : Entity_Id) is
+ begin
+ Write_Separator;
+
+ if List_Representation_Info_To_JSON then
+ Write_Line ("{");
+ end if;
+
+ List_Common_Type_Info (Ent);
-- Special stuff for fixed-point
@@ -2010,6 +2076,13 @@ package body Repinfo is
end if;
end;
end if;
+
+ List_Linker_Section (Ent);
+
+ if List_Representation_Info_To_JSON then
+ Write_Eol;
+ Write_Line ("}");
+ end if;
end List_Type_Info;
----------------------
@@ -2284,6 +2357,23 @@ package body Repinfo is
end case;
end Write_Mechanism;
+ ---------------------
+ -- Write_Separator --
+ ---------------------
+
+ procedure Write_Separator is
+ begin
+ if Need_Separator then
+ if List_Representation_Info_To_JSON then
+ Write_Line (",");
+ else
+ Write_Eol;
+ end if;
+ else
+ Need_Separator := True;
+ end if;
+ end Write_Separator;
+
-----------------------
-- Write_Unknown_Val --
-----------------------
@@ -2324,7 +2414,7 @@ package body Repinfo is
end if;
else
- UI_Write (Val);
+ UI_Write (Val, Decimal);
end if;
end Write_Val;
diff --git a/gcc/ada/repinfo.ads b/gcc/ada/repinfo.ads
index c013721..c51948e 100644
--- a/gcc/ada/repinfo.ads
+++ b/gcc/ada/repinfo.ads
@@ -193,7 +193,7 @@ package Repinfo is
-- following description, the terminology is that of the JSON syntax
-- from the ECMA document and of the JSON grammar from www.json.org.
- -- The output is a concatenation of entities
+ -- The output is an array of entities
-- An entity is an object whose members are pairs taken from:
diff --git a/gcc/ada/rtinit.c b/gcc/ada/rtinit.c
index 13bd595..5c9c5ec 100644
--- a/gcc/ada/rtinit.c
+++ b/gcc/ada/rtinit.c
@@ -41,8 +41,6 @@
#endif
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
/* We don't have libiberty, so use malloc. */
#define xmalloc(S) malloc (S)
#define xrealloc(V,S) realloc (V,S)
@@ -62,7 +60,7 @@ extern "C" {
/* __gnat_runtime_initialize (NT-mingw32 Version) */
/**************************************************/
-extern void __gnat_install_handler(void);
+extern void __gnat_install_handler (void);
int __gnat_wide_text_translation_required = 0;
/* wide text translation, 0=none, 1=activated */
@@ -89,6 +87,189 @@ extern HANDLE ProcListEvt;
int __gnat_do_argv_expansion = 1;
#pragma weak __gnat_do_argv_expansion
+/* Assuming we are pointing to the beginning of a quoted part of an
+argument, skip until the end of the quoted part. */
+static void skip_quoted_string (const WCHAR **current_in,
+ WCHAR **current_out)
+{
+ /* Number of backslashes buffered. */
+ int qbs_count = 0;
+
+ /* Pointer to current input character. */
+ const WCHAR *ci = *current_in;
+
+ /* Pointer to next output character. */
+ WCHAR *co = *current_out;
+
+ /* Skip initial quote. */
+ ci++;
+
+ while (*ci)
+ {
+ if (*ci == '\\')
+ {
+ /* Buffer incoming backslashes. */
+ qbs_count++;
+ }
+ else if (*ci == '"')
+ {
+ /* Append qbs_count / 2 backslahes. */
+ for (int i=0; i<qbs_count / 2; i++)
+ {
+ *co = '\\';
+ co++;
+ }
+ if ((qbs_count & 1) == 0)
+ {
+ /* 2n backslashes means that the quotation mark is the end of
+ the quoted portion. */
+ qbs_count = 0;
+ break;
+ }
+ else
+ {
+ /* Otherwise this is a double quote literal. */
+ qbs_count = 0;
+ *co = '"'; co++;
+ }
+ }
+ else
+ {
+ /* If the character is not a double quote we should append
+ qbs_count backslashes. */
+ for (int i=0; i<qbs_count; i++)
+ {
+ *co = '\\';
+ co++;
+ }
+ *co = *ci; co++;
+ qbs_count = 0;
+ }
+ ci++;
+ }
+ *current_in = ci;
+ *current_out = co;
+}
+
+/* Assuming that this is the beginning of an argument. Skip characters
+ until we reach the character right after the last argument character. */
+static void skip_argument (const WCHAR **current_in,
+ WCHAR **current_out)
+{
+ /* Number of backslashes buffered. */
+ int bs_count = 0;
+
+ /* Pointer to current input character. */
+ const WCHAR *ci = *current_in;
+
+ /* Pointer to next output character. */
+ WCHAR *co = *current_out;
+
+ while (*ci && ! (*ci == ' ' || *ci == '\t'))
+ {
+ if (*ci == '\\')
+ {
+ /* Buffer incoming backslashes. */
+ bs_count++;
+ }
+ else if (*ci == '"')
+ {
+ /* Append qbs_count / 2 backslahes. */
+ for (int i=0; i< bs_count / 2; i++)
+ {
+ *co = '\\'; co++;
+ }
+ if ((bs_count & 1) == 0)
+ {
+ /* 2n backslashes followed by a quotation mark means that
+ this is a start of a quoted string. */
+ skip_quoted_string (&ci, &co);
+ }
+ else
+ {
+ /* Otherwise this is quotation mark literal. */
+ *co = '"';
+ co++;
+ }
+ bs_count = 0;
+ }
+ else
+ {
+ /* This is a regular character. */
+ /* Backslashes are interpreted literally. */
+ for (int i=0; i<bs_count; i++)
+ {
+ *co = '\\';
+ co++;
+ }
+ bs_count = 0;
+ *co = *ci; co++;
+ }
+ ci++;
+ }
+
+ for (int i=0; i<bs_count; i++)
+ {
+ *co = '\\';
+ co++;
+ }
+
+ /* End the argument with a null character. */
+ *co = '\0';
+ co++;
+
+ *current_in = ci;
+ *current_out = co;
+}
+
+
+void __gnat_get_argw (const WCHAR *command_line, WCHAR ***argv, int *argc)
+{
+ WCHAR *inline_argv;
+ WCHAR *co;
+ int arg_count = 1;
+ const WCHAR *ci;
+
+ inline_argv =
+ (WCHAR *) xmalloc ((wcslen (command_line) + 1) * sizeof (WCHAR));
+ co = inline_argv;
+
+ /* Start iteration on command line characters. */
+ ci = command_line;
+
+ /* Skip command name. Note that if the command line starts with whitechars
+ then the command name will be the empty string. */
+ skip_argument (&ci, &co);
+
+ /* Count remaining arguments. */
+ while (*ci)
+ {
+ /* skip whitechar */
+ while (*ci && (*ci == ' ' || *ci == '\t')) { ci++; }
+ if (*ci)
+ {
+ skip_argument (&ci, &co);
+ arg_count++;
+ }
+ else
+ break;
+ }
+
+ /* Allocate table with pointer to each arguments */
+ argv[0] = (WCHAR **) xmalloc (arg_count * sizeof (WCHAR *));
+
+ for (int idx = 0; idx < arg_count; idx++)
+ {
+ argv[0][idx] = inline_argv;
+ while (*inline_argv)
+ {
+ inline_argv++;
+ }
+ inline_argv++;
+ }
+ *argc = arg_count;
+}
+
static void
append_arg (int *index, LPWSTR dir, LPWSTR value,
char ***argv, int *last, int quoted)
@@ -102,14 +283,14 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
{
/* no dir prefix */
dirlen = 0;
- fullvalue = (LPWSTR) xmalloc ((vallen + 1) * sizeof(TCHAR));
+ fullvalue = (LPWSTR) xmalloc ((vallen + 1) * sizeof (TCHAR));
}
else
{
/* Add dir first */
dirlen = _tcslen (dir);
- fullvalue = (LPWSTR) xmalloc ((dirlen + vallen + 1) * sizeof(TCHAR));
+ fullvalue = (LPWSTR) xmalloc ((dirlen + vallen + 1) * sizeof (TCHAR));
_tcscpy (fullvalue, dir);
}
@@ -118,7 +299,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
if (quoted)
{
_tcsncpy (fullvalue + dirlen, value + 1, vallen - 1);
- fullvalue [dirlen + vallen - sizeof(TCHAR)] = _T('\0');
+ fullvalue [dirlen + vallen - sizeof (TCHAR)] = _T ('\0');
}
else
_tcscpy (fullvalue + dirlen, value);
@@ -130,7 +311,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
}
size = WS2SC (NULL, fullvalue, 0);
- (*argv)[*index] = (char *) xmalloc (size + sizeof(TCHAR));
+ (*argv)[*index] = (char *) xmalloc (size + sizeof (TCHAR));
WS2SC ((*argv)[*index], fullvalue, size);
free (fullvalue);
@@ -140,7 +321,7 @@ append_arg (int *index, LPWSTR dir, LPWSTR value,
#endif
void
-__gnat_runtime_initialize(int install_handler)
+__gnat_runtime_initialize (int install_handler)
{
/* increment the reference counter */
@@ -223,7 +404,7 @@ __gnat_runtime_initialize(int install_handler)
TCHAR result [MAX_PATH];
int quoted;
- wargv = CommandLineToArgvW (GetCommandLineW(), &wargc);
+ __gnat_get_argw (GetCommandLineW (), &wargv, &wargc);
if (wargv != NULL)
{
@@ -297,7 +478,8 @@ __gnat_runtime_initialize(int install_handler)
}
}
- LocalFree (wargv);
+ free (wargv[0]);
+ free (wargv);
gnat_argc = argc_expanded;
gnat_argv = (char **) xrealloc
(gnat_argv, argc_expanded * sizeof (char *));
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 47ad874..eab6f4f 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -2755,23 +2755,23 @@ package Rtsfind is
RE_W_WC => System_Stream_Attributes,
RE_W_WWC => System_Stream_Attributes,
- RE_Storage_Array_Input => System_Strings_Stream_Ops,
- RE_Storage_Array_Input_Blk_IO => System_Strings_Stream_Ops,
- RE_Storage_Array_Output => System_Strings_Stream_Ops,
- RE_Storage_Array_Output_Blk_IO => System_Strings_Stream_Ops,
- RE_Storage_Array_Read => System_Strings_Stream_Ops,
- RE_Storage_Array_Read_Blk_IO => System_Strings_Stream_Ops,
- RE_Storage_Array_Write => System_Strings_Stream_Ops,
- RE_Storage_Array_Write_Blk_IO => System_Strings_Stream_Ops,
-
- RE_Stream_Element_Array_Input => System_Strings_Stream_Ops,
- RE_Stream_Element_Array_Input_Blk_IO => System_Strings_Stream_Ops,
- RE_Stream_Element_Array_Output => System_Strings_Stream_Ops,
- RE_Stream_Element_Array_Output_Blk_IO => System_Strings_Stream_Ops,
- RE_Stream_Element_Array_Read => System_Strings_Stream_Ops,
- RE_Stream_Element_Array_Read_Blk_IO => System_Strings_Stream_Ops,
- RE_Stream_Element_Array_Write => System_Strings_Stream_Ops,
- RE_Stream_Element_Array_Write_Blk_IO => System_Strings_Stream_Ops,
+ RE_Storage_Array_Input => System_Strings_Stream_Ops,
+ RE_Storage_Array_Input_Blk_IO => System_Strings_Stream_Ops,
+ RE_Storage_Array_Output => System_Strings_Stream_Ops,
+ RE_Storage_Array_Output_Blk_IO => System_Strings_Stream_Ops,
+ RE_Storage_Array_Read => System_Strings_Stream_Ops,
+ RE_Storage_Array_Read_Blk_IO => System_Strings_Stream_Ops,
+ RE_Storage_Array_Write => System_Strings_Stream_Ops,
+ RE_Storage_Array_Write_Blk_IO => System_Strings_Stream_Ops,
+
+ RE_Stream_Element_Array_Input => System_Strings_Stream_Ops,
+ RE_Stream_Element_Array_Input_Blk_IO => System_Strings_Stream_Ops,
+ RE_Stream_Element_Array_Output => System_Strings_Stream_Ops,
+ RE_Stream_Element_Array_Output_Blk_IO => System_Strings_Stream_Ops,
+ RE_Stream_Element_Array_Read => System_Strings_Stream_Ops,
+ RE_Stream_Element_Array_Read_Blk_IO => System_Strings_Stream_Ops,
+ RE_Stream_Element_Array_Write => System_Strings_Stream_Ops,
+ RE_Stream_Element_Array_Write_Blk_IO => System_Strings_Stream_Ops,
RE_String_Input => System_Strings_Stream_Ops,
RE_String_Input_Blk_IO => System_Strings_Stream_Ops,
diff --git a/gcc/ada/runtime.h b/gcc/ada/runtime.h
new file mode 100644
index 0000000..df42730
--- /dev/null
+++ b/gcc/ada/runtime.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ * *
+ * GNAT COMPILER COMPONENTS *
+ * *
+ * RUNTIME *
+ * *
+ * C Header File *
+ * *
+ * Copyright (C) 2019, Free Software Foundation, Inc. *
+ * *
+ * GNAT is free software; you can redistribute it and/or modify it under *
+ * terms of the GNU General Public License as published by the Free Soft- *
+ * ware Foundation; either version 3, or (at your option) any later ver- *
+ * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
+ * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
+ * or FITNESS FOR A PARTICULAR PURPOSE. *
+ * *
+ * As a special exception under Section 7 of GPL version 3, you are granted *
+ * additional permissions described in the GCC Runtime Library Exception, *
+ * version 3.1, as published by the Free Software Foundation. *
+ * *
+ * You should have received a copy of the GNU General Public License and *
+ * a copy of the GCC Runtime Library Exception along with this program; *
+ * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
+ * <http://www.gnu.org/licenses/>. *
+ * *
+ * GNAT was originally developed by the GNAT team at New York University. *
+ * Extensive contributions were provided by Ada Core Technologies Inc. *
+ * *
+ ****************************************************************************/
+
+/* This file provides common definitions used by GNAT C runtime files. */
+
+#ifdef __vxworks
+#include "vxWorks.h"
+#endif /* __vxworks */
+
+#ifndef ATTRIBUTE_UNUSED
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+#endif
+
+#ifndef ATTRIBUTE_NORETURN
+#define ATTRIBUTE_NORETURN __attribute__((noreturn))
+#endif
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index f63ea52..655d68a 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -261,6 +261,14 @@ main (void) {
TXT("-- This is the version for " TARGET)
TXT("")
TXT("with Interfaces.C;")
+#if defined (__MINGW32__)
+# define TARGET_OS "Windows"
+# define Serial_Port_Descriptor "System.Win32.HANDLE"
+TXT("with System.Win32;")
+#else
+# define TARGET_OS "Other_OS"
+# define Serial_Port_Descriptor "Interfaces.C.int"
+#endif
/*
package System.OS_Constants is
@@ -280,11 +288,6 @@ package System.OS_Constants is
type OS_Type is (Windows, Other_OS);
*/
-#if defined (__MINGW32__)
-# define TARGET_OS "Windows"
-#else
-# define TARGET_OS "Other_OS"
-#endif
C("Target_OS", OS_Type, TARGET_OS, "")
/*
pragma Warnings (Off, Target_OS);
@@ -303,6 +306,8 @@ CST(Target_Name, "")
#define SIZEOF_unsigned_int sizeof (unsigned int)
CND(SIZEOF_unsigned_int, "Size of unsigned int")
+SUB(Serial_Port_Descriptor)
+
/*
-------------------
@@ -405,10 +410,10 @@ CND(FNDELAY, "Nonblocking")
#if defined (__FreeBSD__) || defined (__DragonFly__)
# define CNI CNU
-# define IOCTL_Req_T "unsigned"
+# define IOCTL_Req_T "Interfaces.C.unsigned"
#else
# define CNI CND
-# define IOCTL_Req_T "int"
+# define IOCTL_Req_T "Interfaces.C.int"
#endif
SUB(IOCTL_Req_T)
@@ -1287,6 +1292,111 @@ CND(IPPROTO_UDP, "UDP")
#endif
CND(IPPROTO_TCP, "TCP")
+#ifndef IPPROTO_ICMP
+# define IPPROTO_ICMP -1
+#endif
+CND(IPPROTO_ICMP, "Internet Control Message Protocol")
+
+#ifndef IPPROTO_IGMP
+# define IPPROTO_IGMP -1
+#endif
+CND(IPPROTO_IGMP, "Internet Group Management Protocol")
+
+#ifndef IPPROTO_IPIP
+# define IPPROTO_IPIP -1
+#endif
+CND(IPPROTO_IPIP, "IPIP tunnels (older KA9Q tunnels use 94)")
+
+#ifndef IPPROTO_EGP
+# define IPPROTO_EGP -1
+#endif
+CND(IPPROTO_EGP, "Exterior Gateway Protocol")
+
+#ifndef IPPROTO_PUP
+# define IPPROTO_PUP -1
+#endif
+CND(IPPROTO_PUP, "PUP protocol")
+
+#ifndef IPPROTO_IDP
+# define IPPROTO_IDP -1
+#endif
+CND(IPPROTO_IDP, "XNS IDP protocol")
+
+#ifndef IPPROTO_TP
+# define IPPROTO_TP -1
+#endif
+CND(IPPROTO_TP, "SO Transport Protocol Class 4")
+
+#ifndef IPPROTO_DCCP
+# define IPPROTO_DCCP -1
+#endif
+CND(IPPROTO_DCCP, "Datagram Congestion Control Protocol")
+
+#ifndef IPPROTO_RSVP
+# define IPPROTO_RSVP -1
+#endif
+CND(IPPROTO_RSVP, "Reservation Protocol")
+
+#ifndef IPPROTO_GRE
+# define IPPROTO_GRE -1
+#endif
+CND(IPPROTO_GRE, "General Routing Encapsulation")
+
+#ifndef IPPROTO_ESP
+# define IPPROTO_ESP -1
+#endif
+CND(IPPROTO_ESP, "encapsulating security payload")
+
+#ifndef IPPROTO_AH
+# define IPPROTO_AH -1
+#endif
+CND(IPPROTO_AH, "authentication header")
+
+#ifndef IPPROTO_MTP
+# define IPPROTO_MTP -1
+#endif
+CND(IPPROTO_MTP, "Multicast Transport Protocol")
+
+#ifndef IPPROTO_BEETPH
+# define IPPROTO_BEETPH -1
+#endif
+CND(IPPROTO_BEETPH, "IP option pseudo header for BEET")
+
+#ifndef IPPROTO_ENCAP
+# define IPPROTO_ENCAP -1
+#endif
+CND(IPPROTO_ENCAP, "Encapsulation Header")
+
+#ifndef IPPROTO_PIM
+# define IPPROTO_PIM -1
+#endif
+CND(IPPROTO_PIM, "Protocol Independent Multicast")
+
+#ifndef IPPROTO_COMP
+# define IPPROTO_COMP -1
+#endif
+CND(IPPROTO_COMP, "Compression Header Protocol")
+
+#ifndef IPPROTO_SCTP
+# define IPPROTO_SCTP -1
+#endif
+CND(IPPROTO_SCTP, "Stream Control Transmission Protocol")
+
+#ifndef IPPROTO_UDPLITE
+# define IPPROTO_UDPLITE -1
+#endif
+CND(IPPROTO_UDPLITE, "UDP-Lite protocol")
+
+#ifndef IPPROTO_MPLS
+# define IPPROTO_MPLS -1
+#endif
+CND(IPPROTO_MPLS, "MPLS in IP")
+
+#ifndef IPPROTO_RAW
+# define IPPROTO_RAW -1
+#endif
+CND(IPPROTO_RAW, "Raw IP packets")
+
/*
-------------------
@@ -1628,9 +1738,9 @@ CND(IF_NAMESIZE, "Max size of interface name with 0 terminator");
*/
#if defined (__sun__) || defined (__hpux__)
-# define Msg_Iovlen_T "int"
+# define Msg_Iovlen_T "Interfaces.C.int"
#else
-# define Msg_Iovlen_T "size_t"
+# define Msg_Iovlen_T "Interfaces.C.size_t"
#endif
SUB(Msg_Iovlen_T)
diff --git a/gcc/ada/scil_ll.adb b/gcc/ada/scil_ll.adb
index 58efe51..841206d 100644
--- a/gcc/ada/scil_ll.adb
+++ b/gcc/ada/scil_ll.adb
@@ -49,25 +49,6 @@ package body SCIL_LL is
-- Internal Hash Tables --
--------------------------
- package Contract_Only_Body_Flag is new Simple_HTable
- (Header_Num => Header_Num,
- Element => Boolean,
- No_Element => False,
- Key => Node_Id,
- Hash => Hash,
- Equal => "=");
- -- This table records the value of flag Is_Contract_Only_Flag of tree nodes
-
- package Contract_Only_Body_Nodes is new Simple_HTable
- (Header_Num => Header_Num,
- Element => Node_Id,
- No_Element => Empty,
- Key => Node_Id,
- Hash => Hash,
- Equal => "=");
- -- This table records the value of attribute Contract_Only_Body of tree
- -- nodes.
-
package SCIL_Nodes is new Simple_HTable
(Header_Num => Header_Num,
Element => Node_Id,
@@ -86,21 +67,6 @@ package body SCIL_LL is
Set_SCIL_Node (Target, Get_SCIL_Node (Source));
end Copy_SCIL_Node;
- ----------------------------
- -- Get_Contract_Only_Body --
- ----------------------------
-
- function Get_Contract_Only_Body (N : Node_Id) return Node_Id is
- begin
- if CodePeer_Mode
- and then Present (N)
- then
- return Contract_Only_Body_Nodes.Get (N);
- else
- return Empty;
- end if;
- end Get_Contract_Only_Body;
-
-------------------
-- Get_SCIL_Node --
-------------------
@@ -132,42 +98,9 @@ package body SCIL_LL is
procedure Initialize is
begin
SCIL_Nodes.Reset;
- Contract_Only_Body_Nodes.Reset;
- Contract_Only_Body_Flag.Reset;
Set_Reporting_Proc (Copy_SCIL_Node'Access);
end Initialize;
- ---------------------------
- -- Is_Contract_Only_Body --
- ---------------------------
-
- function Is_Contract_Only_Body (E : Entity_Id) return Boolean is
- begin
- return Contract_Only_Body_Flag.Get (E);
- end Is_Contract_Only_Body;
-
- ----------------------------
- -- Set_Contract_Only_Body --
- ----------------------------
-
- procedure Set_Contract_Only_Body (N : Node_Id; Value : Node_Id) is
- begin
- pragma Assert (CodePeer_Mode
- and then Present (N)
- and then Is_Contract_Only_Body (Value));
-
- Contract_Only_Body_Nodes.Set (N, Value);
- end Set_Contract_Only_Body;
-
- -------------------------------
- -- Set_Is_Contract_Only_Body --
- -------------------------------
-
- procedure Set_Is_Contract_Only_Body (E : Entity_Id) is
- begin
- Contract_Only_Body_Flag.Set (E, True);
- end Set_Is_Contract_Only_Body;
-
-------------------
-- Set_SCIL_Node --
-------------------
diff --git a/gcc/ada/scil_ll.ads b/gcc/ada/scil_ll.ads
index 81d8260..6246af7 100644
--- a/gcc/ada/scil_ll.ads
+++ b/gcc/ada/scil_ll.ads
@@ -30,31 +30,19 @@
------------------------------------------------------------------------------
-- This package extends the tree nodes with fields that are used to reference
--- the SCIL node and the Contract_Only_Body of a subprogram with aspects.
+-- the SCIL node.
with Types; use Types;
package SCIL_LL is
- function Get_Contract_Only_Body (N : Node_Id) return Node_Id;
- -- Read the value of attribute Contract_Only_Body
-
function Get_SCIL_Node (N : Node_Id) return Node_Id;
-- Read the value of attribute SCIL node
- procedure Set_Contract_Only_Body (N : Node_Id; Value : Node_Id);
- -- Set the value of attribute Contract_Only_Body
-
procedure Set_SCIL_Node (N : Node_Id; Value : Node_Id);
-- Set the value of attribute SCIL node
procedure Initialize;
-- Initialize the table of SCIL nodes
- function Is_Contract_Only_Body (E : Entity_Id) return Boolean;
- -- Return True if E is a Contract_Only_Body subprogram
-
- procedure Set_Is_Contract_Only_Body (E : Entity_Id);
- -- Set E as Contract_Only_Body subprogram
-
end SCIL_LL;
diff --git a/gcc/ada/seh_init.c b/gcc/ada/seh_init.c
index fa9a693..2926605 100644
--- a/gcc/ada/seh_init.c
+++ b/gcc/ada/seh_init.c
@@ -39,8 +39,8 @@
#endif
#ifdef IN_RTS
-#include "tconfig.h"
-#include "tsystem.h"
+
+#include "runtime.h"
/* We don't have libiberty, so use malloc. */
#define xmalloc(S) malloc (S)
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index fa3ed48..2f8f6a4 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -1579,7 +1579,7 @@ package body Sem is
and then Nkind (Unit (Comp_Unit)) in N_Proper_Body
and then (Nkind (Unit (Comp_Unit)) /= N_Subprogram_Body
or else not Acts_As_Spec (Comp_Unit))
- and then not In_Extended_Main_Source_Unit (Comp_Unit)
+ and then not Ext_Main_Source_Unit
then
null;
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index d03af55..7aacc5f 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -904,7 +904,7 @@ package body Sem_Aggr is
-- If the aggregate has box-initialized components, its type must be
-- frozen so that initialization procedures can properly be called
- -- in the resolution that follows. The replacement of boxes with
+ -- in the resolution that follows. The replacement of boxes with
-- initialization calls is properly an expansion activity but it must
-- be done during resolution.
@@ -4264,8 +4264,15 @@ package body Sem_Aggr is
Expr_Disc : Node_Id)
is
begin
- if Nkind (Bound) = N_Identifier
- and then Entity (Bound) = Disc
+ if Nkind (Bound) /= N_Identifier then
+ return;
+ end if;
+
+ -- We expect either the discriminant or the discriminal
+
+ if Entity (Bound) = Disc
+ or else (Ekind (Entity (Bound)) = E_In_Parameter
+ and then Discriminal_Link (Entity (Bound)) = Disc)
then
Rewrite (Bound, New_Copy_Tree (Expr_Disc));
end if;
@@ -4280,9 +4287,7 @@ package body Sem_Aggr is
-- Start of processing for Rewrite_Range
begin
- if Has_Discriminants (Root_Type)
- and then Nkind (Rge) = N_Range
- then
+ if Has_Discriminants (Root_Type) and then Nkind (Rge) = N_Range then
Low := Low_Bound (Rge);
High := High_Bound (Rge);
@@ -4903,7 +4908,9 @@ package body Sem_Aggr is
-- Root record type whose discriminants may be used as
-- bounds in range nodes.
- Index : Node_Id;
+ Assoc : Node_Id;
+ Choice : Node_Id;
+ Index : Node_Id;
begin
-- Rewrite the range nodes occurring in the indexes
@@ -4919,12 +4926,26 @@ package body Sem_Aggr is
end loop;
-- Rewrite the range nodes occurring as aggregate
- -- bounds.
+ -- bounds and component associations.
- if Nkind (Expr) = N_Aggregate
- and then Present (Aggregate_Bounds (Expr))
- then
- Rewrite_Range (Rec_Typ, Aggregate_Bounds (Expr));
+ if Nkind (Expr) = N_Aggregate then
+ if Present (Aggregate_Bounds (Expr)) then
+ Rewrite_Range (Rec_Typ, Aggregate_Bounds (Expr));
+ end if;
+
+ if Present (Component_Associations (Expr)) then
+ Assoc := First (Component_Associations (Expr));
+ while Present (Assoc) loop
+ Choice := First (Choices (Assoc));
+ while Present (Choice) loop
+ Rewrite_Range (Rec_Typ, Choice);
+
+ Next (Choice);
+ end loop;
+
+ Next (Assoc);
+ end loop;
+ end if;
end if;
end;
end if;
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index bdc76c3..4c6cba6 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -1634,7 +1634,9 @@ package body Sem_Attr is
raise Bad_Attribute;
end if;
- -- Normal case of array type or subtype
+ -- Normal case of array type or subtype. Note that if the
+ -- prefix is a current instance of a type declaration it
+ -- appears within an aspect specification and is legal.
Check_Either_E0_Or_E1;
Check_Dereference;
@@ -1643,6 +1645,7 @@ package body Sem_Attr is
if not Is_Constrained (P_Type)
and then Is_Entity_Name (P)
and then Is_Type (Entity (P))
+ and then not Is_Current_Instance (P)
then
-- Note: we do not call Error_Attr here, since we prefer to
-- continue, using the relevant index type of the array,
@@ -5845,8 +5848,19 @@ package body Sem_Attr is
or else Ekind (Entity (P)) = E_Enumeration_Literal)
and then Size_Known_At_Compile_Time (Entity (P))
then
- Rewrite (N, Make_Integer_Literal (Sloc (N), Esize (Entity (P))));
- Analyze (N);
+ declare
+ Siz : Uint;
+
+ begin
+ if Known_Static_RM_Size (Entity (P)) then
+ Siz := RM_Size (Entity (P));
+ else
+ Siz := Esize (Entity (P));
+ end if;
+
+ Rewrite (N, Make_Integer_Literal (Sloc (N), Siz));
+ Analyze (N);
+ end;
end if;
-----------
@@ -11418,7 +11432,7 @@ package body Sem_Attr is
if Present (Lo) then
Rewrite (P,
Make_Indexed_Component (Loc,
- Prefix => Relocate_Node (Prefix (P)),
+ Prefix => Relocate_Node (Prefix (P)),
Expressions => New_List (Lo)));
Analyze_And_Resolve (P);
diff --git a/gcc/ada/sem_aux.adb b/gcc/ada/sem_aux.adb
index 0954032..71a3873 100644
--- a/gcc/ada/sem_aux.adb
+++ b/gcc/ada/sem_aux.adb
@@ -1324,6 +1324,19 @@ package body Sem_Aux is
end if;
end Is_Limited_View;
+ ----------------------------
+ -- Is_Protected_Operation --
+ ----------------------------
+
+ function Is_Protected_Operation (E : Entity_Id) return Boolean is
+ begin
+ return
+ Is_Entry (E)
+ or else (Is_Subprogram (E)
+ and then Nkind (Parent (Unit_Declaration_Node (E))) =
+ N_Protected_Definition);
+ end Is_Protected_Operation;
+
----------------------
-- Nearest_Ancestor --
----------------------
diff --git a/gcc/ada/sem_aux.ads b/gcc/ada/sem_aux.ads
index ec0f5e7..55cfefa 100644
--- a/gcc/ada/sem_aux.ads
+++ b/gcc/ada/sem_aux.ads
@@ -87,7 +87,7 @@ package Sem_Aux is
-----------------
function Ancestor_Subtype (Typ : Entity_Id) return Entity_Id;
- -- The argument Id is a type or subtype entity. If the argument is a
+ -- The argument Typ is a type or subtype entity. If the argument is a
-- subtype then it returns the subtype or type from which the subtype was
-- obtained, otherwise it returns Empty.
@@ -357,6 +357,10 @@ package Sem_Aux is
-- these types). This older routine overlaps with the previous one, this
-- should be cleaned up???
+ function Is_Protected_Operation (E : Entity_Id) return Boolean;
+ -- Given a subprogram or entry, determines whether E is a protected entry
+ -- or subprogram.
+
function Nearest_Ancestor (Typ : Entity_Id) return Entity_Id;
-- Given a subtype Typ, this function finds out the nearest ancestor from
-- which constraints and predicates are inherited. There is no simple link
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 407e84f..c5d10f7 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -4355,7 +4355,7 @@ package body Sem_Ch10 is
end;
end if;
- -- The With_Clause may be on a grand-child or one of its further
+ -- The With_Clause may be on a grandchild or one of its further
-- descendants, which makes a child immediately visible. Examine
-- ancestry to determine whether such a child exists. For example,
-- if current unit is A.C, and with_clause is on A.X.Y.Z, then X
@@ -4394,7 +4394,7 @@ package body Sem_Ch10 is
-- Scan context of current unit, to check whether there is
-- a with_clause on the same unit as a private with-clause
-- on a parent, in which case child unit is visible. If the
- -- unit is a grand-child, the same applies to its parent.
+ -- unit is a grandchild, the same applies to its parent.
----------------
-- In_Context --
@@ -6379,22 +6379,38 @@ package body Sem_Ch10 is
begin
-- Ada 2005 (AI-50217): We remove the context clauses in two phases:
- -- limited-views first and regular-views later (to maintain the
- -- stack model).
+ -- limited-views first and regular-views later (to maintain the stack
+ -- model).
-- First Phase: Remove limited_with context clauses
Item := First (Context_Items (N));
while Present (Item) loop
- -- We are interested only in with clauses which got installed
- -- on entry.
+ -- We are interested only in with clauses that got installed on entry
if Nkind (Item) = N_With_Clause
and then Limited_Present (Item)
- and then Limited_View_Installed (Item)
then
- Remove_Limited_With_Clause (Item);
+ if Limited_View_Installed (Item) then
+ Remove_Limited_With_Clause (Item);
+
+ -- An unusual case: If the library unit of the Main_Unit has a
+ -- limited with_clause on some unit P and the context somewhere
+ -- includes a with_clause on P, P has been analyzed. The entity
+ -- for P is still visible, which in general is harmless because
+ -- this is the end of the compilation, but it can affect pending
+ -- instantiations that may have been generated elsewhere, so it
+ -- it is necessary to remove U from visibility so that inlining
+ -- and the analysis of instance bodies can proceed cleanly.
+
+ elsif Current_Sem_Unit = Main_Unit
+ and then Serious_Errors_Detected = 0
+ and then not Implicit_With (Item)
+ then
+ Set_Is_Immediately_Visible
+ (Defining_Entity (Unit (Library_Unit (Item))), False);
+ end if;
end if;
Next (Item);
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 42feab0..3aa4975 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -6002,7 +6002,7 @@ package body Sem_Ch12 is
Make_Parameter_Specification (Loc,
Defining_Identifier => F1,
Parameter_Type => New_Occurrence_Of (Op_Type, Loc))),
- Result_Definition => New_Occurrence_Of (Ret_Type, Loc));
+ Result_Definition => New_Occurrence_Of (Ret_Type, Loc));
if Is_Binary then
Append_To (Parameter_Specifications (Spec),
@@ -6657,9 +6657,11 @@ package body Sem_Ch12 is
Formal_Decl := Parent (Associated_Formal_Package (E));
-- Nothing to check if the formal has a box or an others_clause
- -- (necessarily with a box).
+ -- (necessarily with a box), or no associations altogether
- if Box_Present (Formal_Decl) then
+ if Box_Present (Formal_Decl)
+ or else No (Generic_Associations (Formal_Decl))
+ then
null;
elsif Nkind (First (Generic_Associations (Formal_Decl))) =
@@ -10309,8 +10311,11 @@ package body Sem_Ch12 is
begin
Analyze (Actual);
+ -- The actual must be a package instance, or else a current instance
+ -- such as a parent generic within the body of a generic child.
+
if not Is_Entity_Name (Actual)
- or else Ekind (Entity (Actual)) /= E_Package
+ or else not Ekind_In (Entity (Actual), E_Generic_Package, E_Package)
then
Error_Msg_N
("expect package instance to instantiate formal", Actual);
@@ -10349,8 +10354,14 @@ package body Sem_Ch12 is
("previous error in declaration of formal package", Actual);
Abandon_Instantiation (Actual);
- elsif
- Is_Instance_Of (Parent_Spec, Get_Instance_Of (Gen_Parent))
+ elsif Is_Instance_Of (Parent_Spec, Get_Instance_Of (Gen_Parent)) then
+ null;
+
+ -- If this is the current instance of an enclosing generic, that unit
+ -- is the generic package we need.
+
+ elsif In_Open_Scopes (Actual_Pack)
+ and then Ekind (Actual_Pack) = E_Generic_Package
then
null;
@@ -10412,7 +10423,7 @@ package body Sem_Ch12 is
Actual_Ent := First_Entity (Actual_Pack);
Actual_Of_Formal :=
- First (Visible_Declarations (Specification (Analyzed_Formal)));
+ First (Visible_Declarations (Specification (Analyzed_Formal)));
while Present (Actual_Ent)
and then Actual_Ent /= First_Private_Entity (Actual_Pack)
loop
@@ -10487,6 +10498,17 @@ package body Sem_Ch12 is
Next_Entity (Actual_Ent);
end loop;
+
+ -- No conformance to check if the generic has no formal parameters
+ -- and the formal package has no generic associations.
+
+ if Is_Empty_List (Formals)
+ and then
+ (Box_Present (Formal)
+ or else No (Generic_Associations (Formal)))
+ then
+ return Decls;
+ end if;
end;
-- If the formal is not declared with a box, reanalyze it as an
@@ -14103,9 +14125,33 @@ package body Sem_Ch12 is
------------------------
procedure Preanalyze_Actuals (N : Node_Id; Inst : Entity_Id := Empty) is
+ procedure Perform_Appropriate_Analysis (N : Node_Id);
+ -- Determine if the actuals we are analyzing come from a generic
+ -- instantiation that is a library unit and dispatch accordingly.
+
+ ----------------------------------
+ -- Perform_Appropriate_Analysis --
+ ----------------------------------
+
+ procedure Perform_Appropriate_Analysis (N : Node_Id) is
+ begin
+ -- When we have a library instantiation we cannot allow any expansion
+ -- to occur, since there may be no place to put it. Instead, in that
+ -- case we perform a preanalysis of the actual.
+
+ if Present (Inst) and then Is_Compilation_Unit (Inst) then
+ Preanalyze (N);
+ else
+ Analyze (N);
+ end if;
+ end Perform_Appropriate_Analysis;
+
+ -- Local variables
+
+ Errs : constant Nat := Serious_Errors_Detected;
+
Assoc : Node_Id;
Act : Node_Id;
- Errs : constant Nat := Serious_Errors_Detected;
Cur : Entity_Id := Empty;
-- Current homograph of the instance name
@@ -14113,6 +14159,8 @@ package body Sem_Ch12 is
Vis : Boolean := False;
-- Saved visibility status of the current homograph
+ -- Start of processing for Preanalyze_Actuals
+
begin
Assoc := First (Generic_Associations (N));
@@ -14154,10 +14202,10 @@ package body Sem_Ch12 is
null;
elsif Nkind (Act) = N_Attribute_Reference then
- Analyze (Prefix (Act));
+ Perform_Appropriate_Analysis (Prefix (Act));
elsif Nkind (Act) = N_Explicit_Dereference then
- Analyze (Prefix (Act));
+ Perform_Appropriate_Analysis (Prefix (Act));
elsif Nkind (Act) = N_Allocator then
declare
@@ -14165,7 +14213,7 @@ package body Sem_Ch12 is
begin
if Nkind (Expr) = N_Subtype_Indication then
- Analyze (Subtype_Mark (Expr));
+ Perform_Appropriate_Analysis (Subtype_Mark (Expr));
-- Analyze separately each discriminant constraint, when
-- given with a named association.
@@ -14177,9 +14225,10 @@ package body Sem_Ch12 is
Constr := First (Constraints (Constraint (Expr)));
while Present (Constr) loop
if Nkind (Constr) = N_Discriminant_Association then
- Analyze (Expression (Constr));
+ Perform_Appropriate_Analysis
+ (Expression (Constr));
else
- Analyze (Constr);
+ Perform_Appropriate_Analysis (Constr);
end if;
Next (Constr);
@@ -14187,12 +14236,12 @@ package body Sem_Ch12 is
end;
else
- Analyze (Expr);
+ Perform_Appropriate_Analysis (Expr);
end if;
end;
elsif Nkind (Act) /= N_Operator_Symbol then
- Analyze (Act);
+ Perform_Appropriate_Analysis (Act);
-- Within a package instance, mark actuals that are limited
-- views, so their use can be moved to the body of the
@@ -14213,7 +14262,7 @@ package body Sem_Ch12 is
-- warnings complaining about the generic being unreferenced,
-- before abandoning the instantiation.
- Analyze (Name (N));
+ Perform_Appropriate_Analysis (Name (N));
if Is_Entity_Name (Name (N))
and then Etype (Name (N)) /= Any_Type
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 2a4afb8..bf80200 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -30,7 +30,6 @@ with Debug; use Debug;
with Einfo; use Einfo;
with Elists; use Elists;
with Errout; use Errout;
-with Expander; use Expander;
with Exp_Disp; use Exp_Disp;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
@@ -247,41 +246,6 @@ package body Sem_Ch13 is
-- Remove visibility to the discriminants of type entity E and pop the
-- scope stack if E has discriminants and is not a subtype.
- ---------------------------------------------------
- -- Table for Validate_Compile_Time_Warning_Error --
- ---------------------------------------------------
-
- -- The following table collects pragmas Compile_Time_Error and Compile_
- -- Time_Warning for validation. Entries are made by calls to subprogram
- -- Validate_Compile_Time_Warning_Error, and the call to the procedure
- -- Validate_Compile_Time_Warning_Errors does the actual error checking
- -- and posting of warning and error messages. The reason for this delayed
- -- processing is to take advantage of back-annotations of attributes size
- -- and alignment values performed by the back end.
-
- -- Note: the reason we store a Source_Ptr value instead of a Node_Id is
- -- that by the time Validate_Unchecked_Conversions is called, Sprint will
- -- already have modified all Sloc values if the -gnatD option is set.
-
- type CTWE_Entry is record
- Eloc : Source_Ptr;
- -- Source location used in warnings and error messages
-
- Prag : Node_Id;
- -- Pragma Compile_Time_Error or Compile_Time_Warning
-
- Scope : Node_Id;
- -- The scope which encloses the pragma
- end record;
-
- package Compile_Time_Warnings_Errors is new Table.Table (
- Table_Component_Type => CTWE_Entry,
- Table_Index_Type => Int,
- Table_Low_Bound => 1,
- Table_Initial => 50,
- Table_Increment => 200,
- Table_Name => "Compile_Time_Warnings_Errors");
-
----------------------------------------------
-- Table for Validate_Unchecked_Conversions --
----------------------------------------------
@@ -3491,14 +3455,32 @@ package body Sem_Ch13 is
-- Build the precondition/postcondition pragma
- -- Add note about why we do NOT need Copy_Tree here???
+ -- We use Relocate_Node here rather than New_Copy_Tree
+ -- because subsequent visibility analysis of the aspect
+ -- depends on this sharing. This should be cleaned up???
- Make_Aitem_Pragma
- (Pragma_Argument_Associations => New_List (
- Make_Pragma_Argument_Association (Eloc,
- Chars => Name_Check,
- Expression => Relocate_Node (Expr))),
- Pragma_Name => Pname);
+ -- If the context is generic or involves ASIS, we want
+ -- to preserve the original tree, and simply share it
+ -- between aspect and generated attribute. This parallels
+ -- what is done in sem_prag.adb (see Get_Argument).
+
+ declare
+ New_Expr : Node_Id;
+
+ begin
+ if ASIS_Mode or else Inside_A_Generic then
+ New_Expr := Expr;
+ else
+ New_Expr := Relocate_Node (Expr);
+ end if;
+
+ Make_Aitem_Pragma
+ (Pragma_Argument_Associations => New_List (
+ Make_Pragma_Argument_Association (Eloc,
+ Chars => Name_Check,
+ Expression => New_Expr)),
+ Pragma_Name => Pname);
+ end;
-- Add message unless exception messages are suppressed
@@ -5163,6 +5145,7 @@ package body Sem_Ch13 is
-- aspect case properly.
if Is_Object (O_Ent)
+ and then not Is_Generic_Formal (O_Ent)
and then not Is_Generic_Type (Etype (U_Ent))
and then Address_Clause_Overlay_Warnings
then
@@ -5511,7 +5494,7 @@ package body Sem_Ch13 is
-- Default_Iterator --
----------------------
- when Attribute_Default_Iterator => Default_Iterator : declare
+ when Attribute_Default_Iterator => Default_Iterator : declare
Func : Entity_Id;
Typ : Entity_Id;
@@ -8902,9 +8885,15 @@ package body Sem_Ch13 is
Expression => Expr))));
-- The declaration has been analyzed when created, and placed
- -- after type declaration. Insert body itself after freeze node.
+ -- after type declaration. Insert body itself after freeze node,
+ -- unless subprogram declaration is already there, in which case
+ -- body better be placed afterwards.
- Insert_After_And_Analyze (N, FBody);
+ if FDecl = Next (N) then
+ Insert_After_And_Analyze (FDecl, FBody);
+ else
+ Insert_After_And_Analyze (N, FBody);
+ end if;
-- The defining identifier of a quantified expression carries the
-- scope in which the type appears, but when unnesting we need
@@ -9352,10 +9341,20 @@ package body Sem_Ch13 is
else
-- In a generic context freeze nodes are not always generated, so
- -- analyze the expression now.
+ -- analyze the expression now. If the aspect is for a type, this
+ -- makes its potential components accessible.
if not Analyzed (Freeze_Expr) and then Inside_A_Generic then
- Preanalyze (Freeze_Expr);
+ if A_Id = Aspect_Dynamic_Predicate
+ or else A_Id = Aspect_Predicate
+ or else A_Id = Aspect_Priority
+ then
+ Push_Type (Ent);
+ Preanalyze (Freeze_Expr);
+ Pop_Type (Ent);
+ else
+ Preanalyze (Freeze_Expr);
+ end if;
end if;
-- Indicate that the expression comes from an aspect specification,
@@ -9389,6 +9388,7 @@ package body Sem_Ch13 is
elsif A_Id = Aspect_Dynamic_Predicate
or else A_Id = Aspect_Predicate
or else A_Id = Aspect_Priority
+ or else A_Id = Aspect_CPU
then
Push_Type (Ent);
Preanalyze_Spec_Expression (End_Decl_Expr, T);
@@ -11280,6 +11280,7 @@ package body Sem_Ch13 is
if A_Id = Aspect_Dynamic_Predicate
or else A_Id = Aspect_Predicate
or else A_Id = Aspect_Priority
+ or else A_Id = Aspect_CPU
then
-- Retrieve the visibility to components and discriminants
-- in order to properly analyze the aspects.
@@ -11563,7 +11564,7 @@ package body Sem_Ch13 is
begin
-- A representation item is either subtype-specific (Size and Alignment
- -- clauses) or type-related (all others). Subtype-specific aspects may
+ -- clauses) or type-related (all others). Subtype-specific aspects may
-- differ for different subtypes of the same type (RM 13.1.8).
-- A derived type inherits each type-related representation aspect of
@@ -11796,7 +11797,6 @@ package body Sem_Ch13 is
procedure Initialize is
begin
Address_Clause_Checks.Init;
- Compile_Time_Warnings_Errors.Init;
Unchecked_Conversions.Init;
-- ??? Might be needed in the future for some non GCC back-ends
@@ -12550,6 +12550,30 @@ package body Sem_Ch13 is
------------------------
function Rep_Item_Too_Early (T : Entity_Id; N : Node_Id) return Boolean is
+ function Has_Generic_Parent (E : Entity_Id) return Boolean;
+ -- Return True if any ancestor is a generic type
+
+ ------------------------
+ -- Has_Generic_Parent --
+ ------------------------
+
+ function Has_Generic_Parent (E : Entity_Id) return Boolean is
+ Ancestor_Type : Entity_Id := Etype (E);
+
+ begin
+ while Present (Ancestor_Type)
+ and then not Is_Generic_Type (Ancestor_Type)
+ and then Etype (Ancestor_Type) /= Ancestor_Type
+ loop
+ Ancestor_Type := Etype (Ancestor_Type);
+ end loop;
+
+ return
+ Present (Ancestor_Type) and then Is_Generic_Type (Ancestor_Type);
+ end Has_Generic_Parent;
+
+ -- Start of processing for Rep_Item_Too_Early
+
begin
-- Cannot apply non-operational rep items to generic types
@@ -12557,7 +12581,7 @@ package body Sem_Ch13 is
return False;
elsif Is_Type (T)
- and then Is_Generic_Type (Root_Type (T))
+ and then Has_Generic_Parent (T)
and then (Nkind (N) /= N_Pragma
or else Get_Pragma_Id (N) /= Pragma_Convention)
then
@@ -12607,7 +12631,7 @@ package body Sem_Ch13 is
function Is_Derived_Type_With_Constraint return Boolean;
-- Check whether T is a derived type with an explicit constraint, in
-- which case the constraint has frozen the type and the item is too
- -- late. This compensates for the fact that for derived scalar types
+ -- late. This compensates for the fact that for derived scalar types
-- we freeze the base type unconditionally on account of a long-standing
-- issue in gigi.
@@ -13903,79 +13927,6 @@ package body Sem_Ch13 is
end loop;
end Validate_Address_Clauses;
- -----------------------------------------
- -- Validate_Compile_Time_Warning_Error --
- -----------------------------------------
-
- procedure Validate_Compile_Time_Warning_Error (N : Node_Id) is
- begin
- Compile_Time_Warnings_Errors.Append
- (New_Val => CTWE_Entry'(Eloc => Sloc (N),
- Scope => Current_Scope,
- Prag => N));
- end Validate_Compile_Time_Warning_Error;
-
- ------------------------------------------
- -- Validate_Compile_Time_Warning_Errors --
- ------------------------------------------
-
- procedure Validate_Compile_Time_Warning_Errors is
- procedure Set_Scope (S : Entity_Id);
- -- Install all enclosing scopes of S along with S itself
-
- procedure Unset_Scope (S : Entity_Id);
- -- Uninstall all enclosing scopes of S along with S itself
-
- ---------------
- -- Set_Scope --
- ---------------
-
- procedure Set_Scope (S : Entity_Id) is
- begin
- if S /= Standard_Standard then
- Set_Scope (Scope (S));
- end if;
-
- Push_Scope (S);
- end Set_Scope;
-
- -----------------
- -- Unset_Scope --
- -----------------
-
- procedure Unset_Scope (S : Entity_Id) is
- begin
- if S /= Standard_Standard then
- Unset_Scope (Scope (S));
- end if;
-
- Pop_Scope;
- end Unset_Scope;
-
- -- Start of processing for Validate_Compile_Time_Warning_Errors
-
- begin
- Expander_Mode_Save_And_Set (False);
- In_Compile_Time_Warning_Or_Error := True;
-
- for N in Compile_Time_Warnings_Errors.First ..
- Compile_Time_Warnings_Errors.Last
- loop
- declare
- T : CTWE_Entry renames Compile_Time_Warnings_Errors.Table (N);
-
- begin
- Set_Scope (T.Scope);
- Reset_Analyzed_Flags (T.Prag);
- Process_Compile_Time_Warning_Or_Error (T.Prag, T.Eloc);
- Unset_Scope (T.Scope);
- end;
- end loop;
-
- In_Compile_Time_Warning_Or_Error := False;
- Expander_Mode_Restore;
- end Validate_Compile_Time_Warning_Errors;
-
---------------------------
-- Validate_Independence --
---------------------------
diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads
index 3773a12..eb95e2b 100644
--- a/gcc/ada/sem_ch13.ads
+++ b/gcc/ada/sem_ch13.ads
@@ -189,18 +189,6 @@ package Sem_Ch13 is
-- change. A False result is possible only for array, enumeration or
-- record types.
- procedure Validate_Compile_Time_Warning_Error (N : Node_Id);
- -- N is a pragma Compile_Time_Error or Compile_Warning_Error whose boolean
- -- expression is not known at compile time. This procedure makes an entry
- -- in a table. The actual checking is performed by Validate_Compile_Time_
- -- Warning_Errors, which is invoked after calling the back end.
-
- procedure Validate_Compile_Time_Warning_Errors;
- -- This routine is called after calling the back end to validate pragmas
- -- Compile_Time_Error and Compile_Time_Warning for size and alignment
- -- appropriateness. The reason it is called that late is to take advantage
- -- of any back-annotation of size and alignment performed by the back end.
-
procedure Validate_Unchecked_Conversion
(N : Node_Id;
Act_Unit : Entity_Id);
diff --git a/gcc/ada/sem_ch2.adb b/gcc/ada/sem_ch2.adb
index 3b46ad5..378269f 100644
--- a/gcc/ada/sem_ch2.adb
+++ b/gcc/ada/sem_ch2.adb
@@ -24,6 +24,7 @@
------------------------------------------------------------------------------
with Atree; use Atree;
+with Einfo; use Einfo;
with Namet; use Namet;
with Opt; use Opt;
with Restrict; use Restrict;
@@ -83,7 +84,22 @@ package body Sem_Ch2 is
procedure Analyze_Integer_Literal (N : Node_Id) is
begin
- Set_Etype (N, Universal_Integer);
+ -- As a lexical element, an integer literal has type Universal_Integer,
+ -- i.e., is compatible with any integer type. This is semantically
+ -- consistent and simplifies type checking and subsequent constant
+ -- folding when needed. An exception is caused by 64-bit modular types,
+ -- whose upper bound is not representable in a nonstatic context that
+ -- will use 64-bit integers at run time. For such cases, we need to
+ -- preserve the information that the analyzed literal has that modular
+ -- type. For simplicity, we preserve the information for all integer
+ -- literals that result from a modular operation. This happens after
+ -- prior analysis (or construction) of the literal, and after type
+ -- checking and resolution.
+
+ if No (Etype (N)) or else not Is_Modular_Integer_Type (Etype (N)) then
+ Set_Etype (N, Universal_Integer);
+ end if;
+
Set_Is_Static_Expression (N);
end Analyze_Integer_Literal;
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 75a0099..645a024 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -221,9 +221,7 @@ package body Sem_Ch3 is
-- T has discriminants but there are no discriminant constraints). The
-- Related_Nod is the same as Decl_Node in Create_Constrained_Components.
-- The For_Access says whether or not this subtype is really constraining
- -- an access type. That is its sole purpose is the designated type of an
- -- access type -- in which case a Private_Subtype Is_For_Access_Subtype
- -- is built to avoid freezing T when the access subtype is frozen.
+ -- an access type.
function Build_Scalar_Bound
(Bound : Node_Id;
@@ -930,17 +928,20 @@ package body Sem_Ch3 is
-- declaration may include an expression that is an allocator, whose
-- expansion needs the proper Master for the created tasks.
- if Nkind (Related_Nod) = N_Object_Declaration and then Expander_Active
+ if Expander_Active
+ and then Nkind (Related_Nod) = N_Object_Declaration
then
if Is_Limited_Record (Desig_Type)
and then Is_Class_Wide_Type (Desig_Type)
+ and then Tasking_Allowed
then
Build_Class_Wide_Master (Anon_Type);
-- Similarly, if the type is an anonymous access that designates
-- tasks, create a master entity for it in the current context.
- elsif Has_Task (Desig_Type) and then Comes_From_Source (Related_Nod)
+ elsif Has_Task (Desig_Type)
+ and then Comes_From_Source (Related_Nod)
then
Build_Master_Entity (Defining_Identifier (Related_Nod));
Build_Master_Renaming (Anon_Type);
@@ -3006,14 +3007,15 @@ package body Sem_Ch3 is
-- is consistent with that of the parent.
declare
- Par_Discr : constant Entity_Id :=
- Get_Reference_Discriminant (Par_Type);
- Cur_Discr : constant Entity_Id :=
+ Cur_Discr : constant Entity_Id :=
Get_Reference_Discriminant (Prev);
+ Par_Discr : constant Entity_Id :=
+ Get_Reference_Discriminant (Par_Type);
begin
if Corresponding_Discriminant (Cur_Discr) /= Par_Discr then
- Error_Msg_N ("aspect incosistent with that of parent", N);
+ Error_Msg_N
+ ("aspect inconsistent with that of parent", N);
end if;
-- Check that specification in partial view matches the
@@ -3026,7 +3028,7 @@ package body Sem_Ch3 is
Chars (Cur_Discr)
then
Error_Msg_N
- ("aspect incosistent with that of parent", N);
+ ("aspect inconsistent with that of parent", N);
end if;
end;
end if;
@@ -3646,8 +3648,10 @@ package body Sem_Ch3 is
-- Ghost mode.
procedure Analyze_Object_Declaration (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- Id : constant Entity_Id := Defining_Identifier (N);
+ Loc : constant Source_Ptr := Sloc (N);
+ Id : constant Entity_Id := Defining_Identifier (N);
+ Next_Decl : constant Node_Id := Next (N);
+
Act_T : Entity_Id;
T : Entity_Id;
@@ -3909,6 +3913,11 @@ package body Sem_Ch3 is
A_Id := Get_Aspect_Id (Chars (Identifier (A)));
while Present (A) loop
if A_Id = Aspect_Alignment or else A_Id = Aspect_Address then
+
+ -- Set flag on object entity, for later processing at
+ -- the freeze point.
+
+ Set_Has_Delayed_Aspects (Id);
return True;
end if;
@@ -4492,8 +4501,20 @@ package body Sem_Ch3 is
null;
else
- Insert_After (N,
- Make_Predicate_Check (T, New_Occurrence_Of (Id, Loc)));
+ -- The check must be inserted after the expanded aggregate
+ -- expansion code, if any.
+
+ declare
+ Check : constant Node_Id :=
+ Make_Predicate_Check (T, New_Occurrence_Of (Id, Loc));
+
+ begin
+ if No (Next_Decl) then
+ Append_To (List_Containing (N), Check);
+ else
+ Insert_Before (Next_Decl, Check);
+ end if;
+ end;
end if;
end if;
@@ -4589,14 +4610,6 @@ package body Sem_Ch3 is
elsif Is_Interface (T) then
null;
- -- In GNATprove mode, Expand_Subtype_From_Expr does nothing. Thus,
- -- we should prevent the generation of another Itype with the
- -- same name as the one already generated, or we end up with
- -- two identical types in GNATprove.
-
- elsif GNATprove_Mode then
- null;
-
-- If the type is an unchecked union, no subtype can be built from
-- the expression. Rewrite declaration as a renaming, which the
-- back-end can handle properly. This is a rather unusual case,
@@ -10221,12 +10234,7 @@ package body Sem_Ch3 is
begin
if Ekind (T) = E_Record_Type then
- if For_Access then
- Set_Ekind (Def_Id, E_Private_Subtype);
- Set_Is_For_Access_Subtype (Def_Id, True);
- else
- Set_Ekind (Def_Id, E_Record_Subtype);
- end if;
+ Set_Ekind (Def_Id, E_Record_Subtype);
-- Inherit preelaboration flag from base, for types for which it
-- may have been set: records, private types, protected types.
@@ -10357,7 +10365,7 @@ package body Sem_Ch3 is
then
Create_Constrained_Components (Def_Id, Related_Nod, T, Elist);
- elsif not For_Access then
+ else
Set_Cloned_Subtype (Def_Id, T);
end if;
end if;
@@ -10627,9 +10635,9 @@ package body Sem_Ch3 is
if Ekind (Contr_Typ) /= E_Protected_Type then
Error_Msg_Node_2 := Contr_Typ;
Error_Msg_NE
- ("interface subprogram & cannot be implemented by a " &
- "primitive procedure of task type &", Subp_Alias,
- Iface_Alias);
+ ("interface subprogram & cannot be implemented by a "
+ & "primitive procedure of task type &",
+ Subp_Alias, Iface_Alias);
-- An interface subprogram whose implementation kind is By_
-- Protected_Procedure must be implemented by a procedure.
@@ -10637,28 +10645,27 @@ package body Sem_Ch3 is
elsif Ekind (Impl_Subp) /= E_Procedure then
Error_Msg_Node_2 := Iface_Alias;
Error_Msg_NE
- ("type & must implement abstract subprogram & with a " &
- "procedure", Subp_Alias, Contr_Typ);
+ ("type & must implement abstract subprogram & with a "
+ & "procedure", Subp_Alias, Contr_Typ);
elsif Present (Get_Rep_Pragma (Impl_Subp, Name_Implemented))
and then Implementation_Kind (Impl_Subp) /= Impl_Kind
then
Error_Msg_Name_1 := Impl_Kind;
Error_Msg_N
- ("overriding operation& must have synchronization%",
- Subp_Alias);
+ ("overriding operation& must have synchronization%",
+ Subp_Alias);
end if;
-- If primitive has Optional synchronization, overriding operation
- -- must match if it has an explicit synchronization..
+ -- must match if it has an explicit synchronization.
elsif Present (Get_Rep_Pragma (Impl_Subp, Name_Implemented))
and then Implementation_Kind (Impl_Subp) /= Impl_Kind
then
- Error_Msg_Name_1 := Impl_Kind;
- Error_Msg_N
- ("overriding operation& must have syncrhonization%",
- Subp_Alias);
+ Error_Msg_Name_1 := Impl_Kind;
+ Error_Msg_N
+ ("overriding operation& must have synchronization%", Subp_Alias);
end if;
end Check_Pragma_Implemented;
@@ -12337,48 +12344,73 @@ package body Sem_Ch3 is
-- Next_Entity field of full to ensure that the calls to Copy_Node do
-- not corrupt the entity chain.
- -- Note that the type of the full view is the same entity as the type
- -- of the partial view. In this fashion, the subtype has access to the
- -- correct view of the parent.
- -- The list below included access types, but this leads to several
- -- regressions. How should the base type of the full view be
- -- set consistently for subtypes completed by access types?
-
Save_Next_Entity := Next_Entity (Full);
Save_Homonym := Homonym (Priv);
- case Ekind (Full_Base) is
- when Class_Wide_Kind
- | Private_Kind
- | Protected_Kind
- | Task_Kind
- | E_Record_Subtype
- | E_Record_Type
- =>
- Copy_Node (Priv, Full);
+ if Ekind (Full_Base) in Private_Kind
+ or else Ekind (Full_Base) in Protected_Kind
+ or else Ekind (Full_Base) in Record_Kind
+ or else Ekind (Full_Base) in Task_Kind
+ then
+ Copy_Node (Priv, Full);
- Set_Has_Discriminants
- (Full, Has_Discriminants (Full_Base));
- Set_Has_Unknown_Discriminants
- (Full, Has_Unknown_Discriminants (Full_Base));
- Set_First_Entity (Full, First_Entity (Full_Base));
- Set_Last_Entity (Full, Last_Entity (Full_Base));
+ -- Note that the Etype of the full view is the same as the Etype of
+ -- the partial view. In this fashion, the subtype has access to the
+ -- correct view of the parent.
- -- If the underlying base type is constrained, we know that the
- -- full view of the subtype is constrained as well (the converse
- -- is not necessarily true).
+ Set_Has_Discriminants (Full, Has_Discriminants (Full_Base));
+ Set_Has_Unknown_Discriminants
+ (Full, Has_Unknown_Discriminants (Full_Base));
+ Set_First_Entity (Full, First_Entity (Full_Base));
+ Set_Last_Entity (Full, Last_Entity (Full_Base));
- if Is_Constrained (Full_Base) then
- Set_Is_Constrained (Full);
- end if;
+ -- If the underlying base type is constrained, we know that the
+ -- full view of the subtype is constrained as well (the converse
+ -- is not necessarily true).
- when others =>
- Copy_Node (Full_Base, Full);
+ if Is_Constrained (Full_Base) then
+ Set_Is_Constrained (Full);
+ end if;
- Set_Chars (Full, Chars (Priv));
- Conditional_Delay (Full, Priv);
- Set_Sloc (Full, Sloc (Priv));
- end case;
+ else
+ Copy_Node (Full_Base, Full);
+
+ -- The following subtlety with the Etype of the full view needs to be
+ -- taken into account here. One could think that it must naturally be
+ -- set to the base type of the full base:
+
+ -- Set_Etype (Full, Base_Type (Full_Base));
+
+ -- so that the full view becomes a subtype of the full base when the
+ -- latter is a base type, which must for example happen when the full
+ -- base is declared as derived type. That's also correct if the full
+ -- base is declared as an array type, or a floating-point type, or a
+ -- fixed-point type, or a signed integer type, as these declarations
+ -- create an implicit base type and a first subtype so the Etype of
+ -- the full views must be the implicit base type. But that's wrong
+ -- if the full base is declared as an access type, or an enumeration
+ -- type, or a modular integer type, as these declarations directly
+ -- create a base type, i.e. with Etype pointing to itself. Moreover
+ -- the full base being declared in the private part, i.e. when the
+ -- views are swapped, the end result is that the Etype of the full
+ -- base is set to its private view in this case and that we need to
+ -- propagate this setting to the full view in order for the subtype
+ -- to be compatible with the base type.
+
+ if Is_Base_Type (Full_Base)
+ and then (Is_Derived_Type (Full_Base)
+ or else Ekind (Full_Base) in Array_Kind
+ or else Ekind (Full_Base) in Fixed_Point_Kind
+ or else Ekind (Full_Base) in Float_Kind
+ or else Ekind (Full_Base) in Signed_Integer_Kind)
+ then
+ Set_Etype (Full, Full_Base);
+ end if;
+
+ Set_Chars (Full, Chars (Priv));
+ Set_Sloc (Full, Sloc (Priv));
+ Conditional_Delay (Full, Priv);
+ end if;
Link_Entities (Full, Save_Next_Entity);
Set_Homonym (Full, Save_Homonym);
@@ -12386,35 +12418,14 @@ package body Sem_Ch3 is
-- Set common attributes for all subtypes: kind, convention, etc.
- Set_Ekind (Full, Subtype_Kind (Ekind (Full_Base)));
- Set_Convention (Full, Convention (Full_Base));
-
- -- The Etype of the full view is inconsistent. Gigi needs to see the
- -- structural full view, which is what the current scheme gives: the
- -- Etype of the full view is the etype of the full base. However, if the
- -- full base is a derived type, the full view then looks like a subtype
- -- of the parent, not a subtype of the full base. If instead we write:
-
- -- Set_Etype (Full, Full_Base);
-
- -- then we get inconsistencies in the front-end (confusion between
- -- views). Several outstanding bugs are related to this ???
-
+ Set_Ekind (Full, Subtype_Kind (Ekind (Full_Base)));
+ Set_Convention (Full, Convention (Full_Base));
Set_Is_First_Subtype (Full, False);
Set_Scope (Full, Scope (Priv));
Set_Size_Info (Full, Full_Base);
Set_RM_Size (Full, RM_Size (Full_Base));
Set_Is_Itype (Full);
- -- For the unusual case of a type with unknown discriminants whose
- -- completion is an array, use the proper full base.
-
- if Is_Array_Type (Full_Base)
- and then Has_Unknown_Discriminants (Priv)
- then
- Set_Etype (Full, Full_Base);
- end if;
-
-- A subtype of a private-type-without-discriminants, whose full-view
-- has discriminants with default expressions, is not constrained.
@@ -12959,6 +12970,10 @@ package body Sem_Ch3 is
if Desig_Type = Current_Scope
and then No (Def_Id)
then
+ Error_Msg_Warn := SPARK_Mode /= On;
+ Error_Msg_N ("<<constraint is ignored on component that is "
+ & "access to current record", S);
+
Set_Ekind (Desig_Subtype, E_Record_Subtype);
Def_Id := Entity (Subtype_Mark (S));
@@ -17813,12 +17828,16 @@ package body Sem_Ch3 is
Digs_Val : Uint;
Base_Typ : Entity_Id;
Implicit_Base : Entity_Id;
- Bound : Node_Id;
function Can_Derive_From (E : Entity_Id) return Boolean;
-- Find if given digits value, and possibly a specified range, allows
-- derivation from specified type
+ procedure Convert_Bound (B : Node_Id);
+ -- If specified, the bounds must be static but may be of different
+ -- types. They must be converted into machine numbers of the base type,
+ -- in accordance with RM 4.9(38).
+
function Find_Base_Type return Entity_Id;
-- Find a predefined base type that Def can derive from, or generate
-- an error and substitute Long_Long_Float if none exists.
@@ -17856,6 +17875,28 @@ package body Sem_Ch3 is
return True;
end Can_Derive_From;
+ -------------------
+ -- Convert_Bound --
+ --------------------
+
+ procedure Convert_Bound (B : Node_Id) is
+ begin
+ -- If the bound is not a literal it can only be static if it is
+ -- a static constant, possibly of a specified type.
+
+ if Is_Entity_Name (B)
+ and then Ekind (Entity (B)) = E_Constant
+ then
+ Rewrite (B, Constant_Value (Entity (B)));
+ end if;
+
+ if Nkind (B) = N_Real_Literal then
+ Set_Realval (B, Machine (Base_Typ, Realval (B), Round, B));
+ Set_Is_Machine_Number (B);
+ Set_Etype (B, Base_Typ);
+ end if;
+ end Convert_Bound;
+
--------------------
-- Find_Base_Type --
--------------------
@@ -17953,24 +17994,8 @@ package body Sem_Ch3 is
Set_Scalar_Range (T, Real_Range_Specification (Def));
Set_Is_Constrained (T);
- -- The bounds of this range must be converted to machine numbers
- -- in accordance with RM 4.9(38).
-
- Bound := Type_Low_Bound (T);
-
- if Nkind (Bound) = N_Real_Literal then
- Set_Realval
- (Bound, Machine (Base_Typ, Realval (Bound), Round, Bound));
- Set_Is_Machine_Number (Bound);
- end if;
-
- Bound := Type_High_Bound (T);
-
- if Nkind (Bound) = N_Real_Literal then
- Set_Realval
- (Bound, Machine (Base_Typ, Realval (Bound), Round, Bound));
- Set_Is_Machine_Number (Bound);
- end if;
+ Convert_Bound (Type_Low_Bound (T));
+ Convert_Bound (Type_High_Bound (T));
else
Set_Scalar_Range (T, Scalar_Range (Base_Typ));
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 3328f96..f7b99d4 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -1699,7 +1699,7 @@ package body Sem_Ch4 is
-- If the case expression is a formal object of mode in out, then
-- treat it as having a nonstatic subtype by forcing use of the base
- -- type (which has to get passed to Check_Case_Choices below). Also
+ -- type (which has to get passed to Check_Case_Choices below). Also
-- use base type when the case expression is parenthesized.
if Paren_Count (Expr) > 0
@@ -2101,21 +2101,12 @@ package body Sem_Ch4 is
if not Is_Overloaded (P) then
if Is_Access_Type (Etype (P)) then
- -- Set the Etype. We need to go through Is_For_Access_Subtypes to
- -- avoid other problems caused by the Private_Subtype and it is
- -- safe to go to the Base_Type because this is the same as
- -- converting the access value to its Base_Type.
+ -- Set the Etype
declare
- DT : Entity_Id := Designated_Type (Etype (P));
+ DT : constant Entity_Id := Designated_Type (Etype (P));
begin
- if Ekind (DT) = E_Private_Subtype
- and then Is_For_Access_Subtype (DT)
- then
- DT := Base_Type (DT);
- end if;
-
-- An explicit dereference is a legal occurrence of an
-- incomplete type imported through a limited_with clause, if
-- the full view is visible, or if we are within an instance
@@ -6173,33 +6164,57 @@ package body Sem_Ch4 is
if Nkind (N) = N_Function_Call then
Get_First_Interp (Nam, X, It);
- while Present (It.Nam) loop
- if Ekind_In (It.Nam, E_Function, E_Operator) then
- return;
- else
- Get_Next_Interp (X, It);
- end if;
- end loop;
- -- If all interpretations are procedures, this deserves a
- -- more precise message. Ditto if this appears as the prefix
- -- of a selected component, which may be a lexical error.
+ if No (It.Typ)
+ and then Ekind (Entity (Name (N))) = E_Function
+ and then Present (Homonym (Entity (Name (N))))
+ then
+ -- A name may appear overloaded if it has a homonym, even if that
+ -- homonym is non-overloadable, in which case the overload list is
+ -- in fact empty. This specialized case deserves a special message
+ -- if the homonym is a child package.
- Error_Msg_N
- ("\context requires function call, found procedure name", Nam);
+ declare
+ Nam : constant Node_Id := Name (N);
+ H : constant Entity_Id := Homonym (Entity (Nam));
- if Nkind (Parent (N)) = N_Selected_Component
- and then N = Prefix (Parent (N))
- then
- Error_Msg_N -- CODEFIX
- ("\period should probably be semicolon", Parent (N));
+ begin
+ if Ekind (H) = E_Package and then Is_Child_Unit (H) then
+ Error_Msg_Qual_Level := 2;
+ Error_Msg_NE ("if an entity in package& is meant, ", Nam, H);
+ Error_Msg_NE ("\use a fully qualified name", Nam, H);
+ Error_Msg_Qual_Level := 0;
+ end if;
+ end;
+
+ else
+ while Present (It.Nam) loop
+ if Ekind_In (It.Nam, E_Function, E_Operator) then
+ return;
+ else
+ Get_Next_Interp (X, It);
+ end if;
+ end loop;
+
+ -- If all interpretations are procedures, this deserves a more
+ -- precise message. Ditto if this appears as the prefix of a
+ -- selected component, which may be a lexical error.
+
+ Error_Msg_N
+ ("\context requires function call, found procedure name", Nam);
+
+ if Nkind (Parent (N)) = N_Selected_Component
+ and then N = Prefix (Parent (N))
+ then
+ Error_Msg_N -- CODEFIX
+ ("\period should probably be semicolon", Parent (N));
+ end if;
end if;
elsif Nkind (N) = N_Procedure_Call_Statement
and then not Void_Interp_Seen
then
- Error_Msg_N (
- "\function name found in procedure call", Nam);
+ Error_Msg_N ("\function name found in procedure call", Nam);
end if;
All_Errors_Mode := Err_Mode;
@@ -7806,7 +7821,7 @@ package body Sem_Ch4 is
-- In_Parameter, but for now we examine the formal that
-- corresponds to the indexing, and assume that variable
-- indexing is required if some interpretation has an
- -- assignable formal at that position. Still does not
+ -- assignable formal at that position. Still does not
-- cover the most complex cases ???
if Is_Overloaded (Name (Parent (Par))) then
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 88fd204..ebe610b 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -2234,8 +2234,17 @@ package body Sem_Ch5 is
It : Interp;
begin
+ -- THe domain of iteralion must implement either the RM
+ -- iterator interface, or the SPARK Iterable aspect.
+
if No (Iterator) then
- null; -- error reported below
+ if No
+ (Find_Aspect (Etype (Iter_Name), Aspect_Iterable))
+ then
+ Error_Msg_NE ("cannot iterate over&",
+ N, Base_Type (Etype (Iter_Name)));
+ return;
+ end if;
elsif not Is_Overloaded (Iterator) then
Check_Reverse_Iteration (Etype (Iterator));
@@ -3080,7 +3089,7 @@ package body Sem_Ch5 is
else
-- A quantified expression that appears in a pre/post condition
- -- is preanalyzed several times. If the range is given by an
+ -- is preanalyzed several times. If the range is given by an
-- attribute reference it is rewritten as a range, and this is
-- done even with expansion disabled. If the type is already set
-- do not reanalyze, because a range with static bounds may be
@@ -3904,7 +3913,7 @@ package body Sem_Ch5 is
-- If the expander is not active then we want to analyze the loop body
-- now even in the Ada 2012 iterator case, since the rewriting will not
-- be done. Insert the loop variable in the current scope, if not done
- -- when analysing the iteration scheme. Set its kind properly to detect
+ -- when analysing the iteration scheme. Set its kind properly to detect
-- improper uses in the loop body.
-- In GNATprove mode, we do one of the above depending on the kind of
@@ -3998,7 +4007,7 @@ package body Sem_Ch5 is
-- Variables referenced within a loop subject to possible OpenACC
-- offloading may be implicitly written to as part of the OpenACC
- -- transaction. Clear flags possibly conveying that they are constant,
+ -- transaction. Clear flags possibly conveying that they are constant,
-- set for example when the code does not explicitly assign them.
if Is_OpenAcc_Environment (Stmt) then
@@ -4062,7 +4071,7 @@ package body Sem_Ch5 is
end if;
-- If we failed to find a label, it means the implicit declaration
- -- of the label was hidden. A for-loop parameter can do this to
+ -- of the label was hidden. A for-loop parameter can do this to
-- a label with the same name inside the loop, since the implicit
-- label declaration is in the innermost enclosing body or block
-- statement.
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index cf1b0e7..25ee705 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -3689,7 +3689,7 @@ package body Sem_Ch6 is
-- generated. Freeze nodes, if any, are inserted before the current
-- body. These freeze actions are also needed in ASIS mode and in
-- Compile_Only mode to enable the proper back-end type annotations.
- -- They are necessary in any case to insure order of elaboration
+ -- They are necessary in any case to ensure proper elaboration order
-- in gigi.
if Nkind (N) = N_Subprogram_Body
@@ -3698,13 +3698,16 @@ package body Sem_Ch6 is
and then Serious_Errors_Detected = 0
and then (Expander_Active
or else ASIS_Mode
- or else Operating_Mode = Check_Semantics)
+ or else Operating_Mode = Check_Semantics
+ or else Is_Ignored_Ghost_Entity (Spec_Id))
then
-- The body generated for an expression function that is not a
-- completion is a freeze point neither for the profile nor for
-- anything else. That's why, in order to prevent any freezing
-- during analysis, we need to mask types declared outside the
-- expression (and in an outer scope) that are not yet frozen.
+ -- This also needs to be done in the case of an ignored Ghost
+ -- expression function, where the expander isn't active.
Set_Is_Frozen (Spec_Id);
Mask_Types := Mask_Unfrozen_Types (Spec_Id);
@@ -5957,7 +5960,7 @@ package body Sem_Ch6 is
Access_Definition (N, Discriminant_Type (New_Discr));
else
- Analyze (Discriminant_Type (New_Discr));
+ Find_Type (Discriminant_Type (New_Discr));
New_Discr_Type := Etype (Discriminant_Type (New_Discr));
-- Ada 2005: if the discriminant definition carries a null
@@ -10152,7 +10155,7 @@ package body Sem_Ch6 is
-- Here, S is "function ... return T;" declared in
-- the private part, not overriding some visible
- -- operation. That's illegal in the tagged case
+ -- operation. That's illegal in the tagged case
-- (but not if the private type is untagged).
if ((Present (Partial_View)
@@ -11339,7 +11342,13 @@ package body Sem_Ch6 is
goto Continue;
end if;
- Formal_Type := Entity (Ptype);
+ -- Protect against malformed parameter types
+
+ if Nkind (Ptype) not in N_Has_Entity then
+ Formal_Type := Any_Type;
+ else
+ Formal_Type := Entity (Ptype);
+ end if;
if Is_Incomplete_Type (Formal_Type)
or else
diff --git a/gcc/ada/sem_ch6.ads b/gcc/ada/sem_ch6.ads
index 9e7f858..f069947 100644
--- a/gcc/ada/sem_ch6.ads
+++ b/gcc/ada/sem_ch6.ads
@@ -100,7 +100,7 @@ package Sem_Ch6 is
Overridden_Subp : Entity_Id;
Is_Primitive : Boolean);
-- Verify the consistency of an overriding_indicator given for subprogram
- -- declaration, body, renaming, or instantiation. Overridden_Subp is set
+ -- declaration, body, renaming, or instantiation. Overridden_Subp is set
-- if the scope where we are introducing the subprogram contains a
-- type-conformant subprogram that becomes hidden by the new subprogram.
-- Is_Primitive indicates whether the subprogram is primitive.
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index 6f5126e..e0d20ef 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -790,7 +790,7 @@ package body Sem_Ch7 is
-- Deactivate expansion inside the body of ignored Ghost entities,
-- as this code will ultimately be ignored. This avoids requiring the
-- presence of run-time units which are not needed. Only do this for
- -- user entities, as internally generated entitities might still need
+ -- user entities, as internally generated entities might still need
-- to be expanded (e.g. those generated for types).
if Present (Ignored_Ghost_Region)
@@ -1063,7 +1063,7 @@ package body Sem_Ch7 is
-- to the linker as their Is_Public flag is set to True. This proactive
-- approach is necessary because an inlined or a generic body for which
-- code is generated in other units may need to see these entities. Cut
- -- down the number of global symbols that do not neet public visibility
+ -- down the number of global symbols that do not need public visibility
-- as this has two beneficial effects:
-- (1) It makes the compilation process more efficient.
-- (2) It gives the code generator more leeway to optimize within each
@@ -1757,7 +1757,7 @@ package body Sem_Ch7 is
end if;
-- There may be inherited private subprograms that need to be declared,
- -- even in the absence of an explicit private part. If there are any
+ -- even in the absence of an explicit private part. If there are any
-- public declarations in the package and the package is a public child
-- unit, then an implicit private part is assumed.
@@ -1883,7 +1883,7 @@ package body Sem_Ch7 is
end if;
-- Nested package specs that do not require bodies are not checked for
- -- ineffective use clauses due to the possbility of subunits. This is
+ -- ineffective use clauses due to the possibility of subunits. This is
-- because at this stage it is impossible to tell whether there will be
-- a separate body.
@@ -2261,7 +2261,7 @@ package body Sem_Ch7 is
procedure Swap_Private_Dependents (Priv_Deps : Elist_Id);
-- When the full view of a private type is made available, we do the
-- same for its private dependents under proper visibility conditions.
- -- When compiling a grand-chid unit this needs to be done recursively.
+ -- When compiling a grandchild unit this needs to be done recursively.
-----------------------------
-- Swap_Private_Dependents --
@@ -3196,7 +3196,7 @@ package body Sem_Ch7 is
E : Entity_Id;
Requires_Body : Boolean := False;
- -- Flag set when the unit has at least one construct that requries
+ -- Flag set when the unit has at least one construct that requires
-- completion in a body.
begin
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index b58ad64..7185c40 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -774,6 +774,10 @@ package body Sem_Ch8 is
-- has already established its actual subtype. This is only relevant
-- if the renamed object is an explicit dereference.
+ function Get_Object_Name (Nod : Node_Id) return Node_Id;
+ -- Obtain the name of the object from node Nod which is being renamed by
+ -- the object renaming declaration N.
+
------------------------------
-- Check_Constrained_Object --
------------------------------
@@ -802,17 +806,15 @@ package body Sem_Ch8 is
null;
-- If a record is limited its size is invariant. This is the case
- -- in particular with record types with an access discirminant
+ -- in particular with record types with an access discriminant
-- that are used in iterators. This is an optimization, but it
-- also prevents typing anomalies when the prefix is further
- -- expanded. Limited types with discriminants are included.
+ -- expanded.
+ -- Note that we cannot just use the Is_Limited_Record flag because
+ -- it does not apply to records with limited components, for which
+ -- this syntactic flag is not set, but whose size is also fixed.
- elsif Is_Limited_Record (Typ)
- or else
- (Ekind (Typ) = E_Limited_Private_Type
- and then Has_Discriminants (Typ)
- and then Is_Access_Type (Etype (First_Discriminant (Typ))))
- then
+ elsif Is_Limited_Type (Typ) then
null;
else
@@ -835,6 +837,33 @@ package body Sem_Ch8 is
end if;
end Check_Constrained_Object;
+ ---------------------
+ -- Get_Object_Name --
+ ---------------------
+
+ function Get_Object_Name (Nod : Node_Id) return Node_Id is
+ Obj_Nam : Node_Id;
+
+ begin
+ Obj_Nam := Nod;
+ while Present (Obj_Nam) loop
+ if Nkind_In (Obj_Nam, N_Attribute_Reference,
+ N_Explicit_Dereference,
+ N_Indexed_Component,
+ N_Slice)
+ then
+ Obj_Nam := Prefix (Obj_Nam);
+
+ elsif Nkind (Obj_Nam) = N_Selected_Component then
+ Obj_Nam := Selector_Name (Obj_Nam);
+ else
+ exit;
+ end if;
+ end loop;
+
+ return Obj_Nam;
+ end Get_Object_Name;
+
-- Start of processing for Analyze_Object_Renaming
begin
@@ -1151,18 +1180,10 @@ package body Sem_Ch8 is
elsif Ada_Version >= Ada_2005 and then Nkind (Nam) in N_Has_Entity then
declare
- Nam_Decl : Node_Id;
- Nam_Ent : Entity_Id;
+ Nam_Ent : constant Entity_Id := Entity (Get_Object_Name (Nam));
+ Nam_Decl : constant Node_Id := Declaration_Node (Nam_Ent);
begin
- if Nkind (Nam) = N_Attribute_Reference then
- Nam_Ent := Entity (Prefix (Nam));
- else
- Nam_Ent := Entity (Nam);
- end if;
-
- Nam_Decl := Parent (Nam_Ent);
-
if Has_Null_Exclusion (N)
and then not Has_Null_Exclusion (Nam_Decl)
then
@@ -4815,6 +4836,13 @@ package body Sem_Ch8 is
Set_In_Use (Base_Type (T), False);
Set_Current_Use_Clause (T, Empty);
Set_Current_Use_Clause (Base_Type (T), Empty);
+
+ -- See Use_One_Type for the rationale. This is a bit on the naive
+ -- side, but should be good enough in practice.
+
+ if Is_Tagged_Type (T) then
+ Set_In_Use (Class_Wide_Type (T), False);
+ end if;
end if;
end if;
@@ -8733,7 +8761,7 @@ package body Sem_Ch8 is
if Scope_Stack.Last > Scope_Stack.First then
SST.Component_Alignment_Default :=
Scope_Stack.Table
- (Scope_Stack.Last - 1). Component_Alignment_Default;
+ (Scope_Stack.Last - 1).Component_Alignment_Default;
-- Otherwise, this is the first scope being pushed on the scope
-- stack. Inherit the component alignment from the configuration
@@ -9964,7 +9992,10 @@ package body Sem_Ch8 is
Set_In_Use (T);
-- If T is tagged, primitive operators on class-wide operands are
- -- also available.
+ -- also deemed available. Note that this is really necessary only
+ -- in semantics-only mode, because the primitive operators are not
+ -- fully constructed in this mode, but we do it in all modes for the
+ -- sake of uniformity, as this should not matter in practice.
if Is_Tagged_Type (T) then
Set_In_Use (Class_Wide_Type (T));
diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index a71c35c..0696f92 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -883,7 +883,13 @@ package body Sem_Ch9 is
exit when Task_Nam = Scope_Stack.Table (J).Entity;
if Entry_Nam = Scope_Stack.Table (J).Entity then
- Error_Msg_N ("duplicate accept statement for same entry", N);
+ Error_Msg_N
+ ("duplicate accept statement for same entry (RM 9.5.2 (15))", N);
+
+ -- Do not continue analysis of accept statement, to prevent
+ -- cascaded errors.
+
+ return;
end if;
end loop;
@@ -1891,9 +1897,6 @@ package body Sem_Ch9 is
----------------------------------
procedure Analyze_Protected_Definition (N : Node_Id) is
- E : Entity_Id;
- L : Entity_Id;
-
procedure Undelay_Itypes (T : Entity_Id);
-- Itypes created for the private components of a protected type
-- do not receive freeze nodes, because there is no scope in which
@@ -1926,9 +1929,7 @@ package body Sem_Ch9 is
end if;
while Present (Comp) loop
- if Is_Type (Comp)
- and then Is_Itype (Comp)
- then
+ if Is_Type (Comp) and then Is_Itype (Comp) then
Set_Has_Delayed_Freeze (Comp, False);
Set_Is_Frozen (Comp);
@@ -1936,9 +1937,7 @@ package body Sem_Ch9 is
Layout_Type (Comp);
end if;
- if Is_Record_Type (Comp)
- or else Is_Protected_Type (Comp)
- then
+ if Is_Record_Type (Comp) or else Is_Protected_Type (Comp) then
Undelay_Itypes (Comp);
end if;
end if;
@@ -1947,6 +1946,12 @@ package body Sem_Ch9 is
end loop;
end Undelay_Itypes;
+ -- Local variables
+
+ Prot_Typ : constant Entity_Id := Current_Scope;
+ Item_Id : Entity_Id;
+ Last_Id : Entity_Id;
+
-- Start of processing for Analyze_Protected_Definition
begin
@@ -1957,32 +1962,37 @@ package body Sem_Ch9 is
if Present (Private_Declarations (N))
and then not Is_Empty_List (Private_Declarations (N))
then
- L := Last_Entity (Current_Scope);
+ Last_Id := Last_Entity (Prot_Typ);
Analyze_Declarations (Private_Declarations (N));
- if Present (L) then
- Set_First_Private_Entity (Current_Scope, Next_Entity (L));
+ if Present (Last_Id) then
+ Set_First_Private_Entity (Prot_Typ, Next_Entity (Last_Id));
else
- Set_First_Private_Entity (Current_Scope,
- First_Entity (Current_Scope));
+ Set_First_Private_Entity (Prot_Typ, First_Entity (Prot_Typ));
end if;
end if;
- E := First_Entity (Current_Scope);
- while Present (E) loop
- if Ekind_In (E, E_Function, E_Procedure) then
- Set_Convention (E, Convention_Protected);
+ Item_Id := First_Entity (Prot_Typ);
+ while Present (Item_Id) loop
+ if Ekind_In (Item_Id, E_Function, E_Procedure) then
+ Set_Convention (Item_Id, Convention_Protected);
else
- Propagate_Concurrent_Flags (Current_Scope, Etype (E));
+ Propagate_Concurrent_Flags (Prot_Typ, Etype (Item_Id));
+
+ if Chars (Item_Id) /= Name_uParent
+ and then Needs_Finalization (Etype (Item_Id))
+ then
+ Set_Has_Controlled_Component (Prot_Typ);
+ end if;
end if;
- Next_Entity (E);
+ Next_Entity (Item_Id);
end loop;
- Undelay_Itypes (Current_Scope);
+ Undelay_Itypes (Prot_Typ);
Check_Max_Entries (N, Max_Protected_Entries);
- Process_End_Label (N, 'e', Current_Scope);
+ Process_End_Label (N, 'e', Prot_Typ);
end Analyze_Protected_Definition;
----------------------------------------
diff --git a/gcc/ada/sem_dim.adb b/gcc/ada/sem_dim.adb
index 43b1f23..2bcccd2 100644
--- a/gcc/ada/sem_dim.adb
+++ b/gcc/ada/sem_dim.adb
@@ -115,7 +115,7 @@ package body Sem_Dim is
type Symbol_Array is
array (Dimension_Position range
- Low_Position_Bound .. High_Position_Bound) of String_Id;
+ Low_Position_Bound .. High_Position_Bound) of String_Id;
-- Store the symbols of all units within a system
No_Symbols : constant Symbol_Array := (others => No_String);
@@ -151,7 +151,7 @@ package body Sem_Dim is
type Dimension_Type is
array (Dimension_Position range
- Low_Position_Bound .. High_Position_Bound) of Rational;
+ Low_Position_Bound .. High_Position_Bound) of Rational;
Null_Dimension : constant Dimension_Type := (others => Zero);
@@ -399,9 +399,9 @@ package body Sem_Dim is
function "+" (Left, Right : Rational) return Rational is
R : constant Rational :=
- Rational'(Numerator => Left.Numerator * Right.Denominator +
- Left.Denominator * Right.Numerator,
- Denominator => Left.Denominator * Right.Denominator);
+ Rational'(Numerator => Left.Numerator * Right.Denominator +
+ Left.Denominator * Right.Numerator,
+ Denominator => Left.Denominator * Right.Denominator);
begin
return Reduce (R);
end "+";
@@ -1233,8 +1233,9 @@ package body Sem_Dim is
Dims_Of_Comp_Typ : constant Dimension_Type := Dimensions_Of (Comp_Typ);
Exps : constant List_Id := Expressions (N);
- Comp : Node_Id;
- Expr : Node_Id;
+ Comp : Node_Id;
+ Dims_Of_Expr : Dimension_Type;
+ Expr : Node_Id;
Error_Detected : Boolean := False;
-- This flag is used in order to indicate if an error has been detected
@@ -1281,11 +1282,19 @@ package body Sem_Dim is
-- (may happen when an aggregate is converted into a positional
-- aggregate). We also must verify that this is a scalar component,
-- and not a subaggregate of a multidimensional aggregate.
+ -- The expression may be an identifier that has been copied several
+ -- times during expansion, its dimensions are those of its type.
+
+ if Is_Entity_Name (Expr) then
+ Dims_Of_Expr := Dimensions_Of (Etype (Expr));
+ else
+ Dims_Of_Expr := Dimensions_Of (Expr);
+ end if;
if Comes_From_Source (Original_Node (Expr))
and then Present (Etype (Expr))
and then Is_Numeric_Type (Etype (Expr))
- and then Dimensions_Of (Expr) /= Dims_Of_Comp_Typ
+ and then Dims_Of_Expr /= Dims_Of_Comp_Typ
and then Sloc (Comp) /= Sloc (Prev (Comp))
then
-- Check if an error has already been encountered so far
@@ -2897,7 +2906,7 @@ package body Sem_Dim is
New_Aspects := Empty_List;
List_Of_Dims := New_List;
- for Position in Dims_Of_N'First .. System.Count loop
+ for Position in Dims_Of_N'First .. System.Count loop
Dim_Power := Dims_Of_N (Position);
Append_To (List_Of_Dims,
Make_Op_Divide (Loc,
@@ -3014,7 +3023,7 @@ package body Sem_Dim is
-- System.Dim.Float_IO or System.Dim.Integer_IO, the default string
-- parameter is rewritten to include the unit symbol (or the dimension
-- symbols if not a defined quantity) in the output of a dimensioned
- -- object. If a value is already supplied by the user for the parameter
+ -- object. If a value is already supplied by the user for the parameter
-- Symbol, it is used as is.
-- Case 1. Item is dimensionless
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index a2f753b..5deba18 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -211,6 +211,15 @@ package body Sem_Disp is
if Present (Ctrl_Type) then
+ -- Obtain the full type in case we are looking at an incomplete
+ -- view.
+
+ if Ekind (Ctrl_Type) = E_Incomplete_Type
+ and then Present (Full_View (Ctrl_Type))
+ then
+ Ctrl_Type := Full_View (Ctrl_Type);
+ end if;
+
-- When controlling type is concurrent and declared within a
-- generic or inside an instance use corresponding record type.
@@ -587,7 +596,7 @@ package body Sem_Disp is
-- We need to determine whether the context of the call
-- provides a tag to make the call dispatching. This requires
-- the call to be the actual in an enclosing call, and that
- -- actual must be controlling. If the call is an operand of
+ -- actual must be controlling. If the call is an operand of
-- equality, the other operand must not ve abstract.
if not Is_Tagged_Type (Typ)
diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
index f57b3b1..3145559 100644
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -496,12 +496,6 @@ package body Sem_Elab is
-- actual subprograms through generic formal subprograms. As a
-- result, the calls are not recorded or processed.
--
- -- -gnatd_G encode invocation graph in ALI files
- --
- -- The ABE mechanism encodes the invocation graph of the main
- -- unit. This includes elaboration code, as well as invocation
- -- constructs.
- --
-- -gnatd_i ignore activations and calls to instances for elaboration
--
-- The ABE mechanism ignores calls and task activations when they
@@ -676,6 +670,22 @@ package body Sem_Elab is
-- Kinds --
-----------
+ -- The following type enumerates all possible elaboration phase statutes
+
+ type Elaboration_Phase_Status is
+ (Inactive,
+ -- The elaboration phase of the compiler has not started yet
+
+ Active,
+ -- The elaboration phase of the compiler is currently in progress
+
+ Completed);
+ -- The elaboration phase of the compiler has finished
+
+ Elaboration_Phase : Elaboration_Phase_Status := Inactive;
+ -- The status of the elaboration phase. Use routine Set_Elaboration_Phase
+ -- to alter its value.
+
-- The following type enumerates all subprogram body traversal modes
type Body_Traversal_Kind is
@@ -772,6 +782,9 @@ package body Sem_Elab is
(Generic_Target,
-- A generic unit being instantiated
+ Package_Target,
+ -- The package form of an instantiation
+
Subprogram_Target,
-- An entry, operator, or subprogram being invoked, or aliased through
-- 'Access or 'Unrestricted_Access.
@@ -1958,6 +1971,14 @@ package body Sem_Elab is
-- Return the type of subprogram Subp_Id's first formal parameter. If the
-- subprogram lacks formal parameters, return Empty.
+ function Elaboration_Phase_Active return Boolean;
+ pragma Inline (Elaboration_Phase_Active);
+ -- Determine whether the elaboration phase of the compilation has started
+
+ procedure Finalize_All_Data_Structures;
+ pragma Inline (Finalize_All_Data_Structures);
+ -- Destroy all internal data structures
+
function Has_Body (Pack_Decl : Node_Id) return Boolean;
pragma Inline (Has_Body);
-- Determine whether package declaration Pack_Decl has a corresponding body
@@ -1984,6 +2005,10 @@ package body Sem_Elab is
-- context ignoring enclosing library levels. Nested_OK should be set when
-- the context of N1 can enclose that of N2.
+ procedure Initialize_All_Data_Structures;
+ pragma Inline (Initialize_All_Data_Structures);
+ -- Create all internal data structures
+
function Instantiated_Generic (Inst : Node_Id) return Entity_Id;
pragma Inline (Instantiated_Generic);
-- Obtain the generic instantiated by instance Inst
@@ -2018,6 +2043,10 @@ package body Sem_Elab is
pragma Inline (Is_Same_Unit);
-- Determine whether entities Unit_1 and Unit_2 denote the same unit
+ function Main_Unit_Entity return Entity_Id;
+ pragma Inline (Main_Unit_Entity);
+ -- Return the entity of the main unit
+
function Non_Private_View (Typ : Entity_Id) return Entity_Id;
pragma Inline (Non_Private_View);
-- Return the full view of private type Typ if available, otherwise return
@@ -2027,6 +2056,10 @@ package body Sem_Elab is
pragma Inline (Scenario);
-- Return the appropriate scenario node for scenario N
+ procedure Set_Elaboration_Phase (Status : Elaboration_Phase_Status);
+ pragma Inline (Set_Elaboration_Phase);
+ -- Change the status of the elaboration phase of the compiler to Status
+
procedure Spec_And_Body_From_Entity
(Id : Node_Id;
Spec_Decl : out Node_Id;
@@ -3572,6 +3605,12 @@ package body Sem_Elab is
elsif Preanalysis_Active then
return;
+ -- Nothing to do when the elaboration phase of the compiler is not
+ -- active.
+
+ elsif not Elaboration_Phase_Active then
+ return;
+
-- Nothing to do when the input does not denote a call or a requeue
elsif not Nkind_In (N, N_Entry_Call_Statement,
@@ -3789,6 +3828,13 @@ package body Sem_Elab is
-- Start of processing for Build_Variable_Reference_Marker
begin
+ -- Nothing to do when the elaboration phase of the compiler is not
+ -- active.
+
+ if not Elaboration_Phase_Active then
+ return;
+ end if;
+
Marker := Make_Variable_Reference_Marker (Sloc (N));
-- Inherit the attributes of the original variable reference
@@ -3887,30 +3933,30 @@ package body Sem_Elab is
-- to carry out this action.
if Legacy_Elaboration_Checks then
+ Finalize_All_Data_Structures;
return;
-- Nothing to do for ASIS because ABE checks and diagnostics are not
-- performed in this mode.
elsif ASIS_Mode then
+ Finalize_All_Data_Structures;
return;
- end if;
- -- Create all internal data structures
+ -- Nothing to do when the elaboration phase of the compiler is not
+ -- active.
- Initialize_Body_Processor;
- Initialize_Early_Call_Region_Processor;
- Initialize_Elaborated_Units;
- Initialize_Internal_Representation;
- Initialize_Invocation_Graph;
- Initialize_Scenario_Storage;
+ elsif not Elaboration_Phase_Active then
+ Finalize_All_Data_Structures;
+ return;
+ end if;
-- Restore the original elaboration model which was in effect when the
-- scenarios were first recorded. The model may be specified by pragma
-- Elaboration_Checks which appears on the initial declaration of the
-- main unit.
- Install_Elaboration_Model (Unit_Entity (Cunit_Entity (Main_Unit)));
+ Install_Elaboration_Model (Unit_Entity (Main_Unit_Entity));
-- Examine the context of the main unit and record all units with prior
-- elaboration with respect to it.
@@ -3949,14 +3995,11 @@ package body Sem_Elab is
Record_Invocation_Graph;
- -- Destroy all internal data structures
+ -- Destroy all internal data structures and complete the elaboration
+ -- phase of the compiler.
- Finalize_Body_Processor;
- Finalize_Early_Call_Region_Processor;
- Finalize_Elaborated_Units;
- Finalize_Internal_Representation;
- Finalize_Invocation_Graph;
- Finalize_Scenario_Storage;
+ Finalize_All_Data_Structures;
+ Set_Elaboration_Phase (Completed);
end Check_Elaboration_Scenarios;
---------------------
@@ -6302,7 +6345,7 @@ package body Sem_Elab is
-- because diagnostics on reads are relevant only for external
-- variables.
- if Is_Same_Unit (Unit_Id, Cunit_Entity (Main_Unit)) then
+ if Is_Same_Unit (Unit_Id, Main_Unit_Entity) then
null;
-- Nothing to do when the variable is already initialized. Note that
@@ -7676,8 +7719,7 @@ package body Sem_Elab is
-- The following map relates an elaboration attributes of a unit to the
-- unit.
- Unit_To_Attributes_Map : UA_Map.Dynamic_Hash_Table :=
- UA_Map.Create (250);
+ Unit_To_Attributes_Map : UA_Map.Dynamic_Hash_Table := UA_Map.Nil;
------------------
-- Constructors --
@@ -8122,7 +8164,7 @@ package body Sem_Elab is
-- body of A elaborated <-- problem
--
-- The generation of an implicit pragma Elaborate_All (B) ensures
- -- that the elaboration order mechanism will not pick the above
+ -- that the elaboration-order mechanism will not pick the above
-- order.
--
-- An implicit Elaborate is NOT generated when the unit is subject
@@ -8461,10 +8503,9 @@ package body Sem_Elab is
Elab_Body_OK : Boolean := False;
Same_Unit_OK : Boolean := False) return Boolean
is
- EA_Id : constant Elaboration_Attributes_Id :=
- Elaboration_Attributes_Of (Unit_Id);
-
- Main_Id : constant Entity_Id := Cunit_Entity (Main_Unit);
+ EA_Id : constant Elaboration_Attributes_Id :=
+ Elaboration_Attributes_Of (Unit_Id);
+ Main_Id : constant Entity_Id := Main_Unit_Entity;
Unit_Prag : constant Node_Id := Elab_Pragma (EA_Id);
Unit_With : constant Node_Id := With_Clause (EA_Id);
@@ -8519,7 +8560,7 @@ package body Sem_Elab is
procedure Initialize_Elaborated_Units is
begin
- null;
+ Unit_To_Attributes_Map := UA_Map.Create (250);
end Initialize_Elaborated_Units;
----------------------------------
@@ -8534,7 +8575,7 @@ package body Sem_Elab is
is
pragma Assert (Nam_In (Req_Nam, Name_Elaborate, Name_Elaborate_All));
- Main_Id : constant Entity_Id := Cunit_Entity (Main_Unit);
+ Main_Id : constant Entity_Id := Main_Unit_Entity;
Unit_Id : constant Entity_Id := Find_Top_Unit (Targ_Id);
procedure Elaboration_Requirement_Error;
@@ -8800,6 +8841,29 @@ package body Sem_Elab is
end With_Clause;
end Elaborated_Units;
+ ------------------------------
+ -- Elaboration_Phase_Active --
+ ------------------------------
+
+ function Elaboration_Phase_Active return Boolean is
+ begin
+ return Elaboration_Phase = Active;
+ end Elaboration_Phase_Active;
+
+ ----------------------------------
+ -- Finalize_All_Data_Structures --
+ ----------------------------------
+
+ procedure Finalize_All_Data_Structures is
+ begin
+ Finalize_Body_Processor;
+ Finalize_Early_Call_Region_Processor;
+ Finalize_Elaborated_Units;
+ Finalize_Internal_Representation;
+ Finalize_Invocation_Graph;
+ Finalize_Scenario_Storage;
+ end Finalize_All_Data_Structures;
+
-----------------------------
-- Find_Enclosing_Instance --
-----------------------------
@@ -10072,8 +10136,28 @@ package body Sem_Elab is
-- each time it is transformed into another node.
Set_Rewriting_Proc (Update_Elaboration_Scenario'Access);
+
+ -- Create all internal data structures and activate the elaboration
+ -- phase of the compiler.
+
+ Initialize_All_Data_Structures;
+ Set_Elaboration_Phase (Active);
end Initialize;
+ ------------------------------------
+ -- Initialize_All_Data_Structures --
+ ------------------------------------
+
+ procedure Initialize_All_Data_Structures is
+ begin
+ Initialize_Body_Processor;
+ Initialize_Early_Call_Region_Processor;
+ Initialize_Elaborated_Units;
+ Initialize_Internal_Representation;
+ Initialize_Invocation_Graph;
+ Initialize_Scenario_Storage;
+ end Initialize_All_Data_Structures;
+
--------------------------
-- Instantiated_Generic --
--------------------------
@@ -10201,8 +10285,7 @@ package body Sem_Elab is
-- The following map relates target representations to entities
- Entity_To_Target_Map : ETT_Map.Dynamic_Hash_Table :=
- ETT_Map.Create (500);
+ Entity_To_Target_Map : ETT_Map.Dynamic_Hash_Table := ETT_Map.Nil;
procedure Destroy (S_Id : in out Scenario_Rep_Id);
-- Destroy a scenario representation S_Id
@@ -10221,8 +10304,7 @@ package body Sem_Elab is
-- The following map relates scenario representations to nodes
- Node_To_Scenario_Map : NTS_Map.Dynamic_Hash_Table :=
- NTS_Map.Create (500);
+ Node_To_Scenario_Map : NTS_Map.Dynamic_Hash_Table := NTS_Map.Nil;
-- The following table stores all scenario representations
@@ -10274,6 +10356,11 @@ package body Sem_Elab is
pragma Inline (Create_Instantiation_Rep);
-- Create the representation of instantiation Inst
+ function Create_Package_Rep
+ (Pack_Id : Entity_Id) return Target_Rep_Record;
+ pragma Inline (Create_Package_Rep);
+ -- Create the representation of package Pack_Id
+
function Create_Protected_Entry_Rep
(PE_Id : Entity_Id) return Target_Rep_Record;
pragma Inline (Create_Protected_Entry_Rep);
@@ -10542,6 +10629,26 @@ package body Sem_Elab is
return Rec;
end Create_Instantiation_Rep;
+ ------------------------
+ -- Create_Package_Rep --
+ ------------------------
+
+ function Create_Package_Rep
+ (Pack_Id : Entity_Id) return Target_Rep_Record
+ is
+ Rec : Target_Rep_Record;
+
+ begin
+ Rec.Kind := Package_Target;
+
+ Spec_And_Body_From_Entity
+ (Id => Pack_Id,
+ Body_Decl => Rec.Body_Decl,
+ Spec_Decl => Rec.Spec_Decl);
+
+ return Rec;
+ end Create_Package_Rep;
+
--------------------------------
-- Create_Protected_Entry_Rep --
--------------------------------
@@ -10764,6 +10871,9 @@ package body Sem_Elab is
then
Rec := Create_Subprogram_Rep (Id);
+ elsif Ekind (Id) = E_Package then
+ Rec := Create_Package_Rep (Id);
+
else
pragma Assert (False);
return Rec;
@@ -11058,7 +11168,8 @@ package body Sem_Elab is
procedure Initialize_Internal_Representation is
begin
- null;
+ Entity_To_Target_Map := ETT_Map.Create (500);
+ Node_To_Scenario_Map := NTS_Map.Create (500);
end Initialize_Internal_Representation;
-------------------------
@@ -11539,6 +11650,14 @@ package body Sem_Elab is
-- Process invocation call scenario Call with representation Call_Rep.
-- In_State is the current state of the Processing phase.
+ procedure Process_Invocation_Instantiation
+ (Inst : Node_Id;
+ Inst_Rep : Scenario_Rep_Id;
+ In_State : Processing_In_State);
+ pragma Inline (Process_Invocation_Instantiation);
+ -- Process invocation instantiation scenario Inst with representation
+ -- Inst_Rep. In_State is the current state of the Processing phase.
+
procedure Process_Invocation_Scenario
(N : Node_Id;
In_State : Processing_In_State);
@@ -11606,6 +11725,11 @@ package body Sem_Elab is
-- active scenarios. In_State is the current state of the Processing
-- phase.
+ procedure Record_Invocation_Graph_Encoding;
+ pragma Inline (Record_Invocation_Graph_Encoding);
+ -- Record the encoding format used to capture information related to
+ -- invocation constructs and relations.
+
procedure Record_Invocation_Path (In_State : Processing_In_State);
pragma Inline (Record_Invocation_Path);
-- Record the invocation relations found within the path represented in
@@ -11679,7 +11803,7 @@ package body Sem_Elab is
end if;
Spec_And_Body_From_Entity
- (Id => Cunit_Entity (Main_Unit),
+ (Id => Main_Unit_Entity,
Body_Decl => Body_Decl,
Spec_Decl => Spec_Decl);
@@ -11711,7 +11835,7 @@ package body Sem_Elab is
Set_Ekind (Proc_Id, E_Procedure);
Set_Etype (Proc_Id, Standard_Void_Type);
- Set_Scope (Proc_Id, Unique_Entity (Cunit_Entity (Main_Unit)));
+ Set_Scope (Proc_Id, Unique_Entity (Main_Unit_Entity));
-- Create a dummy declaration for the elaboration procedure. The
-- declaration does not need to be syntactically legal, but must
@@ -11742,7 +11866,7 @@ package body Sem_Elab is
end if;
Spec_And_Body_From_Entity
- (Id => Cunit_Entity (Main_Unit),
+ (Id => Main_Unit_Entity,
Body_Decl => Body_Decl,
Spec_Decl => Spec_Decl);
@@ -11855,40 +11979,32 @@ package body Sem_Elab is
(Constr_Id : Entity_Id;
In_State : Processing_In_State)
is
+ function Body_Placement_Of
+ (Id : Entity_Id) return Declaration_Placement_Kind;
+ pragma Inline (Body_Placement_Of);
+ -- Obtain the placement of arbitrary entity Id's body
+
+ function Declaration_Placement_Of_Node
+ (N : Node_Id) return Declaration_Placement_Kind;
+ pragma Inline (Declaration_Placement_Of_Node);
+ -- Obtain the placement of arbitrary node N
+
function Kind_Of (Id : Entity_Id) return Invocation_Construct_Kind;
pragma Inline (Kind_Of);
-- Obtain the invocation construct kind of arbitrary entity Id
- function Placement_Of (Id : Entity_Id) return Body_Placement_Kind;
- pragma Inline (Placement_Of);
- -- Obtain the body placement of arbitrary entity Id
-
- function Placement_Of_Node (N : Node_Id) return Body_Placement_Kind;
- pragma Inline (Placement_Of_Node);
- -- Obtain the body placement of arbitrary node N
-
- -------------
- -- Kind_Of --
- -------------
+ function Spec_Placement_Of
+ (Id : Entity_Id) return Declaration_Placement_Kind;
+ pragma Inline (Spec_Placement_Of);
+ -- Obtain the placement of arbitrary entity Id's spec
- function Kind_Of (Id : Entity_Id) return Invocation_Construct_Kind is
- begin
- if Id = Elab_Body_Id then
- return Elaborate_Body_Procedure;
-
- elsif Id = Elab_Spec_Id then
- return Elaborate_Spec_Procedure;
-
- else
- return Regular_Construct;
- end if;
- end Kind_Of;
-
- ------------------
- -- Placement_Of --
- ------------------
+ -----------------------
+ -- Body_Placement_Of --
+ -----------------------
- function Placement_Of (Id : Entity_Id) return Body_Placement_Kind is
+ function Body_Placement_Of
+ (Id : Entity_Id) return Declaration_Placement_Kind
+ is
Id_Rep : constant Target_Rep_Id :=
Target_Representation_Of (Id, In_State);
Body_Decl : constant Node_Id := Body_Declaration (Id_Rep);
@@ -11898,22 +12014,24 @@ package body Sem_Elab is
-- The entity has a body
if Present (Body_Decl) then
- return Placement_Of_Node (Body_Decl);
+ return Declaration_Placement_Of_Node (Body_Decl);
-- Otherwise the entity must have a spec
else
pragma Assert (Present (Spec_Decl));
- return Placement_Of_Node (Spec_Decl);
+ return Declaration_Placement_Of_Node (Spec_Decl);
end if;
- end Placement_Of;
+ end Body_Placement_Of;
- -----------------------
- -- Placement_Of_Node --
- -----------------------
+ -----------------------------------
+ -- Declaration_Placement_Of_Node --
+ -----------------------------------
- function Placement_Of_Node (N : Node_Id) return Body_Placement_Kind is
- Main_Unit_Id : constant Entity_Id := Cunit_Entity (Main_Unit);
+ function Declaration_Placement_Of_Node
+ (N : Node_Id) return Declaration_Placement_Kind
+ is
+ Main_Unit_Id : constant Entity_Id := Main_Unit_Entity;
N_Unit_Id : constant Entity_Id := Find_Top_Unit (N);
begin
@@ -11956,11 +12074,50 @@ package body Sem_Elab is
else
return In_Body;
end if;
- end Placement_Of_Node;
+ end Declaration_Placement_Of_Node;
- -- Local variables
+ -------------
+ -- Kind_Of --
+ -------------
+
+ function Kind_Of (Id : Entity_Id) return Invocation_Construct_Kind is
+ begin
+ if Id = Elab_Body_Id then
+ return Elaborate_Body_Procedure;
+
+ elsif Id = Elab_Spec_Id then
+ return Elaborate_Spec_Procedure;
+
+ else
+ return Regular_Construct;
+ end if;
+ end Kind_Of;
+
+ -----------------------
+ -- Spec_Placement_Of --
+ -----------------------
+
+ function Spec_Placement_Of
+ (Id : Entity_Id) return Declaration_Placement_Kind
+ is
+ Id_Rep : constant Target_Rep_Id :=
+ Target_Representation_Of (Id, In_State);
+ Body_Decl : constant Node_Id := Body_Declaration (Id_Rep);
+ Spec_Decl : constant Node_Id := Spec_Declaration (Id_Rep);
+
+ begin
+ -- The entity has a spec
+
+ if Present (Spec_Decl) then
+ return Declaration_Placement_Of_Node (Spec_Decl);
- IC_Rec : Invocation_Construct_Record;
+ -- Otherwise the entity must have a body
+
+ else
+ pragma Assert (Present (Body_Decl));
+ return Declaration_Placement_Of_Node (Body_Decl);
+ end if;
+ end Spec_Placement_Of;
-- Start of processing for Declare_Invocation_Construct
@@ -11976,15 +12133,14 @@ package body Sem_Elab is
Set_Is_Saved_Construct (Constr_Id);
- IC_Rec.Kind := Kind_Of (Constr_Id);
- IC_Rec.Placement := Placement_Of (Constr_Id);
- IC_Rec.Signature := Signature_Of (Constr_Id);
-
-- Add the construct in the ALI file
Add_Invocation_Construct
- (IC_Rec => IC_Rec,
- Update_Units => False);
+ (Body_Placement => Body_Placement_Of (Constr_Id),
+ Kind => Kind_Of (Constr_Id),
+ Signature => Signature_Of (Constr_Id),
+ Spec_Placement => Spec_Placement_Of (Constr_Id),
+ Update_Units => False);
end Declare_Invocation_Construct;
-------------------------------
@@ -12030,16 +12186,10 @@ package body Sem_Elab is
Main_Cunit : constant Node_Id := Cunit (Main_Unit);
begin
- -- Nothing to do when switch -gnatd_G (encode invocation graph in ALI
- -- files) is not in effect.
-
- if not Debug_Flag_Underscore_GG then
- return False;
-
-- Nothing to do when compiling for GNATprove because the invocation
-- graph is not needed.
- elsif GNATprove_Mode then
+ if GNATprove_Mode then
return False;
-- Nothing to do when the compilation will not produce an ALI file
@@ -12338,6 +12488,43 @@ package body Sem_Elab is
end if;
end Process_Invocation_Call;
+ --------------------------------------
+ -- Process_Invocation_Instantiation --
+ --------------------------------------
+
+ procedure Process_Invocation_Instantiation
+ (Inst : Node_Id;
+ Inst_Rep : Scenario_Rep_Id;
+ In_State : Processing_In_State)
+ is
+ pragma Unreferenced (Inst);
+
+ Gen_Id : constant Entity_Id := Target (Inst_Rep);
+
+ begin
+ -- Nothing to do when the generic appears within an internal unit
+
+ if In_Internal_Unit (Gen_Id) then
+ return;
+ end if;
+
+ -- The generic being instantiated resides within an external unit
+ --
+ -- Main unit External unit
+ -- +-----------+ +-------------+
+ -- | | | |
+ -- | Start ------------> Generic |
+ -- | | | |
+ -- +-----------+ +-------------+
+ --
+ -- Record the invocation path which originates from Start and reaches
+ -- the generic.
+
+ if not In_Extended_Main_Code_Unit (Gen_Id) then
+ Record_Invocation_Path (In_State);
+ end if;
+ end Process_Invocation_Instantiation;
+
---------------------------------
-- Process_Invocation_Scenario --
---------------------------------
@@ -12383,6 +12570,14 @@ package body Sem_Elab is
In_State => In_State);
end if;
end if;
+
+ -- Instantiation
+
+ elsif Is_Suitable_Instantiation (Scen) then
+ Process_Invocation_Instantiation
+ (Inst => Scen,
+ Inst_Rep => Scenario_Representation_Of (Scen, In_State),
+ In_State => In_State);
end if;
-- Remove the current scenario from the stack of active scenarios
@@ -12726,6 +12921,12 @@ package body Sem_Elab is
return;
end if;
+ -- Save the encoding format used to capture information about the
+ -- invocation constructs and relations in the ALI file of the main
+ -- unit.
+
+ Record_Invocation_Graph_Encoding;
+
-- Examine all library level invocation scenarios and perform DFS
-- traversals from each one. Encode a path in the ALI file of the
-- main unit if it reaches into an external unit.
@@ -12741,6 +12942,30 @@ package body Sem_Elab is
Process_Main_Unit;
end Record_Invocation_Graph;
+ --------------------------------------
+ -- Record_Invocation_Graph_Encoding --
+ --------------------------------------
+
+ procedure Record_Invocation_Graph_Encoding is
+ Kind : Invocation_Graph_Encoding_Kind := No_Encoding;
+
+ begin
+ -- Switch -gnatd_F (encode full invocation paths in ALI files) is in
+ -- effect.
+
+ if Debug_Flag_Underscore_FF then
+ Kind := Full_Path_Encoding;
+ else
+ Kind := Endpoints_Encoding;
+ end if;
+
+ -- Save the encoding format in the ALI file of the main unit
+
+ Set_Invocation_Graph_Encoding
+ (Kind => Kind,
+ Update_Units => False);
+ end Record_Invocation_Graph_Encoding;
+
----------------------------
-- Record_Invocation_Path --
----------------------------
@@ -12799,6 +13024,10 @@ package body Sem_Elab is
(Extra : out Entity_Id;
Kind : out Invocation_Kind)
is
+ Targ_Rep : constant Target_Rep_Id :=
+ Target_Representation_Of (Targ_Id, In_State);
+ Spec_Decl : constant Node_Id := Spec_Declaration (Targ_Rep);
+
begin
-- Accept within a task body
@@ -12887,7 +13116,7 @@ package body Sem_Elab is
-- Postcondition verification
elsif Is_Postconditions_Proc (Targ_Id) then
- Extra := Find_Enclosing_Scope (Targ_Id);
+ Extra := Find_Enclosing_Scope (Spec_Decl);
Kind := Postcondition_Verification;
-- Protected entry call
@@ -12930,7 +13159,6 @@ package body Sem_Elab is
Extra : Entity_Id;
Extra_Nam : Name_Id;
- IR_Rec : Invocation_Relation_Record;
Kind : Invocation_Kind;
Rel : Invoker_Target_Relation;
@@ -12969,15 +13197,13 @@ package body Sem_Elab is
Extra_Nam := No_Name;
end if;
- IR_Rec.Extra := Extra_Nam;
- IR_Rec.Invoker := Signature_Of (Invk_Id);
- IR_Rec.Kind := Kind;
- IR_Rec.Target := Signature_Of (Targ_Id);
-
-- Add the relation in the ALI file
Add_Invocation_Relation
- (IR_Rec => IR_Rec,
+ (Extra => Extra_Nam,
+ Invoker => Signature_Of (Invk_Id),
+ Kind => Kind,
+ Target => Signature_Of (Targ_Id),
Update_Units => False);
end Record_Invocation_Relation;
@@ -13422,6 +13648,12 @@ package body Sem_Elab is
if Legacy_Elaboration_Checks then
return;
+
+ -- Nothing to do when the elaboration phase of the compiler is not
+ -- active.
+
+ elsif not Elaboration_Phase_Active then
+ return;
end if;
-- Eliminate a recorded scenario when it appears within dead code
@@ -13433,6 +13665,18 @@ package body Sem_Elab is
end Kill_Elaboration_Scenario;
----------------------
+ -- Main_Unit_Entity --
+ ----------------------
+
+ function Main_Unit_Entity return Entity_Id is
+ begin
+ -- Note that Cunit_Entity (Main_Unit) is not reliable in the presence of
+ -- generic bodies and may return an outdated entity.
+
+ return Defining_Entity (Unit (Cunit (Main_Unit)));
+ end Main_Unit_Entity;
+
+ ----------------------
-- Non_Private_View --
----------------------
@@ -13785,6 +14029,12 @@ package body Sem_Elab is
elsif Preanalysis_Active then
return;
+
+ -- Nothing to do when the elaboration phase of the compiler is not
+ -- active.
+
+ elsif not Elaboration_Phase_Active then
+ return;
end if;
Scen_Lvl := Find_Enclosing_Level (Scen);
@@ -13889,16 +14139,11 @@ package body Sem_Elab is
-- The following sets store all scenarios
- Declaration_Scenarios : NE_Set.Membership_Set :=
- NE_Set.Create (1000);
- Dynamic_ABE_Check_Scenarios : NE_Set.Membership_Set :=
- NE_Set.Create (500);
- Library_Body_Scenarios : NE_Set.Membership_Set :=
- NE_Set.Create (1000);
- Library_Spec_Scenarios : NE_Set.Membership_Set :=
- NE_Set.Create (1000);
- SPARK_Scenarios : NE_Set.Membership_Set :=
- NE_Set.Create (100);
+ Declaration_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
+ Dynamic_ABE_Check_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
+ Library_Body_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
+ Library_Spec_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
+ SPARK_Scenarios : NE_Set.Membership_Set := NE_Set.Nil;
-------------------------------
-- Finalize_Scenario_Storage --
@@ -13919,7 +14164,11 @@ package body Sem_Elab is
procedure Initialize_Scenario_Storage is
begin
- null;
+ Declaration_Scenarios := NE_Set.Create (1000);
+ Dynamic_ABE_Check_Scenarios := NE_Set.Create (500);
+ Library_Body_Scenarios := NE_Set.Create (1000);
+ Library_Spec_Scenarios := NE_Set.Create (1000);
+ SPARK_Scenarios := NE_Set.Create (100);
end Initialize_Scenario_Storage;
------------------------------
@@ -14796,6 +15045,15 @@ package body Sem_Elab is
end Is_Up_Level_Target;
end Semantics;
+ ---------------------------
+ -- Set_Elaboration_Phase --
+ ---------------------------
+
+ procedure Set_Elaboration_Phase (Status : Elaboration_Phase_Status) is
+ begin
+ Elaboration_Phase := Status;
+ end Set_Elaboration_Phase;
+
---------------------
-- SPARK_Processor --
---------------------
@@ -14855,8 +15113,7 @@ package body Sem_Elab is
-- emitted multiple times.
procedure Check_SPARK_Model_In_Effect is
- Spec_Id : constant Entity_Id :=
- Unique_Entity (Cunit_Entity (Main_Unit));
+ Spec_Id : constant Entity_Id := Unique_Entity (Main_Unit_Entity);
begin
-- Do not emit the warning multiple times as this creates useless
@@ -15700,17 +15957,24 @@ package body Sem_Elab is
procedure Update_Elaboration_Scenario (New_N : Node_Id; Old_N : Node_Id) is
begin
+ -- Nothing to do when the elaboration phase of the compiler is not
+ -- active.
+
+ if not Elaboration_Phase_Active then
+ return;
+
-- Nothing to do when the old and new scenarios are one and the same
- if Old_N = New_N then
+ elsif Old_N = New_N then
return;
+ end if;
-- A scenario is being transformed by Atree.Rewrite. Update all relevant
-- internal data structures to reflect this change. This ensures that a
-- potential run-time conditional ABE check or a guaranteed ABE failure
-- is inserted at the proper place in the tree.
- elsif Is_Scenario (Old_N) then
+ if Is_Scenario (Old_N) then
Replace_Scenario (Old_N, New_N);
end if;
end Update_Elaboration_Scenario;
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 4956ef3..734c961 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -986,6 +986,13 @@ package body Sem_Eval is
Lf : constant Node_Id := Compare_Fixup (L);
Rf : constant Node_Id := Compare_Fixup (R);
+ function Is_Rewritten_Loop_Entry (N : Node_Id) return Boolean;
+ -- An attribute reference to Loop_Entry may have been rewritten into
+ -- its prefix as a way to avoid generating a constant for that
+ -- attribute when the corresponding pragma is ignored. These nodes
+ -- should be ignored when deciding if they can be equal to one
+ -- another.
+
function Is_Same_Subscript (L, R : List_Id) return Boolean;
-- L, R are the Expressions values from two attribute nodes for First
-- or Last attributes. Either may be set to No_List if no expressions
@@ -993,6 +1000,19 @@ package body Sem_Eval is
-- expressions represent the same subscript (note one case is where
-- one subscript is missing and the other is explicitly set to 1).
+ -----------------------------
+ -- Is_Rewritten_Loop_Entry --
+ -----------------------------
+
+ function Is_Rewritten_Loop_Entry (N : Node_Id) return Boolean is
+ Orig_N : constant Node_Id := Original_Node (N);
+ begin
+ return Orig_N /= N
+ and then Nkind (Orig_N) = N_Attribute_Reference
+ and then Get_Attribute_Id (Attribute_Name (Orig_N)) =
+ Attribute_Loop_Entry;
+ end Is_Rewritten_Loop_Entry;
+
-----------------------
-- Is_Same_Subscript --
-----------------------
@@ -1018,23 +1038,32 @@ package body Sem_Eval is
-- Start of processing for Is_Same_Value
begin
- -- Values are the same if they refer to the same entity and the
- -- entity is non-volatile. This does not however apply to Float
- -- types, since we may have two NaN values and they should never
- -- compare equal.
+ -- Loop_Entry nodes rewritten into their prefix inside ignored
+ -- pragmas should never lead to a decision of equality.
- -- If the entity is a discriminant, the two expressions may be bounds
- -- of components of objects of the same discriminated type. The
- -- values of the discriminants are not static, and therefore the
- -- result is unknown.
+ if Is_Rewritten_Loop_Entry (Lf)
+ or else Is_Rewritten_Loop_Entry (Rf)
+ then
+ return False;
- -- It would be better to comment individual branches of this test ???
+ -- Values are the same if they refer to the same entity and the
+ -- entity is nonvolatile.
- if Nkind_In (Lf, N_Identifier, N_Expanded_Name)
+ elsif Nkind_In (Lf, N_Identifier, N_Expanded_Name)
and then Nkind_In (Rf, N_Identifier, N_Expanded_Name)
and then Entity (Lf) = Entity (Rf)
+
+ -- If the entity is a discriminant, the two expressions may be
+ -- bounds of components of objects of the same discriminated type.
+ -- The values of the discriminants are not static, and therefore
+ -- the result is unknown.
+
and then Ekind (Entity (Lf)) /= E_Discriminant
and then Present (Entity (Lf))
+
+ -- This does not however apply to Float types, since we may have
+ -- two NaN values and they should never compare equal.
+
and then not Is_Floating_Point_Type (Etype (L))
and then not Is_Volatile_Reference (L)
and then not Is_Volatile_Reference (R)
@@ -4281,7 +4310,15 @@ package body Sem_Eval is
return Ent;
else
pragma Assert (Ekind (Ent) = E_Constant);
- return Expr_Value_E (Constant_Value (Ent));
+
+ -- We may be dealing with a enumerated character type constant, so
+ -- handle that case here.
+
+ if Nkind (Constant_Value (Ent)) = N_Character_Literal then
+ return Ent;
+ else
+ return Expr_Value_E (Constant_Value (Ent));
+ end if;
end if;
end Expr_Value_E;
@@ -4611,10 +4648,14 @@ package body Sem_Eval is
-- will cause semantic errors if it is marked as static), and after
-- the Resolve step (since Resolve in some cases sets this flag).
+ -- We mark the node as analyzed so that its type is not erased by
+ -- calling Analyze_Real_Literal.
+
Analyze (N);
Set_Is_Static_Expression (N, Static);
Set_Etype (N, Typ);
Resolve (N);
+ Set_Analyzed (N);
Set_Is_Static_Expression (N, Static);
end Fold_Ureal;
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index b499dbd..1a2a759 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -41,6 +41,7 @@ with Elists; use Elists;
with Errout; use Errout;
with Exp_Dist; use Exp_Dist;
with Exp_Util; use Exp_Util;
+with Expander; use Expander;
with Freeze; use Freeze;
with Ghost; use Ghost;
with Gnatvsn; use Gnatvsn;
@@ -298,6 +299,12 @@ package body Sem_Prag is
-- pragma. Entity name for unit and its parents is taken from item in
-- previous with_clause that mentions the unit.
+ procedure Validate_Compile_Time_Warning_Error (N : Node_Id);
+ -- N is a pragma Compile_Time_Error or Compile_Warning_Error whose boolean
+ -- expression is not known at compile time. This procedure makes an entry
+ -- in a table. The actual checking is performed by Validate_Compile_Time_
+ -- Warning_Errors, which is invoked after calling the back end.
+
Dummy : Integer := 0;
pragma Volatile (Dummy);
-- Dummy volatile integer used in bodies of ip/rv to prevent optimization
@@ -316,6 +323,41 @@ package body Sem_Prag is
-- pragma in the source program, a breakpoint on rv catches this place in
-- the source, allowing convenient stepping to the point of interest.
+ ---------------------------------------------------
+ -- Table for Validate_Compile_Time_Warning_Error --
+ ---------------------------------------------------
+
+ -- The following table collects pragmas Compile_Time_Error and Compile_
+ -- Time_Warning for validation. Entries are made by calls to subprogram
+ -- Validate_Compile_Time_Warning_Error, and the call to the procedure
+ -- Validate_Compile_Time_Warning_Errors does the actual error checking
+ -- and posting of warning and error messages. The reason for this delayed
+ -- processing is to take advantage of back-annotations of attributes size
+ -- and alignment values performed by the back end.
+
+ -- Note: the reason we store a Source_Ptr value instead of a Node_Id is
+ -- that by the time Validate_Unchecked_Conversions is called, Sprint will
+ -- already have modified all Sloc values if the -gnatD option is set.
+
+ type CTWE_Entry is record
+ Eloc : Source_Ptr;
+ -- Source location used in warnings and error messages
+
+ Prag : Node_Id;
+ -- Pragma Compile_Time_Error or Compile_Time_Warning
+
+ Scope : Node_Id;
+ -- The scope which encloses the pragma
+ end record;
+
+ package Compile_Time_Warnings_Errors is new Table.Table (
+ Table_Component_Type => CTWE_Entry,
+ Table_Index_Type => Int,
+ Table_Low_Bound => 1,
+ Table_Initial => 50,
+ Table_Increment => 200,
+ Table_Name => "Compile_Time_Warnings_Errors");
+
-------------------------------
-- Adjust_External_Name_Case --
-------------------------------
@@ -7605,7 +7647,7 @@ package body Sem_Prag is
Check_Expression (Arg1x);
if Validation_Needed then
- Sem_Ch13.Validate_Compile_Time_Warning_Error (N);
+ Validate_Compile_Time_Warning_Error (N);
end if;
end if;
end Process_Compile_Time_Warning_Or_Error;
@@ -8921,8 +8963,7 @@ package body Sem_Prag is
Mark_Rewrite_Insertion (Decl);
else
- Error_Pragma_Arg ("no matching type found for pragma%",
- Arg2);
+ Error_Pragma_Arg ("no matching type found for pragma%", Arg2);
end if;
end Process_Import_Predefined_Type;
@@ -13579,8 +13620,8 @@ package body Sem_Prag is
-- Async_Readers/Async_Writers/Effective_Reads/Effective_Writes --
------------------------------------------------------------------
- -- pragma Asynch_Readers [ (boolean_EXPRESSION) ];
- -- pragma Asynch_Writers [ (boolean_EXPRESSION) ];
+ -- pragma Async_Readers [ (boolean_EXPRESSION) ];
+ -- pragma Async_Writers [ (boolean_EXPRESSION) ];
-- pragma Effective_Reads [ (boolean_EXPRESSION) ];
-- pragma Effective_Writes [ (boolean_EXPRESSION) ];
@@ -14072,9 +14113,14 @@ package body Sem_Prag is
Expr := Get_Pragma_Arg (Arg2);
- -- Deal with SCO generation
+ -- Mark the pragma (or, if rewritten from an aspect, the original
+ -- aspect) as enabled. Nothing to do for an internally generated
+ -- check for a dynamic predicate.
- if Is_Checked (N) and then not Split_PPC (N) then
+ if Is_Checked (N)
+ and then not Split_PPC (N)
+ and then Cname /= Name_Dynamic_Predicate
+ then
Set_SCO_Pragma_Enabled (Loc);
end if;
@@ -23189,7 +23235,16 @@ package body Sem_Prag is
-- Start of processing for Check_Library_Level_Entity
begin
- if not Is_Library_Level_Entity (E) then
+ -- A SPARK_Mode of On shall only apply to library-level
+ -- entities, except for those in generic instances, which are
+ -- ignored (even if the entity gets SPARK_Mode pragma attached
+ -- in the AST, its effect is not taken into account unless the
+ -- context already provides SPARK_Mode of On in GNATprove).
+
+ if Get_SPARK_Mode_From_Annotation (N) = On
+ and then not Is_Library_Level_Entity (E)
+ and then Instantiation_Location (Sloc (N)) = No_Location
+ then
Error_Msg_Name_1 := Pname;
Error_Msg_N (Fix_Error (Msg_1), N);
@@ -25737,7 +25792,7 @@ package body Sem_Prag is
-- Otherwise we have a call to an overridden primitive, and we
-- will create a common class-wide clone for the body of
- -- original operation and its eventual inherited versions. If
+ -- original operation and its eventual inherited versions. If
-- the original operation dispatches on result it is never
-- inherited and there is no need for a clone. There is not
-- need for a clone either in GNATprove mode, as cases that
@@ -30715,6 +30770,7 @@ package body Sem_Prag is
procedure Initialize is
begin
Externals.Init;
+ Compile_Time_Warnings_Errors.Init;
end Initialize;
--------
@@ -32057,4 +32113,77 @@ package body Sem_Prag is
return Empty;
end Test_Case_Arg;
+ -----------------------------------------
+ -- Validate_Compile_Time_Warning_Error --
+ -----------------------------------------
+
+ procedure Validate_Compile_Time_Warning_Error (N : Node_Id) is
+ begin
+ Compile_Time_Warnings_Errors.Append
+ (New_Val => CTWE_Entry'(Eloc => Sloc (N),
+ Scope => Current_Scope,
+ Prag => N));
+ end Validate_Compile_Time_Warning_Error;
+
+ ------------------------------------------
+ -- Validate_Compile_Time_Warning_Errors --
+ ------------------------------------------
+
+ procedure Validate_Compile_Time_Warning_Errors is
+ procedure Set_Scope (S : Entity_Id);
+ -- Install all enclosing scopes of S along with S itself
+
+ procedure Unset_Scope (S : Entity_Id);
+ -- Uninstall all enclosing scopes of S along with S itself
+
+ ---------------
+ -- Set_Scope --
+ ---------------
+
+ procedure Set_Scope (S : Entity_Id) is
+ begin
+ if S /= Standard_Standard then
+ Set_Scope (Scope (S));
+ end if;
+
+ Push_Scope (S);
+ end Set_Scope;
+
+ -----------------
+ -- Unset_Scope --
+ -----------------
+
+ procedure Unset_Scope (S : Entity_Id) is
+ begin
+ if S /= Standard_Standard then
+ Unset_Scope (Scope (S));
+ end if;
+
+ Pop_Scope;
+ end Unset_Scope;
+
+ -- Start of processing for Validate_Compile_Time_Warning_Errors
+
+ begin
+ Expander_Mode_Save_And_Set (False);
+ In_Compile_Time_Warning_Or_Error := True;
+
+ for N in Compile_Time_Warnings_Errors.First ..
+ Compile_Time_Warnings_Errors.Last
+ loop
+ declare
+ T : CTWE_Entry renames Compile_Time_Warnings_Errors.Table (N);
+
+ begin
+ Set_Scope (T.Scope);
+ Reset_Analyzed_Flags (T.Prag);
+ Process_Compile_Time_Warning_Or_Error (T.Prag, T.Eloc);
+ Unset_Scope (T.Scope);
+ end;
+ end loop;
+
+ In_Compile_Time_Warning_Or_Error := False;
+ Expander_Mode_Restore;
+ end Validate_Compile_Time_Warning_Errors;
+
end Sem_Prag;
diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads
index f2f6d0c..25353b7 100644
--- a/gcc/ada/sem_prag.ads
+++ b/gcc/ada/sem_prag.ads
@@ -555,4 +555,10 @@ package Sem_Prag is
--
-- Empty if there is no such argument
+ procedure Validate_Compile_Time_Warning_Errors;
+ -- This routine is called after calling the back end to validate pragmas
+ -- Compile_Time_Error and Compile_Time_Warning for size and alignment
+ -- appropriateness. The reason it is called that late is to take advantage
+ -- of any back-annotation of size and alignment performed by the back end.
+
end Sem_Prag;
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 8521478..b668a51 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -111,8 +111,8 @@ package body Sem_Res is
Pref : Node_Id);
-- Check that the type of the prefix of a dereference is not incomplete
- function Check_Infinite_Recursion (N : Node_Id) return Boolean;
- -- Given a call node, N, which is known to occur immediately within the
+ function Check_Infinite_Recursion (Call : Node_Id) return Boolean;
+ -- Given a call node, Call, which is known to occur immediately within the
-- subprogram being called, determines whether it is a detectable case of
-- an infinite recursion, and if so, outputs appropriate messages. Returns
-- True if an infinite recursion is detected, and False otherwise.
@@ -159,7 +159,7 @@ package body Sem_Res is
Typ : Entity_Id;
Is_Comp : Boolean);
-- Internal procedure for Resolve_Op_Concat to resolve one operand of
- -- concatenation operator. The operand is either of the array type or of
+ -- concatenation operator. The operand is either of the array type or of
-- the component type. If the operand is an aggregate, and the component
-- type is composite, this is ambiguous if component type has aggregates.
@@ -695,164 +695,398 @@ package body Sem_Res is
-- Check_Infinite_Recursion --
------------------------------
- function Check_Infinite_Recursion (N : Node_Id) return Boolean is
- P : Node_Id;
- C : Node_Id;
+ function Check_Infinite_Recursion (Call : Node_Id) return Boolean is
+ function Enclosing_Declaration_Or_Statement (N : Node_Id) return Node_Id;
+ -- Return the nearest enclosing declaration or statement that houses
+ -- arbitrary node N.
- function Same_Argument_List return Boolean;
- -- Check whether list of actuals is identical to list of formals of
- -- called function (which is also the enclosing scope).
+ function Invoked_With_Different_Arguments (N : Node_Id) return Boolean;
+ -- Determine whether call N invokes the related enclosing subprogram
+ -- with actuals that differ from the subprogram's formals.
- ------------------------
- -- Same_Argument_List --
- ------------------------
+ function Is_Conditional_Statement (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N denotes a conditional construct
+
+ function Is_Control_Flow_Statement (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N denotes a control flow statement
+ -- or a construct that may contains such a statement.
+
+ function Is_Immediately_Within_Body (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N appears immediately within the
+ -- statements of an entry or subprogram body.
+
+ function Is_Raise_Idiom (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N appears immediately within the
+ -- body of an entry or subprogram, and is preceded by a single raise
+ -- statement.
+
+ function Is_Raise_Statement (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N denotes a raise statement
+
+ function Is_Sole_Statement (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N is the sole source statement in
+ -- the body of the enclosing subprogram.
+
+ function Preceded_By_Control_Flow_Statement (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N is preceded by a control flow
+ -- statement.
+
+ function Within_Conditional_Statement (N : Node_Id) return Boolean;
+ -- Determine whether arbitrary node N appears within a conditional
+ -- construct.
+
+ ----------------------------------------
+ -- Enclosing_Declaration_Or_Statement --
+ ----------------------------------------
- function Same_Argument_List return Boolean is
- A : Node_Id;
- F : Entity_Id;
- Subp : Entity_Id;
+ function Enclosing_Declaration_Or_Statement
+ (N : Node_Id) return Node_Id
+ is
+ Par : Node_Id;
begin
- if not Is_Entity_Name (Name (N)) then
- return False;
- else
- Subp := Entity (Name (N));
- end if;
+ Par := N;
+ while Present (Par) loop
+ if Is_Declaration (Par) or else Is_Statement (Par) then
+ return Par;
- F := First_Formal (Subp);
- A := First_Actual (N);
- while Present (F) and then Present (A) loop
- if not Is_Entity_Name (A) or else Entity (A) /= F then
- return False;
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (Par) then
+ exit;
end if;
- Next_Actual (A);
- Next_Formal (F);
+ Par := Parent (Par);
end loop;
- return True;
- end Same_Argument_List;
+ return N;
+ end Enclosing_Declaration_Or_Statement;
- -- Start of processing for Check_Infinite_Recursion
+ --------------------------------------
+ -- Invoked_With_Different_Arguments --
+ --------------------------------------
- begin
- -- Special case, if this is a procedure call and is a call to the
- -- current procedure with the same argument list, then this is for
- -- sure an infinite recursion and we insert a call to raise SE.
+ function Invoked_With_Different_Arguments (N : Node_Id) return Boolean is
+ Subp : constant Entity_Id := Entity (Name (N));
- if Is_List_Member (N)
- and then List_Length (List_Containing (N)) = 1
- and then Same_Argument_List
- then
- declare
- P : constant Node_Id := Parent (N);
- begin
- if Nkind (P) = N_Handled_Sequence_Of_Statements
- and then Nkind (Parent (P)) = N_Subprogram_Body
- and then Is_Empty_List (Declarations (Parent (P)))
+ Actual : Node_Id;
+ Formal : Entity_Id;
+
+ begin
+ -- Determine whether the formals of the invoked subprogram are not
+ -- used as actuals in the call.
+
+ Actual := First_Actual (Call);
+ Formal := First_Formal (Subp);
+ while Present (Actual) and then Present (Formal) loop
+
+ -- The current actual does not match the current formal
+
+ if not (Is_Entity_Name (Actual)
+ and then Entity (Actual) = Formal)
then
- Error_Msg_Warn := SPARK_Mode /= On;
- Error_Msg_N ("!infinite recursion<<", N);
- Error_Msg_N ("\!Storage_Error [<<", N);
- Insert_Action (N,
- Make_Raise_Storage_Error (Sloc (N),
- Reason => SE_Infinite_Recursion));
return True;
end if;
- end;
- end if;
- -- If not that special case, search up tree, quitting if we reach a
- -- construct (e.g. a conditional) that tells us that this is not a
- -- case for an infinite recursion warning.
+ Next_Actual (Actual);
+ Next_Formal (Formal);
+ end loop;
+
+ return False;
+ end Invoked_With_Different_Arguments;
- C := N;
- loop
- P := Parent (C);
+ ------------------------------
+ -- Is_Conditional_Statement --
+ ------------------------------
- -- If no parent, then we were not inside a subprogram, this can for
- -- example happen when processing certain pragmas in a spec. Just
- -- return False in this case.
+ function Is_Conditional_Statement (N : Node_Id) return Boolean is
+ begin
+ return
+ Nkind_In (N, N_And_Then,
+ N_Case_Expression,
+ N_Case_Statement,
+ N_If_Expression,
+ N_If_Statement,
+ N_Or_Else);
+ end Is_Conditional_Statement;
- if No (P) then
- return False;
+ -------------------------------
+ -- Is_Control_Flow_Statement --
+ -------------------------------
+
+ function Is_Control_Flow_Statement (N : Node_Id) return Boolean is
+ begin
+ -- It is assumed that all statements may affect the control flow in
+ -- some way. A raise statement may be expanded into a non-statement
+ -- node.
+
+ return Is_Statement (N) or else Is_Raise_Statement (N);
+ end Is_Control_Flow_Statement;
+
+ --------------------------------
+ -- Is_Immediately_Within_Body --
+ --------------------------------
+
+ function Is_Immediately_Within_Body (N : Node_Id) return Boolean is
+ HSS : constant Node_Id := Parent (N);
+
+ begin
+ return
+ Nkind (HSS) = N_Handled_Sequence_Of_Statements
+ and then Nkind_In (Parent (HSS), N_Entry_Body, N_Subprogram_Body)
+ and then Is_List_Member (N)
+ and then List_Containing (N) = Statements (HSS);
+ end Is_Immediately_Within_Body;
+
+ --------------------
+ -- Is_Raise_Idiom --
+ --------------------
+
+ function Is_Raise_Idiom (N : Node_Id) return Boolean is
+ Raise_Stmt : Node_Id;
+ Stmt : Node_Id;
+
+ begin
+ if Is_Immediately_Within_Body (N) then
+
+ -- Assume that no raise statement has been seen yet
+
+ Raise_Stmt := Empty;
+
+ -- Examine the statements preceding the input node, skipping
+ -- internally-generated constructs.
+
+ Stmt := Prev (N);
+ while Present (Stmt) loop
+
+ -- Multiple raise statements violate the idiom
+
+ if Is_Raise_Statement (Stmt) then
+ if Present (Raise_Stmt) then
+ return False;
+ end if;
+
+ Raise_Stmt := Stmt;
+
+ elsif Comes_From_Source (Stmt) then
+ exit;
+ end if;
+
+ Stmt := Prev (Stmt);
+ end loop;
+
+ -- At this point the node must be preceded by a raise statement,
+ -- and the raise statement has to be the sole statement within
+ -- the enclosing entry or subprogram body.
+
+ return
+ Present (Raise_Stmt) and then Is_Sole_Statement (Raise_Stmt);
end if;
- -- Done if we get to subprogram body, this is definitely an infinite
- -- recursion case if we did not find anything to stop us.
+ return False;
+ end Is_Raise_Idiom;
- exit when Nkind (P) = N_Subprogram_Body;
+ ------------------------
+ -- Is_Raise_Statement --
+ ------------------------
- -- If appearing in conditional, result is false
+ function Is_Raise_Statement (N : Node_Id) return Boolean is
+ begin
+ -- A raise statement may be transfomed into a Raise_xxx_Error node
- if Nkind_In (P, N_Or_Else,
- N_And_Then,
- N_Case_Expression,
- N_Case_Statement,
- N_If_Expression,
- N_If_Statement)
- then
- return False;
+ return
+ Nkind (N) = N_Raise_Statement
+ or else Nkind (N) in N_Raise_xxx_Error;
+ end Is_Raise_Statement;
- elsif Nkind (P) = N_Handled_Sequence_Of_Statements
- and then C /= First (Statements (P))
- then
- -- If the call is the expression of a return statement and the
- -- actuals are identical to the formals, it's worth a warning.
- -- However, we skip this if there is an immediately preceding
- -- raise statement, since the call is never executed.
+ -----------------------
+ -- Is_Sole_Statement --
+ -----------------------
- -- Furthermore, this corresponds to a common idiom:
+ function Is_Sole_Statement (N : Node_Id) return Boolean is
+ Stmt : Node_Id;
- -- function F (L : Thing) return Boolean is
- -- begin
- -- raise Program_Error;
- -- return F (L);
- -- end F;
+ begin
+ -- The input node appears within the statements of an entry or
+ -- subprogram body. Examine the statements preceding the node.
- -- for generating a stub function
+ if Is_Immediately_Within_Body (N) then
+ Stmt := Prev (N);
- if Nkind (Parent (N)) = N_Simple_Return_Statement
- and then Same_Argument_List
- then
- exit when not Is_List_Member (Parent (N));
+ while Present (Stmt) loop
- -- OK, return statement is in a statement list, look for raise
+ -- The statement is preceded by another statement or a source
+ -- construct. This indicates that the node does not appear by
+ -- itself.
- declare
- Nod : Node_Id;
+ if Is_Control_Flow_Statement (Stmt)
+ or else Comes_From_Source (Stmt)
+ then
+ return False;
+ end if;
- begin
- -- Skip past N_Freeze_Entity nodes generated by expansion
+ Stmt := Prev (Stmt);
+ end loop;
- Nod := Prev (Parent (N));
- while Present (Nod)
- and then Nkind (Nod) = N_Freeze_Entity
- loop
- Prev (Nod);
- end loop;
+ return True;
+ end if;
- -- If no raise statement, give warning. We look at the
- -- original node, because in the case of "raise ... with
- -- ...", the node has been transformed into a call.
+ -- The input node is within a construct nested inside the entry or
+ -- subprogram body.
- exit when Nkind (Original_Node (Nod)) /= N_Raise_Statement
- and then
- (Nkind (Nod) not in N_Raise_xxx_Error
- or else Present (Condition (Nod)));
- end;
- end if;
+ return False;
+ end Is_Sole_Statement;
- return False;
+ ----------------------------------------
+ -- Preceded_By_Control_Flow_Statement --
+ ----------------------------------------
- else
- C := P;
+ function Preceded_By_Control_Flow_Statement
+ (N : Node_Id) return Boolean
+ is
+ Stmt : Node_Id;
+
+ begin
+ if Is_List_Member (N) then
+ Stmt := Prev (N);
+
+ -- Examine the statements preceding the input node
+
+ while Present (Stmt) loop
+ if Is_Control_Flow_Statement (Stmt) then
+ return True;
+ end if;
+
+ Stmt := Prev (Stmt);
+ end loop;
+
+ return False;
end if;
- end loop;
- Error_Msg_Warn := SPARK_Mode /= On;
- Error_Msg_N ("!possible infinite recursion<<", N);
- Error_Msg_N ("\!??Storage_Error ]<<", N);
+ -- Assume that the node is part of some control flow statement
+
+ return True;
+ end Preceded_By_Control_Flow_Statement;
+
+ ----------------------------------
+ -- Within_Conditional_Statement --
+ ----------------------------------
+
+ function Within_Conditional_Statement (N : Node_Id) return Boolean is
+ Stmt : Node_Id;
+
+ begin
+ Stmt := Parent (N);
+ while Present (Stmt) loop
+ if Is_Conditional_Statement (Stmt) then
+ return True;
+
+ -- Prevent the search from going too far
+
+ elsif Is_Body_Or_Package_Declaration (Stmt) then
+ exit;
+ end if;
+
+ Stmt := Parent (Stmt);
+ end loop;
+
+ return False;
+ end Within_Conditional_Statement;
+
+ -- Local variables
+
+ Call_Context : constant Node_Id :=
+ Enclosing_Declaration_Or_Statement (Call);
+
+ -- Start of processing for Check_Infinite_Recursion
+
+ begin
+ -- The call is assumed to be safe when the enclosing subprogram is
+ -- invoked with actuals other than its formals.
+ --
+ -- procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
+ -- begin
+ -- ...
+ -- Proc (A1, A2, ..., AN);
+ -- ...
+ -- end Proc;
+
+ if Invoked_With_Different_Arguments (Call) then
+ return False;
+
+ -- The call is assumed to be safe when the invocation of the enclosing
+ -- subprogram depends on a conditional statement.
+ --
+ -- procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
+ -- begin
+ -- ...
+ -- if Some_Condition then
+ -- Proc (F1, F2, ..., FN);
+ -- end if;
+ -- ...
+ -- end Proc;
+
+ elsif Within_Conditional_Statement (Call) then
+ return False;
+
+ -- The context of the call is assumed to be safe when the invocation of
+ -- the enclosing subprogram is preceded by some control flow statement.
+ --
+ -- procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
+ -- begin
+ -- ...
+ -- if Some_Condition then
+ -- ...
+ -- end if;
+ -- ...
+ -- Proc (F1, F2, ..., FN);
+ -- ...
+ -- end Proc;
+
+ elsif Preceded_By_Control_Flow_Statement (Call_Context) then
+ return False;
+
+ -- Detect an idiom where the context of the call is preceded by a single
+ -- raise statement.
+ --
+ -- procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
+ -- begin
+ -- raise ...;
+ -- Proc (F1, F2, ..., FN);
+ -- end Proc;
+
+ elsif Is_Raise_Idiom (Call_Context) then
+ return False;
+ end if;
+
+ -- At this point it is certain that infinite recursion will take place
+ -- as long as the call is executed. Detect a case where the context of
+ -- the call is the sole source statement within the subprogram body.
+ --
+ -- procedure Proc (F1 : ...; F2 : ...; ...; FN : ...) is
+ -- begin
+ -- Proc (F1, F2, ..., FN);
+ -- end Proc;
+ --
+ -- Install an explicit raise to prevent the infinite recursion.
+
+ if Is_Sole_Statement (Call_Context) then
+ Error_Msg_Warn := SPARK_Mode /= On;
+ Error_Msg_N ("!infinite recursion<<", Call);
+ Error_Msg_N ("\!Storage_Error [<<", Call);
+
+ Insert_Action (Call,
+ Make_Raise_Storage_Error (Sloc (Call),
+ Reason => SE_Infinite_Recursion));
+
+ -- Otherwise infinite recursion could take place, considering other flow
+ -- control constructs such as gotos, exit statements, etc.
+
+ else
+ Error_Msg_Warn := SPARK_Mode /= On;
+ Error_Msg_N ("!possible infinite recursion<<", Call);
+ Error_Msg_N ("\!??Storage_Error ]<<", Call);
+ end if;
return True;
end Check_Infinite_Recursion;
@@ -3224,12 +3458,17 @@ package body Sem_Res is
begin
-- Nothing to do if no parameters, or original node is neither a
-- function call nor a procedure call statement (happens in the
- -- operator-transformed-to-function call case), or the call does
+ -- operator-transformed-to-function call case), or the call is to an
+ -- operator symbol (which is usually in infix form), or the call does
-- not come from source, or this warning is off.
if not Warn_On_Parameter_Order
or else No (Parameter_Associations (N))
or else Nkind (Original_Node (N)) not in N_Subprogram_Call
+ or else (Nkind (Name (N)) = N_Identifier
+ and then Present (Entity (Name (N)))
+ and then Nkind (Entity (Name (N))) =
+ N_Defining_Operator_Symbol)
or else not Comes_From_Source (N)
then
return;
@@ -3951,17 +4190,16 @@ package body Sem_Res is
DDT : constant Entity_Id :=
Directly_Designated_Type (Base_Type (Etype (F)));
- New_Itype : Entity_Id;
-
begin
+ -- Displace the pointer to the object to reference its
+ -- secondary dispatch table.
+
if Is_Class_Wide_Type (DDT)
and then Is_Interface (DDT)
then
- New_Itype := Create_Itype (E_Anonymous_Access_Type, A);
- Set_Etype (New_Itype, Etype (A));
- Set_Directly_Designated_Type
- (New_Itype, Directly_Designated_Type (Etype (A)));
- Set_Etype (A, New_Itype);
+ Rewrite (A, Convert_To (Etype (F), Relocate_Node (A)));
+ Analyze_And_Resolve (A, Etype (F),
+ Suppress => Access_Check);
end if;
-- Ada 2005, AI-162:If the actual is an allocator, the
@@ -6070,7 +6308,7 @@ package body Sem_Res is
-- is frozen in the usual fashion, by the appearance of a real body,
-- or at the end of a declarative part. However an implicit call to
-- an expression function may appear when it is part of a default
- -- expression in a call to an initialiation procedure, and must be
+ -- expression in a call to an initialization procedure, and must be
-- frozen now, even if the body is inserted at a later point.
if Is_Entity_Name (Subp)
@@ -6710,7 +6948,9 @@ package body Sem_Res is
-- Check the dimensions of the actuals in the call. For function calls,
-- propagate the dimensions from the returned type to N.
- Analyze_Dimension_Call (N, Nam);
+ if not In_Inlined_Body then
+ Analyze_Dimension_Call (N, Nam);
+ end if;
-- All done, evaluate call and deal with elaboration issues
@@ -6768,6 +7008,15 @@ package body Sem_Res is
Cannot_Inline
("cannot inline & (in default expression)?", N, Nam_UA);
+ -- Calls cannot be inlined inside quantified expressions, which
+ -- are left in expression form for GNATprove. Since these
+ -- expressions are only preanalyzed, we need to detect the failure
+ -- to inline outside of the case for Full_Analysis below.
+
+ elsif In_Quantified_Expression (N) then
+ Cannot_Inline
+ ("cannot inline & (in quantified expression)?", N, Nam_UA);
+
-- Inlining should not be performed during preanalysis
elsif Full_Analysis then
@@ -8194,6 +8443,51 @@ package body Sem_Res is
Explain_Redundancy (Original_Node (R));
end if;
+ -- If the equality is overloaded and the operands have resolved
+ -- properly, set the proper equality operator on the node. The
+ -- current setting is the first one found during analysis, which
+ -- is not necessarily the one to which the node has resolved.
+
+ if Is_Overloaded (N) then
+ declare
+ I : Interp_Index;
+ It : Interp;
+
+ begin
+ Get_First_Interp (N, I, It);
+
+ -- If the equality is user-defined, the type of the operands
+ -- matches that of the formals. For a predefined operqtor,
+ -- it is the scope that matters, given that the predefined
+ -- equality has Any_Type formals. In either case the result
+ -- type (most often Booleam) must match the context .
+
+ while Present (It.Typ) loop
+ if Etype (It.Nam) = Typ
+ and then
+ (Etype (First_Entity (It.Nam)) = Etype (L)
+ or else Scope (It.Nam) = Scope (T))
+ then
+ Set_Entity (N, It.Nam);
+
+ Set_Is_Overloaded (N, False);
+ exit;
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+
+ -- If expansion is active and this is an inherited operation,
+ -- replace it with its ancestor. This must not be done during
+ -- preanalysis because the type may not be frozen yet, as when
+ -- the context is a precondition or postcondition.
+
+ if Present (Alias (Entity (N))) and then Expander_Active then
+ Set_Entity (N, Alias (Entity (N)));
+ end if;
+ end;
+ end if;
+
Check_Unset_Reference (L);
Check_Unset_Reference (R);
Generate_Operator_Reference (N, T);
@@ -9791,9 +10085,42 @@ package body Sem_Res is
end if;
-- Complete resolution and evaluation of NOT
+ -- If argument is an equality and expected type is boolean, that
+ -- expected type has no effect on resolution, and there are
+ -- special rules for resolution of Eq, Neq in the presence of
+ -- overloaded operands, so we directly call its resolution routines.
+
+ declare
+ Opnd : constant Node_Id := Right_Opnd (N);
+ Op_Id : Entity_Id;
+
+ begin
+ if B_Typ = Standard_Boolean
+ and then Nkind_In (Opnd, N_Op_Eq, N_Op_Ne)
+ and then Is_Overloaded (Opnd)
+ then
+ Resolve_Equality_Op (Opnd, B_Typ);
+ Op_Id := Entity (Opnd);
+
+ if Ekind (Op_Id) = E_Function
+ and then not Is_Intrinsic_Subprogram (Op_Id)
+ then
+ Rewrite_Operator_As_Call (Opnd, Op_Id);
+ end if;
+
+ if not Inside_A_Generic or else Is_Entity_Name (Opnd) then
+ Freeze_Expression (Opnd);
+ end if;
+
+ Expand (Opnd);
+
+ else
+ Resolve (Opnd, B_Typ);
+ end if;
+
+ Check_Unset_Reference (Opnd);
+ end;
- Resolve (Right_Opnd (N), B_Typ);
- Check_Unset_Reference (Right_Opnd (N));
Set_Etype (N, B_Typ);
Generate_Operator_Reference (N, B_Typ);
Eval_Op_Not (N);
@@ -10297,8 +10624,25 @@ package body Sem_Res is
if Is_Access_Type (Etype (P)) then
T := Designated_Type (Etype (P));
Check_Fully_Declared_Prefix (T, P);
+
else
T := Etype (P);
+
+ -- If the prefix is an entity it may have a deferred reference set
+ -- during analysis of the selected component. After resolution we
+ -- can transform it into a proper reference. This prevents spurious
+ -- warnings on useless assignments when the same selected component
+ -- is the actual for an out parameter in a subsequent call.
+
+ if Is_Entity_Name (P)
+ and then Has_Deferred_Reference (Entity (P))
+ then
+ if May_Be_Lvalue (N) then
+ Generate_Reference (Entity (P), P, 'm');
+ else
+ Generate_Reference (Entity (P), P, 'r');
+ end if;
+ end if;
end if;
-- Set flag for expander if discriminant check required on a component
diff --git a/gcc/ada/sem_spark.adb b/gcc/ada/sem_spark.adb
index b4e816e..a60a6cb 100644
--- a/gcc/ada/sem_spark.adb
+++ b/gcc/ada/sem_spark.adb
@@ -137,6 +137,9 @@ package body Sem_SPARK is
-- corresponds to both "observing" and "owning" types in SPARK RM
-- 3.10. To be used when moving the path.
+ Explanation : Node_Id;
+ -- Node that can be used in an explanation for a permission mismatch
+
case Kind is
-- An entire object is either a leaf (an object which cannot be
-- extended further in a path) or a subtree in folded form (which
@@ -217,6 +220,7 @@ package body Sem_SPARK is
function Children_Permission (T : Perm_Tree_Access) return Perm_Kind;
function Component (T : Perm_Tree_Access) return Perm_Tree_Maps.Instance;
+ function Explanation (T : Perm_Tree_Access) return Node_Id;
function Get_All (T : Perm_Tree_Access) return Perm_Tree_Access;
function Get_Elem (T : Perm_Tree_Access) return Perm_Tree_Access;
function Is_Node_Deep (T : Perm_Tree_Access) return Boolean;
@@ -257,6 +261,7 @@ package body Sem_SPARK is
(N : Node_Id;
Exp_Perm : Perm_Kind;
Act_Perm : Perm_Kind;
+ Expl : Node_Id;
Forbidden_Perm : Boolean := False);
-- Issues a continuation error message about a mismatch between a
-- desired permission Exp_Perm and a permission obtained Act_Perm. N
@@ -428,6 +433,15 @@ package body Sem_SPARK is
Free_Perm_Tree_Dealloc (PT);
end Free_Tree;
+ -----------------
+ -- Explanation --
+ -----------------
+
+ function Explanation (T : Perm_Tree_Access) return Node_Id is
+ begin
+ return T.all.Tree.Explanation;
+ end Explanation;
+
-------------
-- Get_All --
-------------
@@ -503,22 +517,34 @@ package body Sem_SPARK is
(N : Node_Id;
Exp_Perm : Perm_Kind;
Act_Perm : Perm_Kind;
+ Expl : Node_Id;
Forbidden_Perm : Boolean := False)
is
begin
+ Error_Msg_Sloc := Sloc (Expl);
+
if Forbidden_Perm then
- if Exp_Perm = Act_Perm then
- Error_Msg_N ("\got forbidden state `"
- & Perm_Kind'Image (Exp_Perm), N);
+ if Exp_Perm = No_Access then
+ Error_Msg_N ("\object was moved #", N);
else
- Error_Msg_N ("\forbidden state `"
- & Perm_Kind'Image (Exp_Perm) & "`, got `"
- & Perm_Kind'Image (Act_Perm) & "`", N);
+ raise Program_Error;
end if;
else
- Error_Msg_N ("\expected state `"
- & Perm_Kind'Image (Exp_Perm) & "` at least, got `"
- & Perm_Kind'Image (Act_Perm) & "`", N);
+ case Exp_Perm is
+ when Write_Perm =>
+ if Act_Perm = Read_Only then
+ Error_Msg_N
+ ("\object was declared as not writeable #", N);
+ else
+ Error_Msg_N ("\object was moved #", N);
+ end if;
+
+ when Read_Only =>
+ Error_Msg_N ("\object was moved #", N);
+
+ when No_Access =>
+ raise Program_Error;
+ end case;
end if;
end Perm_Mismatch;
@@ -534,9 +560,13 @@ package body Sem_SPARK is
-- has the right permission, and also updating permissions when a path is
-- moved, borrowed, or observed.
- type Checking_Mode is
+ type Extended_Checking_Mode is
+
+ (Read_Subexpr,
+ -- Special value used for assignment, to check that subexpressions of
+ -- the assigned path are readable.
- (Read,
+ Read,
-- Default mode
Move,
@@ -565,6 +595,8 @@ package body Sem_SPARK is
-- and extensions are set to Read_Only.
);
+ subtype Checking_Mode is Extended_Checking_Mode range Read .. Observe;
+
type Result_Kind is (Folded, Unfolded);
-- The type declaration to discriminate in the Perm_Or_Tree type
@@ -575,8 +607,11 @@ package body Sem_SPARK is
type Perm_Or_Tree (R : Result_Kind) is record
case R is
- when Folded => Found_Permission : Perm_Kind;
- when Unfolded => Tree_Access : Perm_Tree_Access;
+ when Folded =>
+ Found_Permission : Perm_Kind;
+ Explanation : Node_Id;
+ when Unfolded =>
+ Tree_Access : Perm_Tree_Access;
end case;
end record;
@@ -602,10 +637,12 @@ package body Sem_SPARK is
procedure Check_Declaration (Decl : Node_Id);
- procedure Check_Expression (Expr : Node_Id; Mode : Checking_Mode);
+ procedure Check_Expression (Expr : Node_Id; Mode : Extended_Checking_Mode);
pragma Precondition (Nkind_In (Expr, N_Index_Or_Discriminant_Constraint,
N_Range_Constraint,
- N_Subtype_Indication)
+ N_Subtype_Indication,
+ N_Digits_Constraint,
+ N_Delta_Constraint)
or else Nkind (Expr) in N_Subexpr);
procedure Check_Globals (Subp : Entity_Id);
@@ -650,6 +687,10 @@ package body Sem_SPARK is
-- Check that type Typ is either not deep, or that it is an observing or
-- owning type according to SPARK RM 3.10
+ function Get_Expl (N : Node_Or_Entity_Id) return Node_Id;
+ -- The function that takes a name as input and returns an explanation node
+ -- for the permission associated with it.
+
function Get_Observed_Or_Borrowed_Expr (Expr : Node_Id) return Node_Id;
pragma Precondition (Is_Path_Expression (Expr));
-- Return the expression being borrowed/observed when borrowing or
@@ -674,11 +715,14 @@ package body Sem_SPARK is
function Get_Root_Object
(Expr : Node_Id;
- Through_Traversal : Boolean := True) return Entity_Id;
- pragma Precondition (Is_Path_Expression (Expr));
+ Through_Traversal : Boolean := True;
+ Is_Traversal : Boolean := False) return Entity_Id;
-- Return the root of the path expression Expr, or Empty for an allocator,
-- NULL, or a function call. Through_Traversal is True if it should follow
- -- through calls to traversal functions.
+ -- through calls to traversal functions. Is_Traversal is True if this
+ -- corresponds to a value returned from a traversal function, which should
+ -- allow if-expressions and case-expressions that refer to the same root,
+ -- even if the paths are not the same in all branches.
generic
with procedure Handle_Parameter_Or_Global
@@ -700,25 +744,30 @@ package body Sem_SPARK is
-- the debugger to look into a hash table.
pragma Unreferenced (Hp);
- procedure Illegal_Global_Usage (N : Node_Or_Entity_Id);
+ procedure Illegal_Global_Usage (N : Node_Or_Entity_Id; E : Entity_Id);
pragma No_Return (Illegal_Global_Usage);
-- A procedure that is called when deep globals or aliased globals are used
-- without any global aspect.
- function Is_Deep (Typ : Entity_Id) return Boolean;
- -- A function that can tell if a type is deep or not. Returns true if the
- -- type passed as argument is deep.
+ function Is_Path_Expression
+ (Expr : Node_Id;
+ Is_Traversal : Boolean := False) return Boolean;
+ -- Return whether Expr corresponds to a path. Is_Traversal is True if this
+ -- corresponds to a value returned from a traversal function, which should
+ -- allow if-expressions and case-expressions.
- function Is_Path_Expression (Expr : Node_Id) return Boolean;
- -- Return whether Expr corresponds to a path
+ function Is_Subpath_Expression
+ (Expr : Node_Id;
+ Is_Traversal : Boolean := False) return Boolean;
+ -- Return True if Expr can be part of a path expression. Is_Traversal is
+ -- True if this corresponds to a value returned from a traversal function,
+ -- which should allow if-expressions and case-expressions.
function Is_Prefix_Or_Almost (Pref, Expr : Node_Id) return Boolean;
-- Determine if the candidate Prefix is indeed a prefix of Expr, or almost
-- a prefix, in the sense that they could still refer to overlapping memory
-- locations.
- function Is_Traversal_Function (E : Entity_Id) return Boolean;
-
function Is_Traversal_Function_Call (Expr : Node_Id) return Boolean;
function Loop_Of_Exit (N : Node_Id) return Entity_Id;
@@ -732,6 +781,7 @@ package body Sem_SPARK is
(N : Node_Id;
Perm : Perm_Kind;
Found_Perm : Perm_Kind;
+ Expl : Node_Id;
Forbidden_Perm : Boolean := False);
-- A procedure that is called when the permissions found contradict the
-- rules established by the RM. This function is called with the node and
@@ -742,7 +792,8 @@ package body Sem_SPARK is
(E : Entity_Id;
Subp : Entity_Id;
Perm : Perm_Kind;
- Found_Perm : Perm_Kind);
+ Found_Perm : Perm_Kind;
+ Expl : Node_Id);
-- A procedure that is called when the permissions found contradict the
-- rules established by the RM at the end of subprograms. This function is
-- called with the node, the node of the returning function, and the
@@ -772,12 +823,18 @@ package body Sem_SPARK is
-- subprogram indeed have Read_Write permission at the end of the
-- subprogram execution.
- procedure Set_Perm_Extensions (T : Perm_Tree_Access; P : Perm_Kind);
+ procedure Set_Perm_Extensions
+ (T : Perm_Tree_Access;
+ P : Perm_Kind;
+ Expl : Node_Id);
-- This procedure takes an access to a permission tree and modifies the
-- tree so that any strict extensions of the given tree become of the
-- access specified by parameter P.
- procedure Set_Perm_Extensions_Move (T : Perm_Tree_Access; E : Entity_Id);
+ procedure Set_Perm_Extensions_Move
+ (T : Perm_Tree_Access;
+ E : Entity_Id;
+ Expl : Node_Id);
-- Set permissions to
-- No for any extension with more .all
-- W for any deep extension with same number of .all
@@ -785,7 +842,8 @@ package body Sem_SPARK is
function Set_Perm_Prefixes
(N : Node_Id;
- Perm : Perm_Kind_Option) return Perm_Tree_Access;
+ Perm : Perm_Kind_Option;
+ Expl : Node_Id) return Perm_Tree_Access;
pragma Precondition (Is_Path_Expression (N));
-- This function modifies the permissions of a given node in the permission
-- environment as well as all the prefixes of the path, to the new
@@ -817,13 +875,18 @@ package body Sem_SPARK is
Typ : Entity_Id;
Kind : Formal_Kind;
Subp : Entity_Id;
- Global_Var : Boolean);
+ Global_Var : Boolean;
+ Expl : Node_Id);
-- Auxiliary procedure to Setup_Parameters and Setup_Globals
procedure Setup_Parameters (Subp : Entity_Id);
-- Takes a subprogram as input, and sets up the environment by adding
-- formal parameters with appropriate permissions.
+ procedure Setup_Protected_Components (Subp : Entity_Id);
+ -- Takes a protected operation as input, and sets up the environment by
+ -- adding protected components with appropriate permissions.
+
----------------------
-- Global Variables --
----------------------
@@ -903,7 +966,7 @@ package body Sem_SPARK is
null;
else
Handle_Parameter_Or_Global (Expr => Item,
- Formal_Typ => Etype (Item),
+ Formal_Typ => Retysp (Etype (Item)),
Param_Mode => Kind,
Subp => Subp,
Global_Var => True);
@@ -1020,9 +1083,12 @@ package body Sem_SPARK is
and then (Is_Traversal_Function_Call (Expr)
or else Get_Root_Object (Borrowed) /= Var)
then
- Error_Msg_NE
- ("source of assignment must have & as root (SPARK RM 3.10(8)))",
- Expr, Var);
+ if Emit_Messages then
+ Error_Msg_NE
+ ("source of assignment must have & as root" &
+ " (SPARK RM 3.10(8)))",
+ Expr, Var);
+ end if;
return;
end if;
@@ -1049,9 +1115,12 @@ package body Sem_SPARK is
and then (Is_Traversal_Function_Call (Expr)
or else Get_Root_Object (Observed) /= Var)
then
- Error_Msg_NE
- ("source of assignment must have & as root (SPARK RM 3.10(8)))",
- Expr, Var);
+ if Emit_Messages then
+ Error_Msg_NE
+ ("source of assignment must have & as root" &
+ " (SPARK RM 3.10(8)))",
+ Expr, Var);
+ end if;
return;
end if;
@@ -1106,6 +1175,7 @@ package body Sem_SPARK is
if Perm = No_Access then
Perm_Error (Expr, No_Access, No_Access,
+ Expl => Get_Expl (Expr),
Forbidden_Perm => True);
return;
end if;
@@ -1114,6 +1184,7 @@ package body Sem_SPARK is
if Perm = No_Access then
Perm_Error (Expr, No_Access, No_Access,
+ Expl => Get_Expl (Expr_Root),
Forbidden_Perm => True);
return;
end if;
@@ -1133,21 +1204,25 @@ package body Sem_SPARK is
Perm := Get_Perm (Expr);
if Perm /= Read_Write then
- Perm_Error (Expr, Read_Write, Perm);
+ Perm_Error (Expr, Read_Write, Perm, Expl => Get_Expl (Expr));
return;
end if;
if not Is_Decl then
if not Is_Entity_Name (Target) then
- Error_Msg_N
- ("target of borrow must be stand-alone variable",
- Target);
+ if Emit_Messages then
+ Error_Msg_N
+ ("target of borrow must be stand-alone variable",
+ Target);
+ end if;
return;
elsif Target_Root /= Expr_Root then
- Error_Msg_NE
- ("source of borrow must be variable &",
- Expr, Target);
+ if Emit_Messages then
+ Error_Msg_NE
+ ("source of borrow must be variable &",
+ Expr, Target);
+ end if;
return;
end if;
end if;
@@ -1162,7 +1237,9 @@ package body Sem_SPARK is
Check_Expression (Expr, Move);
else
- Error_Msg_N ("expression not allowed as source of move", Expr);
+ if Emit_Messages then
+ Error_Msg_N ("expression not allowed as source of move", Expr);
+ end if;
return;
end if;
@@ -1195,7 +1272,7 @@ package body Sem_SPARK is
begin
Check_Parameter_Or_Global
(Expr => Actual,
- Typ => Underlying_Type (Etype (Formal)),
+ Typ => Retysp (Etype (Formal)),
Kind => Ekind (Formal),
Subp => Subp,
Global_Var => False);
@@ -1229,7 +1306,15 @@ package body Sem_SPARK is
begin
Inside_Procedure_Call := True;
Check_Params (Call);
- Check_Globals (Get_Called_Entity (Call));
+ if Ekind (Get_Called_Entity (Call)) = E_Subprogram_Type then
+ if Emit_Messages then
+ Error_Msg_N
+ ("call through access to subprogram is not allowed in SPARK",
+ Call);
+ end if;
+ else
+ Check_Globals (Get_Called_Entity (Call));
+ end if;
Inside_Procedure_Call := False;
Update_Params (Call);
@@ -1260,6 +1345,17 @@ package body Sem_SPARK is
Inside_Elaboration := False;
+ if Ekind (Spec_Id) = E_Function
+ and then Is_Anonymous_Access_Type (Etype (Spec_Id))
+ and then not Is_Traversal_Function (Spec_Id)
+ then
+ if Emit_Messages then
+ Error_Msg_N ("anonymous access type for result only allowed for "
+ & "traversal functions", Spec_Id);
+ end if;
+ return;
+ end if;
+
-- Save environment and put a new one in place
Move_Env (Current_Perm_Env, Saved_Env);
@@ -1273,6 +1369,13 @@ package body Sem_SPARK is
Setup_Globals (Spec_Id);
end if;
+ -- For protected operations, add protected components to the environment
+ -- with adequate permissions.
+
+ if Is_Protected_Operation (Spec_Id) then
+ Setup_Protected_Components (Spec_Id);
+ end if;
+
-- Analyze the body of the subprogram
Check_List (Declarations (Body_N));
@@ -1316,9 +1419,37 @@ package body Sem_SPARK is
Check_Expression (Subtype_Indication (Decl), Read);
when N_Object_Declaration =>
+ Expr := Expression (Decl);
+
Check_Type (Target_Typ);
- Expr := Expression (Decl);
+ -- A declaration of a stand-alone object of an anonymous access
+ -- type shall have an explicit initial value and shall occur
+ -- immediately within a subprogram body, an entry body, or a
+ -- block statement (SPARK RM 3.10(4)).
+
+ if Is_Anonymous_Access_Type (Target_Typ) then
+ declare
+ Scop : constant Entity_Id := Scope (Target);
+ begin
+ if not Is_Local_Context (Scop) then
+ if Emit_Messages then
+ Error_Msg_N
+ ("object of anonymous access type must be declared "
+ & "immediately within a subprogram, entry or block "
+ & "(SPARK RM 3.10(4))", Decl);
+ end if;
+ end if;
+ end;
+
+ if No (Expr) then
+ if Emit_Messages then
+ Error_Msg_N ("object of anonymous access type must be "
+ & "initialized (SPARK RM 3.10(4))", Decl);
+ end if;
+ end if;
+ end if;
+
if Present (Expr) then
Check_Assignment (Target => Target,
Expr => Expr);
@@ -1331,6 +1462,7 @@ package body Sem_SPARK is
(Tree =>
(Kind => Entire_Object,
Is_Node_Deep => True,
+ Explanation => Decl,
Permission => Read_Write,
Children_Permission => Read_Write));
begin
@@ -1375,13 +1507,22 @@ package body Sem_SPARK is
-- Check_Expression --
----------------------
- procedure Check_Expression (Expr : Node_Id; Mode : Checking_Mode) is
-
+ procedure Check_Expression
+ (Expr : Node_Id;
+ Mode : Extended_Checking_Mode)
+ is
-- Local subprograms
function Is_Type_Name (Expr : Node_Id) return Boolean;
-- Detect when a path expression is in fact a type name
+ procedure Move_Expression (Expr : Node_Id);
+ -- Some subexpressions are only analyzed in Move mode. This is a
+ -- specialized version of Check_Expression for that case.
+
+ procedure Move_Expression_List (L : List_Id);
+ -- Call Move_Expression on every expression in the list L
+
procedure Read_Expression (Expr : Node_Id);
-- Most subexpressions are only analyzed in Read mode. This is a
-- specialized version of Check_Expression for that case.
@@ -1390,7 +1531,6 @@ package body Sem_SPARK is
-- Call Read_Expression on every expression in the list L
procedure Read_Indexes (Expr : Node_Id);
- pragma Precondition (Is_Path_Expression (Expr));
-- When processing a path, the index expressions and function call
-- arguments occurring on the path should be analyzed in Read mode.
@@ -1405,6 +1545,36 @@ package body Sem_SPARK is
end Is_Type_Name;
---------------------
+ -- Move_Expression --
+ ---------------------
+
+ -- Distinguish the case where the argument is a path expression that
+ -- needs explicit moving.
+
+ procedure Move_Expression (Expr : Node_Id) is
+ begin
+ if Is_Path_Expression (Expr) then
+ Check_Expression (Expr, Move);
+ else
+ Read_Expression (Expr);
+ end if;
+ end Move_Expression;
+
+ --------------------------
+ -- Move_Expression_List --
+ --------------------------
+
+ procedure Move_Expression_List (L : List_Id) is
+ N : Node_Id;
+ begin
+ N := First (L);
+ while Present (N) loop
+ Move_Expression (N);
+ Next (N);
+ end loop;
+ end Move_Expression_List;
+
+ ---------------------
-- Read_Expression --
---------------------
@@ -1435,7 +1605,26 @@ package body Sem_SPARK is
-- Local subprograms
+ function Is_Singleton_Choice (Choices : List_Id) return Boolean;
+ -- Return whether Choices is a singleton choice
+
procedure Read_Param (Formal : Entity_Id; Actual : Node_Id);
+ -- Call Read_Expression on the actual
+
+ -------------------------
+ -- Is_Singleton_Choice --
+ -------------------------
+
+ function Is_Singleton_Choice (Choices : List_Id) return Boolean is
+ Choice : constant Node_Id := First (Choices);
+ begin
+ return List_Length (Choices) = 1
+ and then Nkind (Choice) /= N_Others_Choice
+ and then not Nkind_In (Choice, N_Subtype_Indication, N_Range)
+ and then not
+ (Nkind_In (Choice, N_Identifier, N_Expanded_Name)
+ and then Is_Type (Entity (Choice)));
+ end Is_Singleton_Choice;
----------------
-- Read_Param --
@@ -1452,6 +1641,14 @@ package body Sem_SPARK is
-- Start of processing for Read_Indexes
begin
+ if not Is_Subpath_Expression (Expr) then
+ if Emit_Messages then
+ Error_Msg_N
+ ("name expected here for move/borrow/observe", Expr);
+ end if;
+ return;
+ end if;
+
case N_Subexpr'(Nkind (Expr)) is
when N_Identifier
| N_Expanded_Name
@@ -1472,12 +1669,27 @@ package body Sem_SPARK is
Read_Indexes (Prefix (Expr));
Read_Expression (Discrete_Range (Expr));
+ -- The argument of an allocator is moved as part of the implicit
+ -- assignment.
+
when N_Allocator =>
- Read_Expression (Expression (Expr));
+ Move_Expression (Expression (Expr));
when N_Function_Call =>
Read_Params (Expr);
- Check_Globals (Get_Called_Entity (Expr));
+ if Ekind (Get_Called_Entity (Expr)) = E_Subprogram_Type then
+ if Emit_Messages then
+ Error_Msg_N
+ ("call through access to subprogram is not allowed in "
+ & "SPARK", Expr);
+ end if;
+ else
+ Check_Globals (Get_Called_Entity (Expr));
+ end if;
+
+ when N_Op_Concat =>
+ Read_Expression (Left_Opnd (Expr));
+ Read_Expression (Right_Opnd (Expr));
when N_Qualified_Expression
| N_Type_Conversion
@@ -1485,6 +1697,142 @@ package body Sem_SPARK is
=>
Read_Indexes (Expression (Expr));
+ when N_Aggregate =>
+ declare
+ Assocs : constant List_Id := Component_Associations (Expr);
+ CL : List_Id;
+ Assoc : Node_Id := Nlists.First (Assocs);
+ Choice : Node_Id;
+
+ begin
+ -- The subexpressions of an aggregate are moved as part
+ -- of the implicit assignments. Handle the positional
+ -- components first.
+
+ Move_Expression_List (Expressions (Expr));
+
+ -- Handle the named components next
+
+ while Present (Assoc) loop
+ CL := Choices (Assoc);
+
+ -- For an array aggregate, we should also check that the
+ -- expressions used in choices are readable.
+
+ if Is_Array_Type (Etype (Expr)) then
+ Choice := Nlists.First (CL);
+ while Present (Choice) loop
+ if Nkind (Choice) /= N_Others_Choice then
+ Read_Expression (Choice);
+ end if;
+ Next (Choice);
+ end loop;
+ end if;
+
+ -- There can be only one element for a value of deep type
+ -- in order to avoid aliasing.
+
+ if not Box_Present (Assoc)
+ and then Is_Deep (Etype (Expression (Assoc)))
+ and then not Is_Singleton_Choice (CL)
+ and then Emit_Messages
+ then
+ Error_Msg_F
+ ("singleton choice required to prevent aliasing",
+ First (CL));
+ end if;
+
+ -- The subexpressions of an aggregate are moved as part
+ -- of the implicit assignments.
+
+ if not Box_Present (Assoc) then
+ Move_Expression (Expression (Assoc));
+ end if;
+
+ Next (Assoc);
+ end loop;
+ end;
+
+ when N_Extension_Aggregate =>
+ declare
+ Exprs : constant List_Id := Expressions (Expr);
+ Assocs : constant List_Id := Component_Associations (Expr);
+ CL : List_Id;
+ Assoc : Node_Id := Nlists.First (Assocs);
+
+ begin
+ Move_Expression (Ancestor_Part (Expr));
+
+ -- No positional components allowed at this stage
+
+ if Present (Exprs) then
+ raise Program_Error;
+ end if;
+
+ while Present (Assoc) loop
+ CL := Choices (Assoc);
+
+ -- Only singleton components allowed at this stage
+
+ if not Is_Singleton_Choice (CL) then
+ raise Program_Error;
+ end if;
+
+ -- The subexpressions of an aggregate are moved as part
+ -- of the implicit assignments.
+
+ if not Box_Present (Assoc) then
+ Move_Expression (Expression (Assoc));
+ end if;
+
+ Next (Assoc);
+ end loop;
+ end;
+
+ when N_If_Expression =>
+ declare
+ Cond : constant Node_Id := First (Expressions (Expr));
+ Then_Part : constant Node_Id := Next (Cond);
+ Else_Part : constant Node_Id := Next (Then_Part);
+ begin
+ Read_Expression (Cond);
+ Read_Indexes (Then_Part);
+ Read_Indexes (Else_Part);
+ end;
+
+ when N_Case_Expression =>
+ declare
+ Cases : constant List_Id := Alternatives (Expr);
+ Cur_Case : Node_Id := First (Cases);
+
+ begin
+ Read_Expression (Expression (Expr));
+
+ while Present (Cur_Case) loop
+ Read_Indexes (Expression (Cur_Case));
+ Next (Cur_Case);
+ end loop;
+ end;
+
+ when N_Attribute_Reference =>
+ pragma Assert
+ (Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Loop_Entry
+ or else
+ Get_Attribute_Id (Attribute_Name (Expr)) = Attribute_Update
+ or else
+ Get_Attribute_Id (Attribute_Name (Expr)) = Attribute_Image);
+
+ Read_Expression (Prefix (Expr));
+
+ if Get_Attribute_Id (Attribute_Name (Expr)) = Attribute_Update
+ or else (Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Image
+ and then Is_Type_Name (Prefix (Expr)))
+ then
+ Read_Expression_List (Expressions (Expr));
+ end if;
+
when others =>
raise Program_Error;
end case;
@@ -1497,15 +1845,26 @@ package body Sem_SPARK is
return;
elsif Is_Path_Expression (Expr) then
- Read_Indexes (Expr);
- Process_Path (Expr, Mode);
+ if Mode /= Assign then
+ Read_Indexes (Expr);
+ end if;
+
+ if Mode /= Read_Subexpr then
+ Process_Path (Expr, Mode);
+ end if;
+
return;
end if;
-- Expressions that are not path expressions should only be analyzed in
-- Read mode.
- pragma Assert (Mode = Read);
+ if Mode /= Read then
+ if Emit_Messages then
+ Error_Msg_N ("name expected here for move/borrow/observe", Expr);
+ end if;
+ return;
+ end if;
-- Special handling for nodes that may contain evaluated expressions in
-- the form of constraints.
@@ -1539,6 +1898,20 @@ package body Sem_SPARK is
end if;
return;
+ when N_Digits_Constraint =>
+ Read_Expression (Digits_Expression (Expr));
+ if Present (Range_Constraint (Expr)) then
+ Read_Expression (Range_Constraint (Expr));
+ end if;
+ return;
+
+ when N_Delta_Constraint =>
+ Read_Expression (Delta_Expression (Expr));
+ if Present (Range_Constraint (Expr)) then
+ Read_Expression (Range_Constraint (Expr));
+ end if;
+ return;
+
when others =>
null;
end case;
@@ -1548,12 +1921,28 @@ package body Sem_SPARK is
case N_Subexpr'(Nkind (Expr)) is
when N_Binary_Op
- | N_Membership_Test
| N_Short_Circuit
=>
Read_Expression (Left_Opnd (Expr));
Read_Expression (Right_Opnd (Expr));
+ when N_Membership_Test =>
+ Read_Expression (Left_Opnd (Expr));
+ if Present (Right_Opnd (Expr)) then
+ Read_Expression (Right_Opnd (Expr));
+ else
+ declare
+ Cases : constant List_Id := Alternatives (Expr);
+ Cur_Case : Node_Id := First (Cases);
+
+ begin
+ while Present (Cur_Case) loop
+ Read_Expression (Cur_Case);
+ Next (Cur_Case);
+ end loop;
+ end;
+ end if;
+
when N_Unary_Op =>
Read_Expression (Right_Opnd (Expr));
@@ -1637,6 +2026,14 @@ package body Sem_SPARK is
when Attribute_Modulus =>
null;
+ -- The following attributes apply to types; there are no
+ -- expressions to read.
+
+ when Attribute_Class
+ | Attribute_Storage_Size
+ =>
+ null;
+
-- Postconditions should not be analyzed
when Attribute_Old
@@ -1645,8 +2042,7 @@ package body Sem_SPARK is
raise Program_Error;
when others =>
- Error_Msg_Name_1 := Aname;
- Error_Msg_N ("attribute % not allowed in SPARK", Expr);
+ null;
end case;
end;
@@ -1699,45 +2095,6 @@ package body Sem_SPARK is
Read_Expression (Condition (Expr));
end;
- when N_Aggregate =>
- declare
- Assocs : constant List_Id := Component_Associations (Expr);
- Assoc : Node_Id := First (Assocs);
- CL : List_Id;
- Choice : Node_Id;
-
- begin
- while Present (Assoc) loop
-
- -- An array aggregate with a single component association
- -- may have a nonstatic choice expression that needs to be
- -- analyzed. This can only occur for a single choice that
- -- is not the OTHERS one.
-
- if Is_Array_Type (Etype (Expr)) then
- CL := Choices (Assoc);
- if List_Length (CL) = 1 then
- Choice := First (CL);
- if Nkind (Choice) /= N_Others_Choice then
- Read_Expression (Choice);
- end if;
- end if;
- end if;
-
- -- The expression in the component association also needs to
- -- be analyzed.
-
- Read_Expression (Expression (Assoc));
- Next (Assoc);
- end loop;
-
- Read_Expression_List (Expressions (Expr));
- end;
-
- when N_Extension_Aggregate =>
- Read_Expression (Ancestor_Part (Expr));
- Read_Expression_List (Expressions (Expr));
-
when N_Character_Literal
| N_Numeric_Or_String_Literal
| N_Operator_Symbol
@@ -1749,7 +2106,7 @@ package body Sem_SPARK is
when N_Delta_Aggregate
| N_Target_Name
=>
- Error_Msg_N ("unsupported construct in SPARK", Expr);
+ null;
-- Procedure calls are handled in Check_Node
@@ -1758,9 +2115,11 @@ package body Sem_SPARK is
-- Path expressions are handled before this point
- when N_Allocator
+ when N_Aggregate
+ | N_Allocator
| N_Expanded_Name
| N_Explicit_Dereference
+ | N_Extension_Aggregate
| N_Function_Call
| N_Identifier
| N_Indexed_Component
@@ -1819,7 +2178,8 @@ package body Sem_SPARK is
(E : Entity_Id;
Loop_Id : Node_Id;
Perm : Perm_Kind;
- Found_Perm : Perm_Kind);
+ Found_Perm : Perm_Kind;
+ Expl : Node_Id);
-- A procedure that is called when the permissions found contradict
-- the rules established by the RM at the exit of loops. This function
-- is called with the entity, the node of the enclosing loop, the
@@ -1889,14 +2249,15 @@ package body Sem_SPARK is
begin
if not (Permission (Tree) >= Perm) then
Perm_Error_Loop_Exit
- (E, Stmt, Permission (Tree), Perm);
+ (E, Stmt, Permission (Tree), Perm, Explanation (Tree));
end if;
case Kind (Tree) is
when Entire_Object =>
if not (Children_Permission (Tree) >= Perm) then
Perm_Error_Loop_Exit
- (E, Stmt, Children_Permission (Tree), Perm);
+ (E, Stmt, Children_Permission (Tree), Perm,
+ Explanation (Tree));
end if;
@@ -1934,14 +2295,15 @@ package body Sem_SPARK is
begin
if not (Perm >= Permission (Tree)) then
Perm_Error_Loop_Exit
- (E, Stmt, Permission (Tree), Perm);
+ (E, Stmt, Permission (Tree), Perm, Explanation (Tree));
end if;
case Kind (Tree) is
when Entire_Object =>
if not (Perm >= Children_Permission (Tree)) then
Perm_Error_Loop_Exit
- (E, Stmt, Children_Permission (Tree), Perm);
+ (E, Stmt, Children_Permission (Tree), Perm,
+ Explanation (Tree));
end if;
when Reference =>
@@ -1974,7 +2336,8 @@ package body Sem_SPARK is
(E => E,
Loop_Id => Stmt,
Perm => Permission (New_Tree),
- Found_Perm => Permission (Orig_Tree));
+ Found_Perm => Permission (Orig_Tree),
+ Expl => Explanation (New_Tree));
end if;
case Kind (New_Tree) is
@@ -1994,7 +2357,8 @@ package body Sem_SPARK is
Perm_Error_Loop_Exit
(E, Stmt,
Children_Permission (New_Tree),
- Children_Permission (Orig_Tree));
+ Children_Permission (Orig_Tree),
+ Explanation (New_Tree));
end if;
when Reference =>
@@ -2073,16 +2437,16 @@ package body Sem_SPARK is
KeyO := Perm_Tree_Maps.Get_First_Key
(Component (Orig_Tree));
while KeyO.Present loop
+ CompN := Perm_Tree_Maps.Get
+ (Component (New_Tree), KeyO.K);
+ CompO := Perm_Tree_Maps.Get
+ (Component (Orig_Tree), KeyO.K);
pragma Assert (CompO /= null);
Check_Is_Less_Restrictive_Tree (CompN, CompO, E);
KeyO := Perm_Tree_Maps.Get_Next_Key
(Component (Orig_Tree));
- CompN := Perm_Tree_Maps.Get
- (Component (New_Tree), KeyO.K);
- CompO := Perm_Tree_Maps.Get
- (Component (Orig_Tree), KeyO.K);
end loop;
end;
@@ -2101,14 +2465,19 @@ package body Sem_SPARK is
(E : Entity_Id;
Loop_Id : Node_Id;
Perm : Perm_Kind;
- Found_Perm : Perm_Kind)
+ Found_Perm : Perm_Kind;
+ Expl : Node_Id)
is
begin
- Error_Msg_Node_2 := Loop_Id;
- Error_Msg_N ("insufficient permission for & when exiting loop &", E);
- Perm_Mismatch (Exp_Perm => Perm,
- Act_Perm => Found_Perm,
- N => Loop_Id);
+ if Emit_Messages then
+ Error_Msg_Node_2 := Loop_Id;
+ Error_Msg_N
+ ("insufficient permission for & when exiting loop &", E);
+ Perm_Mismatch (Exp_Perm => Perm,
+ Act_Perm => Found_Perm,
+ N => Loop_Id,
+ Expl => Expl);
+ end if;
end Perm_Error_Loop_Exit;
-- Local variables
@@ -2229,13 +2598,17 @@ package body Sem_SPARK is
Check_Call_Statement (N);
when N_Package_Body =>
- Check_Package_Body (N);
+ if not Is_Generic_Unit (Unique_Defining_Entity (N)) then
+ Check_Package_Body (N);
+ end if;
when N_Subprogram_Body
| N_Entry_Body
| N_Task_Body
=>
- Check_Callable_Body (N);
+ if not Is_Generic_Unit (Unique_Defining_Entity (N)) then
+ Check_Callable_Body (N);
+ end if;
when N_Protected_Body =>
Check_List (Declarations (N));
@@ -2280,6 +2653,7 @@ package body Sem_SPARK is
| N_Package_Instantiation
| N_Package_Renaming_Declaration
| N_Procedure_Instantiation
+ | N_Raise_xxx_Error
| N_Record_Representation_Clause
| N_Subprogram_Declaration
| N_Subprogram_Renaming_Declaration
@@ -2311,39 +2685,43 @@ package body Sem_SPARK is
Save_In_Elab : constant Boolean := Inside_Elaboration;
Spec : constant Node_Id :=
Package_Specification (Corresponding_Spec (Pack));
- Prag : constant Node_Id := SPARK_Pragma (Defining_Entity (Pack));
+ Id : constant Entity_Id := Defining_Entity (Pack);
+ Prag : constant Node_Id := SPARK_Pragma (Id);
+ Aux_Prag : constant Node_Id := SPARK_Aux_Pragma (Id);
Saved_Env : Perm_Env;
begin
- -- Only SPARK bodies are analyzed
-
- if No (Prag)
- or else Get_SPARK_Mode_From_Annotation (Prag) /= Opt.On
+ if Present (Prag)
+ and then Get_SPARK_Mode_From_Annotation (Prag) = Opt.On
then
- return;
- end if;
+ Inside_Elaboration := True;
- Inside_Elaboration := True;
+ -- Save environment and put a new one in place
- -- Save environment and put a new one in place
+ Move_Env (Current_Perm_Env, Saved_Env);
- Move_Env (Current_Perm_Env, Saved_Env);
+ -- Reanalyze package spec to have its variables in the environment
- -- Reanalyze package spec to have its variables in the environment
+ Check_List (Visible_Declarations (Spec));
+ Check_List (Private_Declarations (Spec));
- Check_List (Visible_Declarations (Spec));
- Check_List (Private_Declarations (Spec));
+ -- Check declarations and statements in the special mode for
+ -- elaboration.
- -- Check declarations and statements in the special mode for elaboration
+ Check_List (Declarations (Pack));
- Check_List (Declarations (Pack));
- Check_Node (Handled_Statement_Sequence (Pack));
+ if Present (Aux_Prag)
+ and then Get_SPARK_Mode_From_Annotation (Aux_Prag) = Opt.On
+ then
+ Check_Node (Handled_Statement_Sequence (Pack));
+ end if;
- -- Restore the saved environment and free the current one
+ -- Restore the saved environment and free the current one
- Move_Env (Saved_Env, Current_Perm_Env);
+ Move_Env (Saved_Env, Current_Perm_Env);
- Inside_Elaboration := Save_In_Elab;
+ Inside_Elaboration := Save_In_Elab;
+ end if;
end Check_Package_Body;
------------------------
@@ -2353,25 +2731,41 @@ package body Sem_SPARK is
procedure Check_Package_Spec (Pack : Node_Id) is
Save_In_Elab : constant Boolean := Inside_Elaboration;
Spec : constant Node_Id := Specification (Pack);
+ Id : constant Entity_Id := Defining_Entity (Pack);
+ Prag : constant Node_Id := SPARK_Pragma (Id);
+ Aux_Prag : constant Node_Id := SPARK_Aux_Pragma (Id);
Saved_Env : Perm_Env;
begin
- Inside_Elaboration := True;
+ if Present (Prag)
+ and then Get_SPARK_Mode_From_Annotation (Prag) = Opt.On
+ then
+ Inside_Elaboration := True;
- -- Save environment and put a new one in place
+ -- Save environment and put a new one in place
- Move_Env (Current_Perm_Env, Saved_Env);
+ Move_Env (Current_Perm_Env, Saved_Env);
- -- Check declarations in the special mode for elaboration
+ -- Check declarations in the special mode for elaboration
- Check_List (Visible_Declarations (Spec));
- Check_List (Private_Declarations (Spec));
+ Check_List (Visible_Declarations (Spec));
- -- Restore the saved environment and free the current one
+ if Present (Aux_Prag)
+ and then Get_SPARK_Mode_From_Annotation (Aux_Prag) = Opt.On
+ then
+ Check_List (Private_Declarations (Spec));
+ end if;
- Move_Env (Saved_Env, Current_Perm_Env);
+ -- Restore the saved environment and free the current one. As part of
+ -- the restoration, the environment of the package spec is merged in
+ -- the enclosing environment, which may be an enclosing
+ -- package/subprogram spec or body which has access to the variables
+ -- of the package spec.
- Inside_Elaboration := Save_In_Elab;
+ Merge_Env (Saved_Env, Current_Perm_Env);
+
+ Inside_Elaboration := Save_In_Elab;
+ end if;
end Check_Package_Spec;
-------------------------------
@@ -2442,6 +2836,10 @@ package body Sem_SPARK is
Mode := Move;
end case;
+ if Mode = Assign then
+ Check_Expression (Expr, Read_Subexpr);
+ end if;
+
Check_Expression (Expr, Mode);
end Check_Parameter_Or_Global;
@@ -2458,7 +2856,7 @@ package body Sem_SPARK is
Prag_Id : constant Pragma_Id := Get_Pragma_Id (Prag);
Arg1 : constant Node_Id :=
First (Pragma_Argument_Associations (Prag));
- Arg2 : Node_Id;
+ Arg2 : Node_Id := Empty;
begin
if Present (Arg1) then
@@ -2478,9 +2876,14 @@ package body Sem_SPARK is
-- independently for R permission. Outputs are checked
-- independently to have RW permission on exit.
- when Pragma_Contract_Cases
+ -- Postconditions are checked for correct use of 'Old, but starting
+ -- from the corresponding declaration, in order to avoid dealing with
+ -- with contracts on generic subprograms, which are not handled in
+ -- GNATprove.
+
+ when Pragma_Precondition
| Pragma_Postcondition
- | Pragma_Precondition
+ | Pragma_Contract_Cases
| Pragma_Refined_Post
=>
null;
@@ -2549,11 +2952,6 @@ package body Sem_SPARK is
Reset (Current_Perm_Env);
end Initialize;
- -- Local variables
-
- Prag : Node_Id;
- -- SPARK_Mode pragma in application
-
-- Start of processing for Check_Safe_Pointers
begin
@@ -2567,20 +2965,28 @@ package body Sem_SPARK is
| N_Package_Declaration
| N_Subprogram_Body
=>
- Prag := SPARK_Pragma (Defining_Entity (N));
+ declare
+ E : constant Entity_Id := Defining_Entity (N);
+ Prag : constant Node_Id := SPARK_Pragma (E);
+ -- SPARK_Mode pragma in application
- if Present (Prag) then
- if Get_SPARK_Mode_From_Annotation (Prag) = Opt.On then
- Check_Node (N);
- end if;
+ begin
+ if Ekind (Unique_Entity (E)) in Generic_Unit_Kind then
+ null;
+
+ elsif Present (Prag) then
+ if Get_SPARK_Mode_From_Annotation (Prag) = Opt.On then
+ Check_Node (N);
+ end if;
- elsif Nkind (N) = N_Package_Body then
- Check_List (Declarations (N));
+ elsif Nkind (N) = N_Package_Body then
+ Check_List (Declarations (N));
- elsif Nkind (N) = N_Package_Declaration then
- Check_List (Private_Declarations (Specification (N)));
- Check_List (Visible_Declarations (Specification (N)));
- end if;
+ elsif Nkind (N) = N_Package_Declaration then
+ Check_List (Private_Declarations (Specification (N)));
+ Check_List (Visible_Declarations (Specification (N)));
+ end if;
+ end;
when others =>
null;
@@ -2613,17 +3019,20 @@ package body Sem_SPARK is
-- function.
if No (Root) then
- if Nkind (Expr) = N_Function_Call then
- Error_Msg_N
- ("incorrect borrow or observe (SPARK RM 3.10(3))", Expr);
- Error_Msg_N
- ("\function called must be a traversal function", Expr);
- else
- Error_Msg_N
- ("incorrect borrow or observe (SPARK RM 3.10(3))", Expr);
- Error_Msg_N
- ("\expression must be part of stand-alone object or parameter",
- Expr);
+ if Emit_Messages then
+ if Nkind (Expr) = N_Function_Call then
+ Error_Msg_N
+ ("incorrect borrow or observe (SPARK RM 3.10(3))", Expr);
+ Error_Msg_N
+ ("\function called must be a traversal function", Expr);
+ else
+ Error_Msg_N
+ ("incorrect borrow or observe (SPARK RM 3.10(3))", Expr);
+ Error_Msg_N
+ ("\expression must be part of stand-alone object or " &
+ "parameter",
+ Expr);
+ end if;
end if;
Status := Error;
@@ -2648,7 +3057,14 @@ package body Sem_SPARK is
when N_Assignment_Statement =>
declare
Target : constant Node_Id := Name (Stmt);
+
begin
+ -- Start with checking that the subexpressions of the target
+ -- path are readable, before possibly updating the permission
+ -- of these subexpressions in Check_Assignment.
+
+ Check_Expression (Target, Read_Subexpr);
+
Check_Assignment (Target => Target,
Expr => Expression (Stmt));
@@ -2661,7 +3077,9 @@ package body Sem_SPARK is
if No (Get_Root_Object
(Target, Through_Traversal => False))
then
- Error_Msg_N ("illegal target for assignment", Target);
+ if Emit_Messages then
+ Error_Msg_N ("illegal target for assignment", Target);
+ end if;
return;
end if;
@@ -2770,11 +3188,11 @@ package body Sem_SPARK is
if Nkind (Expr) /= N_Null then
declare
Expr_Root : constant Entity_Id :=
- Get_Root_Object (Expr);
+ Get_Root_Object (Expr, Is_Traversal => True);
Param : constant Entity_Id :=
First_Formal (Subp);
begin
- if Param /= Expr_Root then
+ if Param /= Expr_Root and then Emit_Messages then
Error_Msg_NE
("returned value must be rooted in "
& "traversed parameter & "
@@ -2792,9 +3210,11 @@ package body Sem_SPARK is
Check_Expression (Expr, Move);
else
- Error_Msg_N
- ("expression not allowed as source of move",
- Expr);
+ if Emit_Messages then
+ Error_Msg_N
+ ("expression not allowed as source of move",
+ Expr);
+ end if;
return;
end if;
@@ -2817,14 +3237,14 @@ package body Sem_SPARK is
Subp : constant Entity_Id :=
Return_Applies_To (Return_Statement_Entity (Stmt));
Decls : constant List_Id := Return_Object_Declarations (Stmt);
- Decl : constant Node_Id := Last (Decls);
+ Decl : constant Node_Id := Last_Non_Pragma (Decls);
Obj : constant Entity_Id := Defining_Identifier (Decl);
Perm : Perm_Kind;
begin
-- SPARK RM 3.10(5): return statement of traversal function
- if Is_Traversal_Function (Subp) then
+ if Is_Traversal_Function (Subp) and then Emit_Messages then
Error_Msg_N
("extended return cannot apply to a traversal function",
Stmt);
@@ -2833,10 +3253,13 @@ package body Sem_SPARK is
Check_List (Return_Object_Declarations (Stmt));
Check_Node (Handled_Statement_Sequence (Stmt));
- Perm := Get_Perm (Obj);
+ if Is_Deep (Etype (Obj)) then
+ Perm := Get_Perm (Obj);
- if Perm /= Read_Write then
- Perm_Error (Decl, Read_Write, Perm);
+ if Perm /= Read_Write then
+ Perm_Error (Decl, Read_Write, Perm,
+ Expl => Get_Expl (Obj));
+ end if;
end if;
if Ekind_In (Subp, E_Procedure, E_Entry)
@@ -2954,7 +3377,7 @@ package body Sem_SPARK is
| N_Selective_Accept
| N_Timed_Entry_Call
=>
- Error_Msg_N ("unsupported construct in SPARK", Stmt);
+ null;
-- The following nodes are never generated in GNATprove mode
@@ -2970,12 +3393,12 @@ package body Sem_SPARK is
----------------
procedure Check_Type (Typ : Entity_Id) is
- Check_Typ : constant Entity_Id := Underlying_Type (Typ);
+ Check_Typ : constant Entity_Id := Retysp (Typ);
begin
case Type_Kind'(Ekind (Check_Typ)) is
when Access_Kind =>
- case Access_Kind'(Ekind (Underlying_Type (Check_Typ))) is
+ case Access_Kind'(Ekind (Check_Typ)) is
when E_Access_Type
| E_Anonymous_Access_Type
=>
@@ -2983,18 +3406,26 @@ package body Sem_SPARK is
when E_Access_Subtype =>
Check_Type (Base_Type (Check_Typ));
when E_Access_Attribute_Type =>
- Error_Msg_N ("access attribute not allowed in SPARK",
- Check_Typ);
+ if Emit_Messages then
+ Error_Msg_N ("access attribute not allowed in SPARK",
+ Check_Typ);
+ end if;
when E_Allocator_Type =>
- Error_Msg_N ("missing type resolution", Check_Typ);
+ if Emit_Messages then
+ Error_Msg_N ("missing type resolution", Check_Typ);
+ end if;
when E_General_Access_Type =>
- Error_Msg_NE
- ("general access type & not allowed in SPARK",
- Check_Typ, Check_Typ);
+ if Emit_Messages then
+ Error_Msg_NE
+ ("general access type & not allowed in SPARK",
+ Check_Typ, Check_Typ);
+ end if;
when Access_Subprogram_Kind =>
- Error_Msg_NE
- ("access to subprogram type & not allowed in SPARK",
- Check_Typ, Check_Typ);
+ if Emit_Messages then
+ Error_Msg_NE
+ ("access to subprogram type & not allowed in SPARK",
+ Check_Typ, Check_Typ);
+ end if;
end case;
when E_Array_Type
@@ -3007,9 +3438,11 @@ package body Sem_SPARK is
and then (Is_Tagged_Type (Check_Typ)
or else Is_Class_Wide_Type (Check_Typ))
then
- Error_Msg_NE
- ("tagged type & cannot be owning in SPARK",
- Check_Typ, Check_Typ);
+ if Emit_Messages then
+ Error_Msg_NE
+ ("tagged type & cannot be owning in SPARK",
+ Check_Typ, Check_Typ);
+ end if;
else
declare
@@ -3017,7 +3450,12 @@ package body Sem_SPARK is
begin
Comp := First_Component_Or_Discriminant (Check_Typ);
while Present (Comp) loop
- Check_Type (Etype (Comp));
+
+ -- Ignore components which are not visible in SPARK
+
+ if Component_Is_Visible_In_SPARK (Comp) then
+ Check_Type (Etype (Comp));
+ end if;
Next_Component_Or_Discriminant (Comp);
end loop;
end;
@@ -3033,17 +3471,62 @@ package body Sem_SPARK is
=>
null;
- -- The following should not arise as underlying types
+ -- Do not check type whose full view is not SPARK
when E_Private_Type
| E_Private_Subtype
| E_Limited_Private_Type
| E_Limited_Private_Subtype
=>
- raise Program_Error;
+ null;
end case;
end Check_Type;
+ --------------
+ -- Get_Expl --
+ --------------
+
+ function Get_Expl (N : Node_Or_Entity_Id) return Node_Id is
+ begin
+ -- Special case for the object declared in an extended return statement
+
+ if Nkind (N) = N_Defining_Identifier then
+ declare
+ C : constant Perm_Tree_Access :=
+ Get (Current_Perm_Env, Unique_Entity (N));
+ begin
+ pragma Assert (C /= null);
+ return Explanation (C);
+ end;
+
+ -- The expression is a call to a traversal function
+
+ elsif Is_Traversal_Function_Call (N) then
+ return N;
+
+ -- The expression is directly rooted in an object
+
+ elsif Present (Get_Root_Object (N, Through_Traversal => False)) then
+ declare
+ Tree_Or_Perm : constant Perm_Or_Tree := Get_Perm_Or_Tree (N);
+ begin
+ case Tree_Or_Perm.R is
+ when Folded =>
+ return Tree_Or_Perm.Explanation;
+
+ when Unfolded =>
+ pragma Assert (Tree_Or_Perm.Tree_Access /= null);
+ return Explanation (Tree_Or_Perm.Tree_Access);
+ end case;
+ end;
+
+ -- The expression is a function call, an allocation, or null
+
+ else
+ return N;
+ end if;
+ end Get_Expl;
+
-----------------------------------
-- Get_Observed_Or_Borrowed_Expr --
-----------------------------------
@@ -3125,11 +3608,20 @@ package body Sem_SPARK is
C : constant Perm_Tree_Access :=
Get (Current_Perm_Env, Unique_Entity (Entity (N)));
begin
- pragma Assert (C /= null);
+ -- Except during elaboration, the root object should have been
+ -- declared and entered into the current permission
+ -- environment.
+
+ if not Inside_Elaboration
+ and then C = null
+ then
+ Illegal_Global_Usage (N, N);
+ end if;
+
return (R => Unfolded, Tree_Access => C);
end;
- -- For a non-terminal path, we get the permission tree of its
+ -- For a nonterminal path, we get the permission tree of its
-- prefix, and then get the subtree associated with the extension,
-- if unfolded. If folded, we return the permission associated with
-- children.
@@ -3159,7 +3651,9 @@ package body Sem_SPARK is
when Entire_Object =>
return (R => Folded,
Found_Permission =>
- Children_Permission (C.Tree_Access));
+ Children_Permission (C.Tree_Access),
+ Explanation =>
+ Explanation (C.Tree_Access));
when Reference =>
pragma Assert (Nkind (N) = N_Explicit_Dereference);
@@ -3170,7 +3664,8 @@ package body Sem_SPARK is
pragma Assert (Nkind (N) = N_Selected_Component);
declare
Comp : constant Entity_Id :=
- Entity (Selector_Name (N));
+ Original_Record_Component
+ (Entity (Selector_Name (N)));
D : constant Perm_Tree_Access :=
Perm_Tree_Maps.Get
(Component (C.Tree_Access), Comp);
@@ -3208,7 +3703,7 @@ package body Sem_SPARK is
function Get_Perm_Tree (N : Node_Id) return Perm_Tree_Access is
begin
- return Set_Perm_Prefixes (N, None);
+ return Set_Perm_Prefixes (N, None, Empty);
end Get_Perm_Tree;
---------------------
@@ -3217,9 +3712,37 @@ package body Sem_SPARK is
function Get_Root_Object
(Expr : Node_Id;
- Through_Traversal : Boolean := True) return Entity_Id
+ Through_Traversal : Boolean := True;
+ Is_Traversal : Boolean := False) return Entity_Id
is
+ function GRO (Expr : Node_Id) return Entity_Id;
+ -- Local wrapper on the actual function, to propagate the values of
+ -- optional parameters.
+
+ ---------
+ -- GRO --
+ ---------
+
+ function GRO (Expr : Node_Id) return Entity_Id is
+ begin
+ return Get_Root_Object (Expr, Through_Traversal, Is_Traversal);
+ end GRO;
+
+ Get_Root_Object : Boolean;
+ pragma Unmodified (Get_Root_Object);
+ -- Local variable to mask the name of function Get_Root_Object, to
+ -- prevent direct call. Instead GRO wrapper should be called.
+
+ -- Start of processing for Get_Root_Object
+
begin
+ if not Is_Subpath_Expression (Expr, Is_Traversal) then
+ if Emit_Messages then
+ Error_Msg_N ("name expected here for path", Expr);
+ end if;
+ return Empty;
+ end if;
+
case Nkind (Expr) is
when N_Expanded_Name
| N_Identifier
@@ -3231,12 +3754,16 @@ package body Sem_SPARK is
| N_Selected_Component
| N_Slice
=>
- return Get_Root_Object (Prefix (Expr), Through_Traversal);
+ return GRO (Prefix (Expr));
- -- There is no root object for an allocator or NULL
+ -- There is no root object for an (extension) aggregate, allocator,
+ -- concat, or NULL.
- when N_Allocator
+ when N_Aggregate
+ | N_Allocator
+ | N_Extension_Aggregate
| N_Null
+ | N_Op_Concat
=>
return Empty;
@@ -3248,7 +3775,7 @@ package body Sem_SPARK is
if Through_Traversal
and then Is_Traversal_Function_Call (Expr)
then
- return Get_Root_Object (First_Actual (Expr), Through_Traversal);
+ return GRO (First_Actual (Expr));
else
return Empty;
end if;
@@ -3257,7 +3784,81 @@ package body Sem_SPARK is
| N_Type_Conversion
| N_Unchecked_Type_Conversion
=>
- return Get_Root_Object (Expression (Expr), Through_Traversal);
+ return GRO (Expression (Expr));
+
+ when N_Attribute_Reference =>
+ pragma Assert
+ (Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Loop_Entry
+ or else
+ Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Update
+ or else Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Image);
+ return Empty;
+
+ when N_If_Expression =>
+ if Is_Traversal then
+ declare
+ Cond : constant Node_Id := First (Expressions (Expr));
+ Then_Part : constant Node_Id := Next (Cond);
+ Else_Part : constant Node_Id := Next (Then_Part);
+ Then_Root : constant Entity_Id := GRO (Then_Part);
+ Else_Root : constant Entity_Id := GRO (Else_Part);
+ begin
+ if Nkind (Then_Part) = N_Null then
+ return Else_Root;
+ elsif Nkind (Else_Part) = N_Null then
+ return Then_Part;
+ elsif Then_Root = Else_Root then
+ return Then_Root;
+ else
+ if Emit_Messages then
+ Error_Msg_N
+ ("same name expected here in each branch", Expr);
+ end if;
+ return Empty;
+ end if;
+ end;
+ else
+ if Emit_Messages then
+ Error_Msg_N ("name expected here for path", Expr);
+ end if;
+ return Empty;
+ end if;
+
+ when N_Case_Expression =>
+ if Is_Traversal then
+ declare
+ Cases : constant List_Id := Alternatives (Expr);
+ Cur_Case : Node_Id := First (Cases);
+ Cur_Root : Entity_Id;
+ Common_Root : Entity_Id := Empty;
+
+ begin
+ while Present (Cur_Case) loop
+ Cur_Root := GRO (Expression (Cur_Case));
+
+ if Common_Root = Empty then
+ Common_Root := Cur_Root;
+ elsif Common_Root /= Cur_Root then
+ if Emit_Messages then
+ Error_Msg_N
+ ("same name expected here in each branch", Expr);
+ end if;
+ return Empty;
+ end if;
+ Next (Cur_Case);
+ end loop;
+
+ return Common_Root;
+ end;
+ else
+ if Emit_Messages then
+ Error_Msg_N ("name expected here for path", Expr);
+ end if;
+ return Empty;
+ end if;
when others =>
raise Program_Error;
@@ -3360,9 +3961,10 @@ package body Sem_SPARK is
-- Illegal_Global_Usage --
--------------------------
- procedure Illegal_Global_Usage (N : Node_Or_Entity_Id) is
+ procedure Illegal_Global_Usage (N : Node_Or_Entity_Id; E : Entity_Id)
+ is
begin
- Error_Msg_NE ("cannot use global variable & of deep type", N, N);
+ Error_Msg_NE ("cannot use global variable & of deep type", N, E);
Error_Msg_N ("\without prior declaration in a Global aspect", N);
Errout.Finalize (Last_Call => True);
Errout.Output_Messages;
@@ -3375,22 +3977,27 @@ package body Sem_SPARK is
function Is_Deep (Typ : Entity_Id) return Boolean is
begin
- case Type_Kind'(Ekind (Underlying_Type (Typ))) is
+ case Type_Kind'(Ekind (Retysp (Typ))) is
when Access_Kind =>
return True;
when E_Array_Type
| E_Array_Subtype
=>
- return Is_Deep (Component_Type (Typ));
+ return Is_Deep (Component_Type (Retysp (Typ)));
when Record_Kind =>
declare
Comp : Entity_Id;
begin
- Comp := First_Component_Or_Discriminant (Typ);
+ Comp := First_Component_Or_Discriminant (Retysp (Typ));
while Present (Comp) loop
- if Is_Deep (Etype (Comp)) then
+
+ -- Ignore components not visible in SPARK
+
+ if Component_Is_Visible_In_SPARK (Comp)
+ and then Is_Deep (Etype (Comp))
+ then
return True;
end if;
Next_Component_Or_Discriminant (Comp);
@@ -3408,22 +4015,55 @@ package body Sem_SPARK is
=>
return False;
- -- The following should not arise as underlying types
+ -- Ignore full view of types if it is not in SPARK
when E_Private_Type
| E_Private_Subtype
| E_Limited_Private_Type
| E_Limited_Private_Subtype
=>
- raise Program_Error;
+ return False;
end case;
end Is_Deep;
+ ----------------------
+ -- Is_Local_Context --
+ ----------------------
+
+ function Is_Local_Context (Scop : Entity_Id) return Boolean is
+ begin
+ return Is_Subprogram_Or_Entry (Scop)
+ or else Ekind (Scop) = E_Block;
+ end Is_Local_Context;
+
------------------------
-- Is_Path_Expression --
------------------------
- function Is_Path_Expression (Expr : Node_Id) return Boolean is
+ function Is_Path_Expression
+ (Expr : Node_Id;
+ Is_Traversal : Boolean := False) return Boolean
+ is
+ function IPE (Expr : Node_Id) return Boolean;
+ -- Local wrapper on the actual function, to propagate the values of
+ -- optional parameter Is_Traversal.
+
+ ---------
+ -- IPE --
+ ---------
+
+ function IPE (Expr : Node_Id) return Boolean is
+ begin
+ return Is_Path_Expression (Expr, Is_Traversal);
+ end IPE;
+
+ Is_Path_Expression : Boolean;
+ pragma Unmodified (Is_Path_Expression);
+ -- Local variable to mask the name of function Is_Path_Expression, to
+ -- prevent direct call. Instead IPE wrapper should be called.
+
+ -- Start of processing for Is_Path_Expression
+
begin
case Nkind (Expr) is
when N_Expanded_Name
@@ -3440,10 +4080,12 @@ package body Sem_SPARK is
when N_Null =>
return True;
- -- Object returned by a allocator or function call corresponds to
- -- a path.
+ -- Object returned by an (extension) aggregate, an allocator, or
+ -- a function call corresponds to a path.
- when N_Allocator
+ when N_Aggregate
+ | N_Allocator
+ | N_Extension_Aggregate
| N_Function_Call
=>
return True;
@@ -3452,7 +4094,47 @@ package body Sem_SPARK is
| N_Type_Conversion
| N_Unchecked_Type_Conversion
=>
- return Is_Path_Expression (Expression (Expr));
+ return IPE (Expression (Expr));
+
+ -- When returning from a traversal function, consider an
+ -- if-expression as a possible path expression.
+
+ when N_If_Expression =>
+ if Is_Traversal then
+ declare
+ Cond : constant Node_Id := First (Expressions (Expr));
+ Then_Part : constant Node_Id := Next (Cond);
+ Else_Part : constant Node_Id := Next (Then_Part);
+ begin
+ return IPE (Then_Part)
+ and then IPE (Else_Part);
+ end;
+ else
+ return False;
+ end if;
+
+ -- When returning from a traversal function, consider
+ -- a case-expression as a possible path expression.
+
+ when N_Case_Expression =>
+ if Is_Traversal then
+ declare
+ Cases : constant List_Id := Alternatives (Expr);
+ Cur_Case : Node_Id := First (Cases);
+
+ begin
+ while Present (Cur_Case) loop
+ if not IPE (Expression (Cur_Case)) then
+ return False;
+ end if;
+ Next (Cur_Case);
+ end loop;
+
+ return True;
+ end;
+ else
+ return False;
+ end if;
when others =>
return False;
@@ -3533,8 +4215,10 @@ package body Sem_SPARK is
when N_Selected_Component =>
if Nkind (Expr_Elt) /= N_Selected_Component
- or else Entity (Selector_Name (Prefix_Elt))
- /= Entity (Selector_Name (Expr_Elt))
+ or else Original_Record_Component
+ (Entity (Selector_Name (Prefix_Elt)))
+ /= Original_Record_Component
+ (Entity (Selector_Name (Expr_Elt)))
then
return False;
end if;
@@ -3573,6 +4257,29 @@ package body Sem_SPARK is
end Is_Prefix_Or_Almost;
---------------------------
+ -- Is_Subpath_Expression --
+ ---------------------------
+
+ function Is_Subpath_Expression
+ (Expr : Node_Id;
+ Is_Traversal : Boolean := False) return Boolean
+ is
+ begin
+ return Is_Path_Expression (Expr, Is_Traversal)
+ or else (Nkind (Expr) = N_Attribute_Reference
+ and then
+ (Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Update
+ or else
+ Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Loop_Entry
+ or else
+ Get_Attribute_Id (Attribute_Name (Expr)) =
+ Attribute_Image))
+ or else Nkind (Expr) = N_Op_Concat;
+ end Is_Subpath_Expression;
+
+ ---------------------------
-- Is_Traversal_Function --
---------------------------
@@ -3591,7 +4298,7 @@ package body Sem_SPARK is
-- and the function's first parameter is of an access type.
- and then Is_Access_Type (Etype (First_Formal (E)));
+ and then Is_Access_Type (Retysp (Etype (First_Formal (E))));
end Is_Traversal_Function;
--------------------------------
@@ -3912,6 +4619,7 @@ package body Sem_SPARK is
(N : Node_Id;
Perm : Perm_Kind;
Found_Perm : Perm_Kind;
+ Expl : Node_Id;
Forbidden_Perm : Boolean := False)
is
procedure Set_Root_Object
@@ -3968,14 +4676,16 @@ package body Sem_SPARK is
begin
Set_Root_Object (N, Root, Is_Deref);
- if Is_Deref then
- Error_Msg_NE
- ("insufficient permission on dereference from &", N, Root);
- else
- Error_Msg_NE ("insufficient permission for &", N, Root);
- end if;
+ if Emit_Messages then
+ if Is_Deref then
+ Error_Msg_NE
+ ("insufficient permission on dereference from &", N, Root);
+ else
+ Error_Msg_NE ("insufficient permission for &", N, Root);
+ end if;
- Perm_Mismatch (N, Perm, Found_Perm, Forbidden_Perm);
+ Perm_Mismatch (N, Perm, Found_Perm, Expl, Forbidden_Perm);
+ end if;
end Perm_Error;
-------------------------------
@@ -3986,13 +4696,16 @@ package body Sem_SPARK is
(E : Entity_Id;
Subp : Entity_Id;
Perm : Perm_Kind;
- Found_Perm : Perm_Kind)
+ Found_Perm : Perm_Kind;
+ Expl : Node_Id)
is
begin
- Error_Msg_Node_2 := Subp;
- Error_Msg_NE ("insufficient permission for & when returning from &",
- Subp, E);
- Perm_Mismatch (Subp, Perm, Found_Perm);
+ if Emit_Messages then
+ Error_Msg_Node_2 := Subp;
+ Error_Msg_NE ("insufficient permission for & when returning from &",
+ Subp, E);
+ Perm_Mismatch (Subp, Perm, Found_Perm, Expl);
+ end if;
end Perm_Error_Subprogram_End;
------------------
@@ -4033,9 +4746,11 @@ package body Sem_SPARK is
Var := Key.K;
Borrowed := Get (Current_Borrowers, Var);
- if Is_Prefix_Or_Almost (Pref => Borrowed, Expr => Expr) then
+ if Is_Prefix_Or_Almost (Pref => Borrowed, Expr => Expr)
+ and then Emit_Messages
+ then
Error_Msg_Sloc := Sloc (Borrowed);
- Error_Msg_N ("expression was borrowed #", Expr);
+ Error_Msg_N ("object was borrowed #", Expr);
end if;
Key := Get_Next_Key (Current_Borrowers);
@@ -4069,9 +4784,11 @@ package body Sem_SPARK is
Var := Key.K;
Observed := Get (Current_Observers, Var);
- if Is_Prefix_Or_Almost (Pref => Observed, Expr => Expr) then
+ if Is_Prefix_Or_Almost (Pref => Observed, Expr => Expr)
+ and then Emit_Messages
+ then
Error_Msg_Sloc := Sloc (Observed);
- Error_Msg_N ("expression was observed #", Expr);
+ Error_Msg_N ("object was observed #", Expr);
end if;
Key := Get_Next_Key (Current_Observers);
@@ -4107,7 +4824,7 @@ package body Sem_SPARK is
if not Inside_Elaboration
and then Get (Current_Perm_Env, Root) = null
then
- Illegal_Global_Usage (Expr);
+ Illegal_Global_Usage (Expr, Root);
end if;
-- During elaboration, only the validity of operations is checked, no
@@ -4134,7 +4851,7 @@ package body Sem_SPARK is
-- Check path is readable
if Perm not in Read_Perm then
- Perm_Error (Expr, Read_Only, Perm);
+ Perm_Error (Expr, Read_Only, Perm, Expl => Get_Expl (Expr));
return;
end if;
@@ -4147,6 +4864,7 @@ package body Sem_SPARK is
if Is_Deep (Expr_Type)
and then not Inside_Procedure_Call
and then Present (Get_Root_Object (Expr))
+ and then Emit_Messages
then
Error_Msg_N ("illegal move during elaboration", Expr);
end if;
@@ -4158,7 +4876,7 @@ package body Sem_SPARK is
if not Is_Deep (Expr_Type) then
if Perm not in Read_Perm then
- Perm_Error (Expr, Read_Only, Perm);
+ Perm_Error (Expr, Read_Only, Perm, Expl => Get_Expl (Expr));
end if;
return;
end if;
@@ -4167,7 +4885,7 @@ package body Sem_SPARK is
-- the source object (if any) shall be Unrestricted.
if Perm /= Read_Write then
- Perm_Error (Expr, Read_Write, Perm);
+ Perm_Error (Expr, Read_Write, Perm, Expl => Get_Expl (Expr));
return;
end if;
@@ -4182,45 +4900,39 @@ package body Sem_SPARK is
-- For assignment, check W permission
if Perm not in Write_Perm then
- Perm_Error (Expr, Write_Only, Perm);
+ Perm_Error (Expr, Write_Only, Perm, Expl => Get_Expl (Expr));
return;
end if;
when Borrow =>
- -- Forbidden during elaboration
+ -- Forbidden during elaboration, an error is already issued in
+ -- Check_Declaration, just return.
if Inside_Elaboration then
- if not Inside_Procedure_Call then
- Error_Msg_N ("illegal borrow during elaboration", Expr);
- end if;
-
return;
end if;
-- For borrowing, check RW permission
if Perm /= Read_Write then
- Perm_Error (Expr, Read_Write, Perm);
+ Perm_Error (Expr, Read_Write, Perm, Expl => Get_Expl (Expr));
return;
end if;
when Observe =>
- -- Forbidden during elaboration
+ -- Forbidden during elaboration, an error is already issued in
+ -- Check_Declaration, just return.
if Inside_Elaboration then
- if not Inside_Procedure_Call then
- Error_Msg_N ("illegal observe during elaboration", Expr);
- end if;
-
return;
end if;
-- For borrowing, check R permission
if Perm not in Read_Perm then
- Perm_Error (Expr, Read_Only, Perm);
+ Perm_Error (Expr, Read_Only, Perm, Expl => Get_Expl (Expr));
return;
end if;
end case;
@@ -4259,10 +4971,10 @@ package body Sem_SPARK is
if Present (Get_Root_Object (Expr)) then
declare
Tree : constant Perm_Tree_Access :=
- Set_Perm_Prefixes (Expr, Write_Only);
+ Set_Perm_Prefixes (Expr, Write_Only, Expl => Expr);
begin
pragma Assert (Tree /= null);
- Set_Perm_Extensions_Move (Tree, Etype (Expr));
+ Set_Perm_Extensions_Move (Tree, Etype (Expr), Expl => Expr);
end;
end if;
@@ -4283,7 +4995,7 @@ package body Sem_SPARK is
Tree : constant Perm_Tree_Access := Get_Perm_Tree (Expr);
begin
Tree.all.Tree.Permission := Read_Write;
- Set_Perm_Extensions (Tree, Read_Write);
+ Set_Perm_Extensions (Tree, Read_Write, Expl => Expr);
-- Normalize the permission tree
@@ -4390,7 +5102,8 @@ package body Sem_SPARK is
(E => Id,
Subp => Subp,
Perm => Read_Write,
- Found_Perm => Permission (Tree));
+ Found_Perm => Permission (Tree),
+ Expl => Explanation (Tree));
end if;
end;
end Return_Parameter_Or_Global;
@@ -4406,7 +5119,7 @@ package body Sem_SPARK is
while Present (Formal) loop
Return_Parameter_Or_Global
(Id => Formal,
- Typ => Underlying_Type (Etype (Formal)),
+ Typ => Retysp (Etype (Formal)),
Kind => Ekind (Formal),
Subp => Subp,
Global_Var => False);
@@ -4418,7 +5131,10 @@ package body Sem_SPARK is
-- Set_Perm_Extensions --
-------------------------
- procedure Set_Perm_Extensions (T : Perm_Tree_Access; P : Perm_Kind) is
+ procedure Set_Perm_Extensions
+ (T : Perm_Tree_Access;
+ P : Perm_Kind;
+ Expl : Node_Id) is
procedure Free_Perm_Tree_Children (T : Perm_Tree_Access);
-- Free the permission tree of children if any, prio to replacing T
@@ -4462,6 +5178,7 @@ package body Sem_SPARK is
Free_Perm_Tree_Children (T);
T.all.Tree := Perm_Tree'(Kind => Entire_Object,
Is_Node_Deep => Is_Node_Deep (T),
+ Explanation => Expl,
Permission => Permission (T),
Children_Permission => P);
end Set_Perm_Extensions;
@@ -4471,14 +5188,16 @@ package body Sem_SPARK is
------------------------------
procedure Set_Perm_Extensions_Move
- (T : Perm_Tree_Access;
- E : Entity_Id)
+ (T : Perm_Tree_Access;
+ E : Entity_Id;
+ Expl : Node_Id)
is
+ Check_Ty : constant Entity_Id := Retysp (E);
begin
-- Shallow extensions are set to RW
if not Is_Node_Deep (T) then
- Set_Perm_Extensions (T, Read_Write);
+ Set_Perm_Extensions (T, Read_Write, Expl => Expl);
return;
end if;
@@ -4492,7 +5211,7 @@ package body Sem_SPARK is
-- precision.
when Entire_Object =>
- case Ekind (E) is
+ case Ekind (Check_Ty) is
when E_Array_Type
| E_Array_Subtype
=>
@@ -4502,12 +5221,15 @@ package body Sem_SPARK is
(Tree =>
(Kind => Entire_Object,
Is_Node_Deep => Is_Node_Deep (T),
+ Explanation => Expl,
Permission => Read_Write,
Children_Permission => Read_Write));
begin
- Set_Perm_Extensions_Move (C, Component_Type (E));
+ Set_Perm_Extensions_Move
+ (C, Component_Type (Check_Ty), Expl);
T.all.Tree := (Kind => Array_Component,
Is_Node_Deep => Is_Node_Deep (T),
+ Explanation => Expl,
Permission => Write_Only,
Get_Elem => C);
end;
@@ -4519,22 +5241,43 @@ package body Sem_SPARK is
Hashtbl : Perm_Tree_Maps.Instance;
begin
- Comp := First_Component_Or_Discriminant (E);
+ Comp := First_Component_Or_Discriminant (Check_Ty);
while Present (Comp) loop
- C := new Perm_Tree_Wrapper'
- (Tree =>
- (Kind => Entire_Object,
- Is_Node_Deep => Is_Deep (Etype (Comp)),
- Permission => Read_Write,
- Children_Permission => Read_Write));
- Set_Perm_Extensions_Move (C, Etype (Comp));
- Perm_Tree_Maps.Set (Hashtbl, Comp, C);
+
+ -- Unfold components which are visible in SPARK
+
+ if Component_Is_Visible_In_SPARK (Comp) then
+ C := new Perm_Tree_Wrapper'
+ (Tree =>
+ (Kind => Entire_Object,
+ Is_Node_Deep => Is_Deep (Etype (Comp)),
+ Explanation => Expl,
+ Permission => Read_Write,
+ Children_Permission => Read_Write));
+ Set_Perm_Extensions_Move (C, Etype (Comp), Expl);
+
+ -- Hidden components are never deep
+
+ else
+ C := new Perm_Tree_Wrapper'
+ (Tree =>
+ (Kind => Entire_Object,
+ Is_Node_Deep => False,
+ Explanation => Expl,
+ Permission => Read_Write,
+ Children_Permission => Read_Write));
+ Set_Perm_Extensions (C, Read_Write, Expl => Expl);
+ end if;
+
+ Perm_Tree_Maps.Set
+ (Hashtbl, Original_Record_Component (Comp), C);
Next_Component_Or_Discriminant (Comp);
end loop;
T.all.Tree :=
(Kind => Record_Component,
Is_Node_Deep => Is_Node_Deep (T),
+ Explanation => Expl,
Permission => Write_Only,
Component => Hashtbl);
end;
@@ -4542,14 +5285,15 @@ package body Sem_SPARK is
-- Otherwise, extensions are set to NO
when others =>
- Set_Perm_Extensions (T, No_Access);
+ Set_Perm_Extensions (T, No_Access, Expl);
end case;
when Reference =>
- Set_Perm_Extensions (T, No_Access);
+ Set_Perm_Extensions (T, No_Access, Expl);
when Array_Component =>
- Set_Perm_Extensions_Move (Get_Elem (T), Component_Type (E));
+ Set_Perm_Extensions_Move
+ (Get_Elem (T), Component_Type (Check_Ty), Expl);
when Record_Component =>
declare
@@ -4557,11 +5301,23 @@ package body Sem_SPARK is
Comp : Entity_Id;
begin
- Comp := First_Component_Or_Discriminant (E);
+ Comp := First_Component_Or_Discriminant (Check_Ty);
while Present (Comp) loop
- C := Perm_Tree_Maps.Get (Component (T), Comp);
+ C := Perm_Tree_Maps.Get
+ (Component (T), Original_Record_Component (Comp));
pragma Assert (C /= null);
- Set_Perm_Extensions_Move (C, Etype (Comp));
+
+ -- Move visible components
+
+ if Component_Is_Visible_In_SPARK (Comp) then
+ Set_Perm_Extensions_Move (C, Etype (Comp), Expl);
+
+ -- Hidden components are never deep
+
+ else
+ Set_Perm_Extensions (C, Read_Write, Expl => Expl);
+ end if;
+
Next_Component_Or_Discriminant (Comp);
end loop;
end;
@@ -4574,7 +5330,8 @@ package body Sem_SPARK is
function Set_Perm_Prefixes
(N : Node_Id;
- Perm : Perm_Kind_Option) return Perm_Tree_Access
+ Perm : Perm_Kind_Option;
+ Expl : Node_Id) return Perm_Tree_Access
is
begin
case Nkind (N) is
@@ -4594,7 +5351,7 @@ package body Sem_SPARK is
return C;
end;
- -- For a non-terminal path, we set the permission tree of its prefix,
+ -- For a nonterminal path, we set the permission tree of its prefix,
-- and then we extract from the returned pointer the subtree and
-- assign an adequate permission to it, if unfolded. If folded,
-- we unroll the tree one level.
@@ -4602,7 +5359,7 @@ package body Sem_SPARK is
when N_Explicit_Dereference =>
declare
C : constant Perm_Tree_Access :=
- Set_Perm_Prefixes (Prefix (N), Perm);
+ Set_Perm_Prefixes (Prefix (N), Perm, Expl);
pragma Assert (C /= null);
pragma Assert (Kind (C) = Entire_Object
or else Kind (C) = Reference);
@@ -4635,6 +5392,7 @@ package body Sem_SPARK is
(Tree =>
(Kind => Entire_Object,
Is_Node_Deep => Is_Deep (Etype (N)),
+ Explanation => Expl,
Permission => Child_P,
Children_Permission => Child_P));
begin
@@ -4644,6 +5402,7 @@ package body Sem_SPARK is
C.all.Tree := (Kind => Reference,
Is_Node_Deep => Is_Node_Deep (C),
+ Explanation => Expl,
Permission => Permission (C),
Get_All => D);
return D;
@@ -4654,7 +5413,7 @@ package body Sem_SPARK is
when N_Selected_Component =>
declare
C : constant Perm_Tree_Access :=
- Set_Perm_Prefixes (Prefix (N), Perm);
+ Set_Perm_Prefixes (Prefix (N), Perm, Expl);
pragma Assert (C /= null);
pragma Assert (Kind (C) = Entire_Object
or else Kind (C) = Record_Component);
@@ -4664,7 +5423,9 @@ package body Sem_SPARK is
if Kind (C) = Record_Component then
declare
- Comp : constant Entity_Id := Entity (Selector_Name (N));
+ Comp : constant Entity_Id :=
+ Original_Record_Component
+ (Entity (Selector_Name (N)));
D : constant Perm_Tree_Access :=
Perm_Tree_Maps.Get (Component (C), Comp);
pragma Assert (D /= null);
@@ -4693,11 +5454,14 @@ package body Sem_SPARK is
begin
Comp :=
- First_Component_Or_Discriminant (Etype (Prefix (N)));
+ First_Component_Or_Discriminant
+ (Retysp (Etype (Prefix (N))));
while Present (Comp) loop
if Perm /= None
- and then Comp = Entity (Selector_Name (N))
+ and then Original_Record_Component (Comp) =
+ Original_Record_Component
+ (Entity (Selector_Name (N)))
then
P := Perm;
else
@@ -4707,14 +5471,22 @@ package body Sem_SPARK is
D := new Perm_Tree_Wrapper'
(Tree =>
(Kind => Entire_Object,
- Is_Node_Deep => Is_Deep (Etype (Comp)),
+ Is_Node_Deep =>
+ -- Hidden components are never deep
+ Component_Is_Visible_In_SPARK (Comp)
+ and then Is_Deep (Etype (Comp)),
+ Explanation => Expl,
Permission => P,
Children_Permission => Child_P));
- Perm_Tree_Maps.Set (Hashtbl, Comp, D);
+ Perm_Tree_Maps.Set
+ (Hashtbl, Original_Record_Component (Comp), D);
-- Store the tree to return for this component
- if Comp = Entity (Selector_Name (N)) then
+ if Original_Record_Component (Comp) =
+ Original_Record_Component
+ (Entity (Selector_Name (N)))
+ then
D_This := D;
end if;
@@ -4723,6 +5495,7 @@ package body Sem_SPARK is
C.all.Tree := (Kind => Record_Component,
Is_Node_Deep => Is_Node_Deep (C),
+ Explanation => Expl,
Permission => Permission (C),
Component => Hashtbl);
return D_This;
@@ -4735,7 +5508,7 @@ package body Sem_SPARK is
=>
declare
C : constant Perm_Tree_Access :=
- Set_Perm_Prefixes (Prefix (N), Perm);
+ Set_Perm_Prefixes (Prefix (N), Perm, Expl);
pragma Assert (C /= null);
pragma Assert (Kind (C) = Entire_Object
or else Kind (C) = Array_Component);
@@ -4768,6 +5541,7 @@ package body Sem_SPARK is
(Tree =>
(Kind => Entire_Object,
Is_Node_Deep => Is_Node_Deep (C),
+ Explanation => Expl,
Permission => Child_P,
Children_Permission => Child_P));
begin
@@ -4777,6 +5551,7 @@ package body Sem_SPARK is
C.all.Tree := (Kind => Array_Component,
Is_Node_Deep => Is_Node_Deep (C),
+ Explanation => Expl,
Permission => Permission (C),
Get_Elem => D);
return D;
@@ -4788,7 +5563,7 @@ package body Sem_SPARK is
| N_Type_Conversion
| N_Unchecked_Type_Conversion
=>
- return Set_Perm_Prefixes (Expression (N), Perm);
+ return Set_Perm_Prefixes (Expression (N), Perm, Expl);
when others =>
raise Program_Error;
@@ -4893,7 +5668,8 @@ package body Sem_SPARK is
Typ => Typ,
Kind => Kind,
Subp => Subp,
- Global_Var => Global_Var);
+ Global_Var => Global_Var,
+ Expl => Expr);
end Setup_Global;
procedure Setup_Globals_Inst is new Handle_Globals (Setup_Global);
@@ -4913,7 +5689,8 @@ package body Sem_SPARK is
Typ : Entity_Id;
Kind : Formal_Kind;
Subp : Entity_Id;
- Global_Var : Boolean)
+ Global_Var : Boolean;
+ Expl : Node_Id)
is
Perm : Perm_Kind_Option;
@@ -4965,14 +5742,6 @@ package body Sem_SPARK is
-- Functions cannot have outputs in SPARK
elsif Ekind (Subp) = E_Function then
- if Kind = E_Out_Parameter then
- Error_Msg_N ("function with OUT parameter is not "
- & "allowed in SPARK", Id);
- else
- Error_Msg_N ("function with `IN OUT` parameter is not "
- & "allowed in SPARK", Id);
- end if;
-
return;
-- Deep types define a borrow or a move
@@ -4989,6 +5758,7 @@ package body Sem_SPARK is
(Tree =>
(Kind => Entire_Object,
Is_Node_Deep => Is_Deep (Etype (Id)),
+ Explanation => Expl,
Permission => Perm,
Children_Permission => Perm));
begin
@@ -5008,12 +5778,47 @@ package body Sem_SPARK is
while Present (Formal) loop
Setup_Parameter_Or_Global
(Id => Formal,
- Typ => Underlying_Type (Etype (Formal)),
+ Typ => Retysp (Etype (Formal)),
Kind => Ekind (Formal),
Subp => Subp,
- Global_Var => False);
+ Global_Var => False,
+ Expl => Formal);
Next_Formal (Formal);
end loop;
end Setup_Parameters;
+ --------------------------------
+ -- Setup_Protected_Components --
+ --------------------------------
+
+ procedure Setup_Protected_Components (Subp : Entity_Id) is
+ Typ : constant Entity_Id := Scope (Subp);
+ Comp : Entity_Id;
+ Kind : Formal_Kind;
+
+ begin
+ Comp := First_Component_Or_Discriminant (Typ);
+
+ -- The protected object is an implicit input of protected functions, and
+ -- an implicit input-output of protected procedures and entries.
+
+ if Ekind (Subp) = E_Function then
+ Kind := E_In_Parameter;
+ else
+ Kind := E_In_Out_Parameter;
+ end if;
+
+ while Present (Comp) loop
+ Setup_Parameter_Or_Global
+ (Id => Comp,
+ Typ => Retysp (Etype (Comp)),
+ Kind => Kind,
+ Subp => Subp,
+ Global_Var => False,
+ Expl => Comp);
+
+ Next_Component_Or_Discriminant (Comp);
+ end loop;
+ end Setup_Protected_Components;
+
end Sem_SPARK;
diff --git a/gcc/ada/sem_spark.ads b/gcc/ada/sem_spark.ads
index ee4126a..195e833 100644
--- a/gcc/ada/sem_spark.ads
+++ b/gcc/ada/sem_spark.ads
@@ -132,12 +132,38 @@
-- get read-write permission, which can be specified using the node's
-- Children_Permission field.
+-- The implementation is done as a generic, so that GNATprove can instantiate
+-- it with suitable formal arguments that depend on the SPARK_Mode boundary
+-- as well as the two-phase architecture of GNATprove (which runs the GNAT
+-- front end twice, once for global generation and once for analysis).
+
with Types; use Types;
+generic
+ with function Retysp (X : Entity_Id) return Entity_Id;
+ -- Return the representative type in SPARK for a type.
+
+ with function Component_Is_Visible_In_SPARK (C : Entity_Id) return Boolean;
+ -- Return whether a component is visible in SPARK. No aliasing check is
+ -- performed for a component that is visible.
+
+ with function Emit_Messages return Boolean;
+ -- Return True when error messages should be emitted.
+
package Sem_SPARK is
procedure Check_Safe_Pointers (N : Node_Id);
-- The entry point of this package. It analyzes a node and reports errors
-- when there are violations of ownership rules.
+ function Is_Deep (Typ : Entity_Id) return Boolean;
+ -- A function that can tell whether a type is deep. Returns True if the
+ -- type passed as argument is deep.
+
+ function Is_Traversal_Function (E : Entity_Id) return Boolean;
+
+ function Is_Local_Context (Scop : Entity_Id) return Boolean;
+ -- Return if a given scope defines a local context where it is legal to
+ -- declare a variable of anonymous access type.
+
end Sem_SPARK;
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 77eefdc..f18eb0f 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -6452,8 +6452,8 @@ package body Sem_Util is
-- Dynamic_Accessibility_Level --
---------------------------------
- function Dynamic_Accessibility_Level (Expr : Node_Id) return Node_Id is
- Loc : constant Source_Ptr := Sloc (Expr);
+ function Dynamic_Accessibility_Level (N : Node_Id) return Node_Id is
+ Loc : constant Source_Ptr := Sloc (N);
function Make_Level_Literal (Level : Uint) return Node_Id;
-- Construct an integer literal representing an accessibility level
@@ -6473,7 +6473,12 @@ package body Sem_Util is
-- Local variables
- E : Entity_Id;
+ Expr : constant Node_Id := Original_Node (N);
+ -- Expr references the original node because at this stage N may be the
+ -- reference to a variable internally created by the frontend to remove
+ -- side effects of an expression.
+
+ E : Entity_Id;
-- Start of processing for Dynamic_Accessibility_Level
@@ -6530,12 +6535,69 @@ package body Sem_Util is
when N_Allocator =>
- -- Unimplemented: depends on context. As an actual parameter where
- -- formal type is anonymous, use
- -- Scope_Depth (Current_Scope) + 1.
- -- For other cases, see 3.10.2(14/3) and following. ???
+ -- This is not fully implemented since it depends on context (see
+ -- 3.10.2(14/3-14.2/3). More work is needed in the following cases
+ --
+ -- 1) For an anonymous allocator defining the value of an access
+ -- parameter, the accessibility level is that of the innermost
+ -- master of the call; however currently we pass the level of
+ -- execution of the called subprogram, which is one greater
+ -- than the current scope level (see Expand_Call_Helper).
+ --
+ -- For example, a statement is a master and a declaration is
+ -- not a master; so we should not pass in the same level for
+ -- the following cases:
+ --
+ -- function F (X : access Integer) return T is ... ;
+ -- Decl : T := F (new Integer); -- level is off by one
+ -- begin
+ -- Decl := F (new Integer); -- we get this case right
+ --
+ -- 2) For an anonymous allocator that defines the result of a
+ -- function with an access result, the accessibility level is
+ -- determined as though the allocator were in place of the call
+ -- of the function. In the special case of a call that is the
+ -- operand of a type conversion the level is that of the target
+ -- access type of the conversion.
+ --
+ -- 3) For an anonymous allocator defining an access discriminant
+ -- the accessibility level is determined as follows:
+ -- * for an allocator used to define the discriminant of an
+ -- object, the level of the object
+ -- * for an allocator used to define the constraint in a
+ -- subtype_indication in any other context, the level of
+ -- the master that elaborates the subtype_indication.
+
+ case Nkind (Parent (N)) is
+ when N_Object_Declaration =>
+
+ -- For an anonymous allocator whose type is that of a
+ -- stand-alone object of an anonymous access-to-object type,
+ -- the accessibility level is that of the declaration of the
+ -- stand-alone object.
+
+ return
+ Make_Level_Literal
+ (Object_Access_Level
+ (Defining_Identifier (Parent (N))));
- null;
+ when N_Assignment_Statement =>
+ return
+ Make_Level_Literal
+ (Object_Access_Level (Name (Parent (N))));
+
+ when others =>
+ declare
+ S : constant String :=
+ Node_Kind'Image (Nkind (Parent (N)));
+ begin
+ Error_Msg_Strlen := S'Length;
+ Error_Msg_String (1 .. Error_Msg_Strlen) := S;
+ Error_Msg_N
+ ("unsupported context for anonymous allocator (~)",
+ Parent (N));
+ end;
+ end case;
when N_Type_Conversion =>
if not Is_Local_Anonymous_Access (Etype (Expr)) then
@@ -6840,8 +6902,9 @@ package body Sem_Util is
elsif Dynamic_Scope = Empty then
return Empty;
- elsif Ekind_In (Dynamic_Scope, E_Package, E_Package_Body,
- E_Generic_Package)
+ elsif Ekind_In (Dynamic_Scope, E_Generic_Package,
+ E_Package,
+ E_Package_Body)
then
return Dynamic_Scope;
@@ -6861,12 +6924,7 @@ package body Sem_Util is
S := Scope (E);
while Present (S) loop
if Is_Package_Or_Generic_Package (S)
- or else Ekind (S) = E_Package_Body
- then
- return S;
-
- elsif Is_Subprogram_Or_Generic_Subprogram (S)
- or else Ekind (S) = E_Subprogram_Body
+ or else Is_Subprogram_Or_Generic_Subprogram (S)
then
return S;
@@ -6895,7 +6953,7 @@ package body Sem_Util is
elsif Ekind (Dyn_Scop) = E_Subprogram_Body then
return Corresponding_Spec (Parent (Parent (Dyn_Scop)));
- elsif Ekind_In (Dyn_Scop, E_Block, E_Return_Statement) then
+ elsif Ekind_In (Dyn_Scop, E_Block, E_Loop, E_Return_Statement) then
return Enclosing_Subprogram (Dyn_Scop);
elsif Ekind (Dyn_Scop) = E_Entry then
@@ -8645,6 +8703,8 @@ package body Sem_Util is
Global : Node_Id := Empty;
Body_Id : Entity_Id;
+ -- Start of processing for First_Global
+
begin
pragma Assert (Nam_In (Global_Mode, Name_In_Out,
Name_Input,
@@ -8655,7 +8715,22 @@ package body Sem_Util is
-- case, it can only be located on the body entity.
if Refined then
- Body_Id := Subprogram_Body_Entity (Subp);
+ if Is_Subprogram_Or_Generic_Subprogram (Subp) then
+ Body_Id := Subprogram_Body_Entity (Subp);
+
+ elsif Is_Entry (Subp) or else Is_Task_Type (Subp) then
+ Body_Id := Corresponding_Body (Parent (Subp));
+
+ -- ??? It should be possible to retrieve the Refined_Global on the
+ -- task body associated to the task object. This is not yet possible.
+
+ elsif Is_Single_Task_Object (Subp) then
+ Body_Id := Empty;
+
+ else
+ Body_Id := Empty;
+ end if;
+
if Present (Body_Id) then
Global := Get_Pragma (Body_Id, Pragma_Refined_Global);
end if;
@@ -8939,6 +9014,12 @@ package body Sem_Util is
begin
Find_Discrete_Value : while Present (Variant) loop
+
+ -- If a choice is a subtype with a static predicate, it must
+ -- be rewritten as an explicit list of non-predicated choices.
+
+ Expand_Static_Predicates_In_Choices (Variant);
+
Discrete_Choice := First (Discrete_Choices (Variant));
while Present (Discrete_Choice) loop
exit Find_Discrete_Value when
@@ -10734,8 +10815,8 @@ package body Sem_Util is
-- Simple option Synchronous
--
-- enables disables
- -- Asynch_Readers Effective_Reads
- -- Asynch_Writers Effective_Writes
+ -- Async_Readers Effective_Reads
+ -- Async_Writers Effective_Writes
--
-- Note that both forms of External have higher precedence than
-- Synchronous (SPARK RM 7.1.4(9)).
@@ -12305,6 +12386,25 @@ package body Sem_Util is
end if;
end In_Pre_Post_Condition;
+ ------------------------------
+ -- In_Quantified_Expression --
+ ------------------------------
+
+ function In_Quantified_Expression (N : Node_Id) return Boolean is
+ P : Node_Id;
+ begin
+ P := Parent (N);
+ loop
+ if No (P) then
+ return False;
+ elsif Nkind (P) = N_Quantified_Expression then
+ return True;
+ else
+ P := Parent (P);
+ end if;
+ end loop;
+ end In_Quantified_Expression;
+
-------------------------------------
-- In_Reverse_Storage_Order_Object --
-------------------------------------
@@ -19320,6 +19420,94 @@ package body Sem_Util is
return Empty;
end Nearest_Enclosing_Instance;
+ ------------------------
+ -- Needs_Finalization --
+ ------------------------
+
+ function Needs_Finalization (Typ : Entity_Id) return Boolean is
+ function Has_Some_Controlled_Component
+ (Input_Typ : Entity_Id) return Boolean;
+ -- Determine whether type Input_Typ has at least one controlled
+ -- component.
+
+ -----------------------------------
+ -- Has_Some_Controlled_Component --
+ -----------------------------------
+
+ function Has_Some_Controlled_Component
+ (Input_Typ : Entity_Id) return Boolean
+ is
+ Comp : Entity_Id;
+
+ begin
+ -- When a type is already frozen and has at least one controlled
+ -- component, or is manually decorated, it is sufficient to inspect
+ -- flag Has_Controlled_Component.
+
+ if Has_Controlled_Component (Input_Typ) then
+ return True;
+
+ -- Otherwise inspect the internals of the type
+
+ elsif not Is_Frozen (Input_Typ) then
+ if Is_Array_Type (Input_Typ) then
+ return Needs_Finalization (Component_Type (Input_Typ));
+
+ elsif Is_Record_Type (Input_Typ) then
+ Comp := First_Component (Input_Typ);
+ while Present (Comp) loop
+ if Needs_Finalization (Etype (Comp)) then
+ return True;
+ end if;
+
+ Next_Component (Comp);
+ end loop;
+ end if;
+ end if;
+
+ return False;
+ end Has_Some_Controlled_Component;
+
+ -- Start of processing for Needs_Finalization
+
+ begin
+ -- Certain run-time configurations and targets do not provide support
+ -- for controlled types.
+
+ if Restriction_Active (No_Finalization) then
+ return False;
+
+ -- C++ types are not considered controlled. It is assumed that the non-
+ -- Ada side will handle their clean up.
+
+ elsif Convention (Typ) = Convention_CPP then
+ return False;
+
+ -- Class-wide types are treated as controlled because derivations from
+ -- the root type may introduce controlled components.
+
+ elsif Is_Class_Wide_Type (Typ) then
+ return True;
+
+ -- Concurrent types are controlled as long as their corresponding record
+ -- is controlled.
+
+ elsif Is_Concurrent_Type (Typ)
+ and then Present (Corresponding_Record_Type (Typ))
+ and then Needs_Finalization (Corresponding_Record_Type (Typ))
+ then
+ return True;
+
+ -- Otherwise the type is controlled when it is either derived from type
+ -- [Limited_]Controlled and not subject to aspect Disable_Controlled, or
+ -- contains at least one controlled component.
+
+ else
+ return
+ Is_Controlled (Typ) or else Has_Some_Controlled_Component (Typ);
+ end if;
+ end Needs_Finalization;
+
----------------------
-- Needs_One_Actual --
----------------------
@@ -22181,9 +22369,15 @@ package body Sem_Util is
-- Start of processing for Null_Status
begin
+ -- Prevent cascaded errors or infinite loops when trying to determine
+ -- the null status of an erroneous construct.
+
+ if Error_Posted (N) then
+ return Unknown;
+
-- An allocator always creates a non-null value
- if Nkind (N) = N_Allocator then
+ elsif Nkind (N) = N_Allocator then
return Is_Non_Null;
-- Taking the 'Access of something yields a non-null value
@@ -23327,6 +23521,13 @@ package body Sem_Util is
if From_Typ = Typ then
return;
+
+ -- Nothing to do when the destination denotes an incomplete type
+ -- because the DIC is associated with the current instance of a
+ -- private type, thus it can never apply to an incomplete type.
+
+ elsif Is_Incomplete_Type (Typ) then
+ return;
end if;
DIC_Proc := DIC_Procedure (From_Typ);
@@ -24178,13 +24379,33 @@ package body Sem_Util is
(Inner : Entity_Id;
Outer : Entity_Id) return Boolean
is
- Curr : Entity_Id;
+ Curr : Entity_Id := Inner;
begin
- Curr := Inner;
+ -- Similar to the above, but check for scope identity first
+
while Present (Curr) and then Curr /= Standard_Standard loop
if Curr = Outer then
return True;
+
+ elsif Ekind (Curr) = E_Task_Type
+ and then Outer = Task_Body_Procedure (Curr)
+ then
+ return True;
+
+ elsif Is_Subprogram (Curr)
+ and then Outer = Protected_Body_Subprogram (Curr)
+ then
+ return True;
+
+ elsif Is_Private_Type (Curr)
+ and then Present (Full_View (Curr))
+ then
+ if Full_View (Curr) = Outer then
+ return True;
+ else
+ return Scope_Within (Full_View (Curr), Outer);
+ end if;
end if;
Curr := Scope (Curr);
@@ -25656,6 +25877,8 @@ package body Sem_Util is
end if;
end;
+ elsif Is_Child_Unit (U) then
+ return Child_Prefix & Unique_Name (S) & "__" & This_Name;
else
return Unique_Name (S) & "__" & This_Name;
end if;
@@ -26407,12 +26630,12 @@ package body Sem_Util is
-- A record type or type extension yields a synchronized object when its
-- discriminants (if any) lack default values and all components are of
- -- a type that yelds a synchronized object.
+ -- a type that yields a synchronized object.
elsif Is_Record_Type (Typ) then
-- Inspect all entities defined in the scope of the type, looking for
- -- components of a type that does not yeld a synchronized object or
+ -- components of a type that does not yield a synchronized object or
-- for discriminants with default values.
Id := First_Entity (Typ);
@@ -26442,6 +26665,7 @@ package body Sem_Util is
-- synchronized object.
if Etype (Typ) /= Typ
+ and then not Is_Private_Type (Etype (Typ))
and then not Yields_Synchronized_Object (Etype (Typ))
then
return False;
@@ -26457,11 +26681,19 @@ package body Sem_Util is
elsif Is_Synchronized_Interface (Typ) then
return True;
- -- A task type yelds a synchronized object by default
+ -- A task type yields a synchronized object by default
elsif Is_Task_Type (Typ) then
return True;
+ -- A private type yields a synchronized object if its underlying type
+ -- does.
+
+ elsif Is_Private_Type (Typ)
+ and then Present (Underlying_Type (Typ))
+ then
+ return Yields_Synchronized_Object (Underlying_Type (Typ));
+
-- Otherwise the type does not yield a synchronized object
else
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 3f8d2e7..35ef111 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -622,11 +622,11 @@ package Sem_Util is
-- private components of protected objects, but is generally useful when
-- restriction No_Implicit_Heap_Allocation is active.
- function Dynamic_Accessibility_Level (Expr : Node_Id) return Node_Id;
- -- Expr should be an expression of an access type. Builds an integer
- -- literal except in cases involving anonymous access types, where
- -- accessibility levels are tracked at run time (access parameters and
- -- Ada 2012 stand-alone objects).
+ function Dynamic_Accessibility_Level (N : Node_Id) return Node_Id;
+ -- N should be an expression of an access type. Builds an integer literal
+ -- except in cases involving anonymous access types, where accessibility
+ -- levels are tracked at run time (access parameters and Ada 2012 stand-
+ -- alone objects).
function Effective_Extra_Accessibility (Id : Entity_Id) return Entity_Id;
-- Same as Einfo.Extra_Accessibility except thtat object renames
@@ -1410,6 +1410,9 @@ package Sem_Util is
-- Returns True if node N appears within a pre/postcondition pragma. Note
-- the pragma Check equivalents are NOT considered.
+ function In_Quantified_Expression (N : Node_Id) return Boolean;
+ -- Returns true if the expression N occurs within a quantified expression
+
function In_Reverse_Storage_Order_Object (N : Node_Id) return Boolean;
-- Returns True if N denotes a component or subcomponent in a record or
-- array that has Reverse_Storage_Order.
@@ -2217,6 +2220,10 @@ package Sem_Util is
-- Return the entity of the nearest enclosing instance which encapsulates
-- entity E. If no such instance exits, return Empty.
+ function Needs_Finalization (Typ : Entity_Id) return Boolean;
+ -- Determine whether type Typ is controlled and this requires finalization
+ -- actions.
+
function Needs_One_Actual (E : Entity_Id) return Boolean;
-- Returns True if a function has defaults for all but its first formal,
-- which is a controlling formal. Used in Ada 2005 mode to solve the
@@ -2851,6 +2858,10 @@ package Sem_Util is
-- Return a unique name for entity E, which could be used to identify E
-- across compilation units.
+ Child_Prefix : constant String := "ada___";
+ -- Prefix for child packages when building a unique name for an entity. It
+ -- is included here to share between Unique_Name and gnatprove.
+
function Unit_Is_Visible (U : Entity_Id) return Boolean;
-- Determine whether a compilation unit is visible in the current context,
-- because there is a with_clause that makes the unit available. Used to
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index 7e13aa5..ab85162 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -333,6 +333,11 @@ package body Sem_Warn is
elsif Has_Warnings_Off (Entity (Name (N))) then
return;
+
+ -- Forget it if the parameter is not In
+
+ elsif Has_Out_Or_In_Out_Parameter (Entity (Name (N))) then
+ return;
end if;
-- OK, see if we have one argument
@@ -1408,9 +1413,13 @@ package body Sem_Warn is
goto Continue;
end if;
- -- Check for unset reference
+ -- Check for unset reference. If type of object has
+ -- preelaborable initialization, warning is misleading.
- if Warn_On_No_Value_Assigned and then Present (UR) then
+ if Warn_On_No_Value_Assigned
+ and then Present (UR)
+ and then not Known_To_Have_Preelab_Init (Etype (E1))
+ then
-- For other than access type, go back to original node to
-- deal with case where original unset reference has been
@@ -2698,7 +2707,7 @@ package body Sem_Warn is
-- Flag any unused with clauses. For a subunit, check only the units
-- in its context, not those of the parent, which may be needed by other
- -- subunits. We will get the full warnings when we compile the parent,
+ -- subunits. We will get the full warnings when we compile the parent,
-- but the following is helpful when compiling a subunit by itself.
if Nkind (Unit (Cunit (Main_Unit))) = N_Subunit then
diff --git a/gcc/ada/sfn_scan.adb b/gcc/ada/sfn_scan.adb
index 66e9a82..377ea19 100644
--- a/gcc/ada/sfn_scan.adb
+++ b/gcc/ada/sfn_scan.adb
@@ -607,6 +607,7 @@ package body SFN_Scan is
exception
when others =>
+ pragma Assert (P'Valid);
Cursor := P - S'First + 1;
raise;
end Scan_SFN_Pragmas;
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index b1e57bf..064147e 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -754,11 +754,16 @@ package Sinfo is
-- GNATprove mode. As a special case, the front end does not insert a
-- Do_Division_Check flag on float exponentiation expressions, for the case
-- where the value is 0.0 and the exponent is negative, although this case
- -- does lead to a division check failure.
+ -- does lead to a division check failure. As another special case,
+ -- the front end does not insert a Do_Range_Check on an allocator where
+ -- the designated type is scalar, and the designated type is more
+ -- constrained than the type of the initialized allocator value or the type
+ -- of the default value for an uninitialized allocator.
- -- Note: the expander always takes care of the Do_Range check case,
- -- so this flag will never be set in the expanded tree passed to the
- -- back end code generator.
+ -- Note that the expander always takes care of the Do_Range_Check case, so
+ -- this flag will never be set in the expanded tree passed to the back end.
+ -- For the other two flags, the check can be generated either by the back
+ -- end or by the front end, depending on the setting of a target parameter.
-- Note that this accounts for all nodes that trigger the corresponding
-- checks, except for range checks on subtype_indications, which may be
@@ -1182,9 +1187,10 @@ package Sinfo is
-- conversion nodes (and set if the conversion requires a check).
-- Do_Division_Check (Flag13-Sem)
- -- This flag is set on a division operator (/ mod rem) to indicate
- -- that a zero divide check is required. The actual check is dealt
- -- with by the backend (all the front end does is to set the flag).
+ -- This flag is set on a division operator (/ mod rem) to indicate that
+ -- a zero divide check is required. The actual check is either dealt with
+ -- by the back end if Backend_Divide_Checks is set to true, or by the
+ -- front end itself if it is set to false.
-- Do_Length_Check (Flag4-Sem)
-- This flag is set in an N_Assignment_Statement, N_Op_And, N_Op_Or,
@@ -1193,15 +1199,13 @@ package Sinfo is
-- Do_Overflow_Check (Flag17-Sem)
-- This flag is set on an operator where an overflow check is required on
- -- the operation. The actual check is dealt with by the backend (all the
- -- front end does is to set the flag). The other cases where this flag is
- -- used is on a Type_Conversion node and for attribute reference nodes.
+ -- the operation. The actual check is either dealt with by the back end
+ -- if Backend_Overflow_Checks is set to true, or by the front end itself
+ -- if it is set to false. The other cases where this flag is used is on a
+ -- Type_Conversion node as well on if and case expression nodes.
-- For a type conversion, it means that the conversion is from one base
-- type to another, and the value may not fit in the target base type.
- -- See also the description of Do_Range_Check for this case. The only
- -- attribute references which use this flag are Pred and Succ, where it
- -- means that the result should be checked for going outside the base
- -- range. Note that this flag is not set for modular types. This flag is
+ -- See also the description of Do_Range_Check for this case. This flag is
-- also set on if and case expression nodes if we are operating in either
-- MINIMIZED or ELIMINATED overflow checking mode (to make sure that we
-- properly process overflow checking for dependent expressions).
@@ -1211,9 +1215,9 @@ package Sinfo is
-- range check is required. The target type is clear from the context.
-- The contexts in which this flag can appear are the following:
- -- Right side of an assignment. In this case the target type is
- -- taken from the left side of the assignment, which is referenced
- -- by the Name of the N_Assignment_Statement node.
+ -- Right side of an assignment. In this case the target type is taken
+ -- from the left side of the assignment, which is referenced by the
+ -- Name of the N_Assignment_Statement node.
-- Subscript expressions in an indexed component. In this case the
-- target type is determined from the type of the array, which is
@@ -1247,15 +1251,6 @@ package Sinfo is
-- listed above (e.g. in a return statement), an additional type
-- conversion node is introduced to represent the required check.
- -- A special case arises for the arguments of the Pred/Succ attributes.
- -- Here the range check needed is against First + 1 .. Last (Pred) or
- -- First .. Last - 1 (Succ) of the corresponding base type. Essentially
- -- these checks are what would be performed within the implicit body of
- -- the functions that correspond to these attributes. In these cases,
- -- the Do_Range check flag is set on the argument to the attribute
- -- function, and the back end must special case the appropriate range
- -- to check against.
-
-- Do_Storage_Check (Flag17-Sem)
-- This flag is set in an N_Allocator node to indicate that a storage
-- check is required for the allocation, or in an N_Subprogram_Body node
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index 21cc0f4..2715310 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -1511,6 +1511,11 @@ package Snames is
Name_Runtime_Library_Dir : constant Name_Id := N + $;
Name_Runtime_Source_Dir : constant Name_Id := N + $;
+ -- Additional names used by the Repinfo unit
+
+ Name_Discriminant : constant Name_Id := N + $;
+ Name_Operands : constant Name_Id := N + $;
+
-- Other miscellaneous names used in front end
Name_Unaligned_Valid : constant Name_Id := N + $;
diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c
index a265e01..8fc8415 100644
--- a/gcc/ada/socket.c
+++ b/gcc/ada/socket.c
@@ -803,4 +803,15 @@ const char * __gnat_gai_strerror(int errcode) {
#endif
+int __gnat_minus_500ms() {
+#if defined (_WIN32)
+ // Windows Server 2019 and Windows 8.0 do not need 500 millisecond socket
+ // timeout correction.
+ return !(IsWindows8OrGreater() && !IsWindowsServer()
+ || IsWindowsVersionOrGreater(10, 0, 17763));
+#else
+ return 0;
+#endif
+}
+
#endif /* defined(HAVE_SOCKETS) */
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index c17cf57..8a8139d 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -1483,9 +1483,9 @@ package body Sprint is
end;
when N_Decimal_Fixed_Point_Definition =>
- Write_Str_With_Col_Check_Sloc (" delta ");
+ Write_Str_With_Col_Check_Sloc ("delta ");
Sprint_Node (Delta_Expression (Node));
- Write_Str_With_Col_Check ("digits ");
+ Write_Str_With_Col_Check (" digits ");
Sprint_Node (Digits_Expression (Node));
Sprint_Opt_Node (Real_Range_Specification (Node));
@@ -4187,9 +4187,7 @@ package body Sprint is
declare
B : constant Node_Id := Etype (Typ);
- X : Node_Id;
P : constant Node_Id := Parent (Typ);
-
S : constant Saved_Output_Buffer := Save_Output_Buffer;
-- Save current output buffer
@@ -4197,6 +4195,8 @@ package body Sprint is
-- Save sloc of related node, so it is not modified when
-- printing with -gnatD.
+ X : Node_Id;
+
begin
-- Write indentation at start of line
@@ -4324,8 +4324,8 @@ package body Sprint is
declare
L : constant Node_Id := Type_Low_Bound (Typ);
H : constant Node_Id := Type_High_Bound (Typ);
- LE : Node_Id;
- HE : Node_Id;
+ BL : Node_Id;
+ BH : Node_Id;
begin
-- B can either be a scalar type, in which case the
@@ -4335,29 +4335,29 @@ package body Sprint is
-- constraint.
if Is_Scalar_Type (B) then
- LE := Type_Low_Bound (B);
- HE := Type_High_Bound (B);
+ BL := Type_Low_Bound (B);
+ BH := Type_High_Bound (B);
else
- LE := Empty;
- HE := Empty;
+ BL := Empty;
+ BH := Empty;
end if;
- if No (LE)
+ if No (BL)
or else (True
and then Nkind (L) = N_Integer_Literal
and then Nkind (H) = N_Integer_Literal
- and then Nkind (LE) = N_Integer_Literal
- and then Nkind (HE) = N_Integer_Literal
- and then UI_Eq (Intval (L), Intval (LE))
- and then UI_Eq (Intval (H), Intval (HE)))
+ and then Nkind (BL) = N_Integer_Literal
+ and then Nkind (BH) = N_Integer_Literal
+ and then UI_Eq (Intval (L), Intval (BL))
+ and then UI_Eq (Intval (H), Intval (BH)))
then
null;
else
Write_Str (" range ");
- Sprint_Node (Type_Low_Bound (Typ));
+ Sprint_Node (L);
Write_Str (" .. ");
- Sprint_Node (Type_High_Bound (Typ));
+ Sprint_Node (H);
end if;
end;
@@ -4368,7 +4368,7 @@ package body Sprint is
Write_Str ("mod ");
Write_Uint_With_Col_Check (Modulus (Typ), Auto);
- -- Floating point types and subtypes
+ -- Floating-point types and subtypes
when E_Floating_Point_Subtype
| E_Floating_Point_Type
@@ -4379,9 +4379,9 @@ package body Sprint is
Write_Str ("new ");
end if;
- Write_Id (Etype (Typ));
+ Write_Id (B);
- if Digits_Value (Typ) /= Digits_Value (Etype (Typ)) then
+ if Digits_Value (Typ) /= Digits_Value (B) then
Write_Str (" digits ");
Write_Uint_With_Col_Check
(Digits_Value (Typ), Decimal);
@@ -4392,27 +4392,54 @@ package body Sprint is
declare
L : constant Node_Id := Type_Low_Bound (Typ);
H : constant Node_Id := Type_High_Bound (Typ);
- LE : constant Node_Id := Type_Low_Bound (B);
- HE : constant Node_Id := Type_High_Bound (B);
+ BL : constant Node_Id := Type_Low_Bound (B);
+ BH : constant Node_Id := Type_High_Bound (B);
begin
- if Nkind (L) = N_Real_Literal
+ if True
+ and then Nkind (L) = N_Real_Literal
and then Nkind (H) = N_Real_Literal
- and then Nkind (LE) = N_Real_Literal
- and then Nkind (HE) = N_Real_Literal
- and then UR_Eq (Realval (L), Realval (LE))
- and then UR_Eq (Realval (H), Realval (HE))
+ and then Nkind (BL) = N_Real_Literal
+ and then Nkind (BH) = N_Real_Literal
+ and then UR_Eq (Realval (L), Realval (BL))
+ and then UR_Eq (Realval (H), Realval (BH))
then
null;
else
Write_Str (" range ");
- Sprint_Node (Type_Low_Bound (Typ));
+ Sprint_Node (L);
Write_Str (" .. ");
- Sprint_Node (Type_High_Bound (Typ));
+ Sprint_Node (H);
end if;
end;
+ -- Ordinary fixed-point types and subtypes
+
+ when E_Ordinary_Fixed_Point_Subtype
+ | E_Ordinary_Fixed_Point_Type
+ =>
+ Write_Header (Ekind (Typ) = E_Ordinary_Fixed_Point_Type);
+
+ Write_Str ("delta ");
+ Write_Ureal_With_Col_Check_Sloc (Delta_Value (Typ));
+ Write_Str (" range ");
+ Sprint_Node (Type_Low_Bound (Typ));
+ Write_Str (" .. ");
+ Sprint_Node (Type_High_Bound (Typ));
+
+ -- Decimal fixed-point types and subtypes
+
+ when E_Decimal_Fixed_Point_Subtype
+ | E_Decimal_Fixed_Point_Type
+ =>
+ Write_Header (Ekind (Typ) = E_Decimal_Fixed_Point_Type);
+
+ Write_Str ("delta ");
+ Write_Ureal_With_Col_Check_Sloc (Delta_Value (Typ));
+ Write_Str (" digits ");
+ Write_Uint_With_Col_Check (Digits_Value (Typ), Decimal);
+
-- Record subtypes
when E_Record_Subtype
@@ -4493,16 +4520,16 @@ package body Sprint is
when E_String_Literal_Subtype =>
declare
- LB : constant Uint :=
+ L : constant Uint :=
Expr_Value (String_Literal_Low_Bound (Typ));
Len : constant Uint :=
String_Literal_Length (Typ);
begin
Write_Header (False);
Write_Str ("String (");
- Write_Int (UI_To_Int (LB));
+ Write_Int (UI_To_Int (L));
Write_Str (" .. ");
- Write_Int (UI_To_Int (LB + Len) - 1);
+ Write_Int (UI_To_Int (L + Len) - 1);
Write_Str (");");
end;
diff --git a/gcc/ada/sprint.ads b/gcc/ada/sprint.ads
index b76b5d9..11a552f 100644
--- a/gcc/ada/sprint.ads
+++ b/gcc/ada/sprint.ads
@@ -70,7 +70,7 @@ package Sprint is
-- Multiple concatenation expr && expr && expr ... && expr
-- Multiply wi Treat_Fixed_As_Integer x #* y
-- Multiply wi Rounded_Result x @* y
- -- Operator with range check {operator} (e.g. {+})
+ -- Operator with overflow check {operator} (e.g. {+})
-- Others choice for cleanup when all others
-- Pop exception label %pop_xxx_exception_label
-- Push exception label %push_xxx_exception_label (label)
diff --git a/gcc/ada/switch-b.adb b/gcc/ada/switch-b.adb
index dc62ec2..3902b66 100644
--- a/gcc/ada/switch-b.adb
+++ b/gcc/ada/switch-b.adb
@@ -353,6 +353,12 @@ package body Switch.B is
Ptr := Ptr + 1;
Usage_Requested := True;
+ -- Processing for H switch
+
+ when 'H' =>
+ Ptr := Ptr + 1;
+ Legacy_Elaboration_Order := True;
+
-- Processing for i switch
when 'i' =>
diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c
index 0fbc606..1e1f5ee 100644
--- a/gcc/ada/sysdep.c
+++ b/gcc/ada/sysdep.c
@@ -33,6 +33,7 @@
GNAT Run Time Library */
#ifdef __vxworks
+#include "vxWorks.h"
#include "ioLib.h"
#if ! defined (VTHREADS)
#include "dosFsLib.h"
@@ -41,7 +42,6 @@
# include "nfsLib.h"
#endif
#include "selectLib.h"
-#include "vxWorks.h"
#include "version.h"
#if defined (__RTP__)
# include "vwModNum.h"
@@ -54,8 +54,10 @@
#ifdef IN_RTS
#define POSIX
-#include "tconfig.h"
-#include "tsystem.h"
+#include "runtime.h"
+#include <string.h>
+#include <unistd.h>
+
#include <fcntl.h>
#include <sys/stat.h>
#else
@@ -300,7 +302,7 @@ __gnat_set_mode (int handle ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
}
char *
-__gnat_ttyname (int filedes)
+__gnat_ttyname (int filedes ATTRIBUTE_UNUSED)
{
#if defined (__vxworks)
return "";
@@ -896,30 +898,34 @@ __gnat_get_task_options (void)
#endif
int
-__gnat_is_file_not_found_error (int errno_val) {
- switch (errno_val) {
- case ENOENT:
+__gnat_is_file_not_found_error (int errno_val)
+ {
+ /* WARNING: Do not rewrite this as a switch/case statement.
+ * Some of the "cases" are duplicated in some versions of
+ * Vxworks, notably VxWorks7r2 SR0610. */
+ if (errno_val == ENOENT)
+ return 1;
#ifdef __vxworks
- /* In the case of VxWorks, we also have to take into account various
- * filesystem-specific variants of this error.
- */
+ /* In the case of VxWorks, we also have to take into account various
+ * filesystem-specific variants of this error.
+ */
#if ! defined (VTHREADS) && (_WRS_VXWORKS_MAJOR < 7)
- case S_dosFsLib_FILE_NOT_FOUND:
+ else if (errno_val == S_dosFsLib_FILE_NOT_FOUND)
+ return 1;
#endif
#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
- case S_nfsLib_NFSERR_NOENT:
+ else if (errno_val == S_nfsLib_NFSERR_NOENT)
+ return 1;
#endif
#if defined (__RTP__)
- /* An RTP can return an NFS file not found, and the NFS bits must
- first be masked on to check the errno. */
- case M_nfsStat | ENOENT:
+ /* An RTP can return an NFS file not found, and the NFS bits must
+ first be masked on to check the errno. */
+ else if (errno_val == (M_nfsStat | ENOENT))
+ return 1;
#endif
#endif
- return 1;
-
- default:
- return 0;
- }
+ else
+ return 0;
}
#if defined (__linux__)
diff --git a/gcc/ada/targext.c b/gcc/ada/targext.c
index 39d75d1..d761b2a 100644
--- a/gcc/ada/targext.c
+++ b/gcc/ada/targext.c
@@ -36,14 +36,21 @@
the file must be compiled with IN_GCC defined, even for the library. */
#ifdef IN_RTS
+
+#ifndef STANDALONE
#include "tconfig.h"
#include "tsystem.h"
+#endif
+
#else
#include "config.h"
#include "system.h"
#endif
+
+#ifndef STANDALONE
#include "coretypes.h"
#include "tm.h"
+#endif
#ifndef TARGET_OBJECT_SUFFIX
#define TARGET_OBJECT_SUFFIX ".o"
diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c
index 23f9dfd..320ad28 100644
--- a/gcc/ada/terminals.c
+++ b/gcc/ada/terminals.c
@@ -108,7 +108,7 @@ __gnat_tty_supported (void)
}
int
-__gnat_tty_waitpid (void *desc ATTRIBUTE_UNUSED)
+__gnat_tty_waitpid (void *desc ATTRIBUTE_UNUSED, int blocking)
{
return 1;
}
@@ -152,6 +152,7 @@ __gnat_setup_winsize (void *desc ATTRIBUTE_UNUSED,
#include <stdlib.h>
#include <windows.h>
+#include <winternl.h>
#define MAXPATHLEN 1024
@@ -1014,20 +1015,28 @@ __gnat_terminate_pid (int pid)
the Win32 API instead of the C one. */
int
-__gnat_tty_waitpid (struct TTY_Process* p)
+__gnat_tty_waitpid (struct TTY_Process* p, int blocking)
{
DWORD exitcode;
- DWORD res;
- HANDLE proc_hand = p->procinfo.hProcess;
+ HANDLE hprocess = p->procinfo.hProcess;
- res = WaitForSingleObject (proc_hand, 0);
- GetExitCodeProcess (proc_hand, &exitcode);
+ if (blocking) {
+ /* Wait is needed on Windows only in blocking mode. */
+ WaitForSingleObject (hprocess, 0);
+ }
- CloseHandle (p->procinfo.hThread);
- CloseHandle (p->procinfo.hProcess);
+ GetExitCodeProcess (hprocess, &exitcode);
- /* No need to close the handles: they were closed on the ada side */
+ if (exitcode == STILL_ACTIVE) {
+ /* If process is still active return -1. */
+ exitcode = -1;
+ } else {
+ /* Process is dead, so handle to process and main thread can be closed. */
+ CloseHandle (p->procinfo.hThread);
+ CloseHandle (hprocess);
+ }
+ /* No need to close the handles: they were closed on the ada side */
return (int) exitcode;
}
@@ -1556,11 +1565,21 @@ __gnat_terminate_pid (int pid)
* exit status of the child process
*/
int
-__gnat_tty_waitpid (pty_desc *desc)
+__gnat_tty_waitpid (pty_desc *desc, int blocking)
{
- int status = 0;
- waitpid (desc->child_pid, &status, 0);
- return WEXITSTATUS (status);
+ int status = -1;
+ int options = 0;
+
+ if (blocking) {
+ options = 0;
+ } else {
+ options = WNOHANG;
+ }
+ waitpid (desc->child_pid, &status, options);
+ if WIFEXITED (status) {
+ status = WEXITSTATUS (status);
+ }
+ return status;
}
/* __gnat_tty_supported - Are tty supported ?
diff --git a/gcc/ada/tracebak.c b/gcc/ada/tracebak.c
index a43dc4d..9e74282 100644
--- a/gcc/ada/tracebak.c
+++ b/gcc/ada/tracebak.c
@@ -50,14 +50,10 @@
extern "C" {
#endif
-#ifdef __alpha_vxworks
-#include "vxWorks.h"
-#endif
-
#ifdef IN_RTS
#define POSIX
-#include "tconfig.h"
-#include "tsystem.h"
+#include "runtime.h"
+#include <stddef.h>
#else
#include "config.h"
#include "system.h"
diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb
index 1eace05..fb261e5 100644
--- a/gcc/ada/usage.adb
+++ b/gcc/ada/usage.adb
@@ -483,6 +483,8 @@ begin
Write_Line (" A turn off all optional info/warnings");
Write_Line (" .a*+ turn on warnings for failing assertion");
Write_Line (" .A turn off warnings for failing assertion");
+ Write_Line (" _a*+ turn on warnings for anonymous allocators");
+ Write_Line (" _A turn off warnings for anonymous allocators");
Write_Line (" b+ turn on warnings for bad fixed value " &
"(not multiple of small)");
Write_Line (" B* turn off warnings for bad fixed value " &
diff --git a/gcc/ada/validsw.adb b/gcc/ada/validsw.adb
index d08299d..ae155c3 100644
--- a/gcc/ada/validsw.adb
+++ b/gcc/ada/validsw.adb
@@ -36,11 +36,12 @@ package body Validsw is
begin
Validity_Check_Components := False;
Validity_Check_Copies := False;
- Validity_Check_Default := True;
+ Validity_Check_Default := False;
Validity_Check_Floating_Point := False;
Validity_Check_In_Out_Params := False;
Validity_Check_In_Params := False;
Validity_Check_Operands := False;
+ Validity_Check_Parameters := False;
Validity_Check_Returns := False;
Validity_Check_Subscripts := False;
Validity_Check_Tests := False;
@@ -73,14 +74,14 @@ package body Validsw is
Options (K) := ' ';
end loop;
- Add ('n', not Validity_Check_Default);
-
- Add ('c', Validity_Check_Copies);
Add ('e', Validity_Check_Components);
+ Add ('c', Validity_Check_Copies);
+ Add ('d', Validity_Check_Default);
Add ('f', Validity_Check_Floating_Point);
Add ('i', Validity_Check_In_Params);
Add ('m', Validity_Check_In_Out_Params);
Add ('o', Validity_Check_Operands);
+ Add ('p', Validity_Check_Parameters);
Add ('r', Validity_Check_Returns);
Add ('s', Validity_Check_Subscripts);
Add ('t', Validity_Check_Tests);
diff --git a/gcc/ada/validsw.ads b/gcc/ada/validsw.ads
index 2dadc5c..5197bdf 100644
--- a/gcc/ada/validsw.ads
+++ b/gcc/ada/validsw.ads
@@ -40,33 +40,33 @@ package Validsw is
-- or in the argument of a Validity_Checks pragma to activate the option.
-- The corresponding upper case letter deactivates the option.
+ Validity_Check_Components : Boolean := False;
+ -- Controls validity checking for assignment to elementary components of
+ -- records. If this switch is set to True using -gnatVe, or an 'e' in the
+ -- argument of Validity_Checks pragma, then the right-hand side of an
+ -- assignment to such a component is checked for validity.
+
Validity_Check_Copies : Boolean := False;
-- Controls the validity checking of copies. If this switch is set to
- -- true using -gnatVc, or a 'c' in the argument of a Validity_Checks
- -- pragma, then the right side of assignments and also initializing
+ -- True using -gnatVc, or a 'c' in the argument of a Validity_Checks
+ -- pragma, then the right-hand side of assignments and also initializing
-- expressions in object declarations are checked for validity.
- Validity_Check_Components : Boolean := False;
- -- Controls validity checking for assignment to elementary components of
- -- records. If this switch is set true using -gnatVe, or an 'e' in the
- -- argument of Validity_Checks pragma, then the right hand of an assignment
- -- to such a component is checked for validity.
-
Validity_Check_Default : Boolean := True;
-- Controls default (reference manual) validity checking. If this switch is
-- set to True using -gnatVd or a 'd' in the argument of a Validity_Checks
- -- pragma (or the initial default value is used, set True), then left side
- -- subscripts and case statement arguments are checked for validity. This
- -- switch is also set by default if no -gnatV switch is used and no
+ -- pragma (or the initial default value is used, set True), then left-hand
+ -- side subscripts and case statement arguments are checked for validity.
+ -- This switch is also set by default if no -gnatV switch is used and no
-- Validity_Checks pragma is processed.
Validity_Check_Floating_Point : Boolean := False;
- -- Normally validity checking applies only to discrete values (integer
- -- and enumeration types). If this switch is set to True using -gnatVf
- -- or an 'f' in the argument of a Validity_Checks pragma, then floating-
- -- point values are also checked. The context in which such checks
- -- occur depends on other flags, e.g. if Validity_Check_Copies is also
- -- set then floating-point values on the right side of an assignment
+ -- Normally validity checking applies only to discrete values (integer and
+ -- enumeration types). If this switch is set to True using -gnatVf or an
+ -- 'f' in the argument of a Validity_Checks pragma, then floating-point
+ -- values are also checked. If the context in which such checks occur
+ -- depends on other flags, e.g. if Validity_Check_Copies is also set,
+ -- then floating-point values on the right-hand side of an assignment
-- will be validity checked.
Validity_Check_In_Out_Params : Boolean := False;
@@ -103,13 +103,13 @@ package Validsw is
-- pragma, then the expression in a RETURN statement is validity checked.
Validity_Check_Subscripts : Boolean := False;
- -- Controls validity checking of subscripts. If this switch is set to
- -- True using -gnatVs, or an 's' in the argument of a Validity_Checks
- -- pragma, then all subscripts are checked for validity. Note that left
- -- side subscript checking is controlled also by Validity_Check_Default.
- -- If Validity_Check_Subscripts is True, then all subscripts are checked,
- -- otherwise if Validity_Check_Default is True, then left side subscripts
- -- are checked, otherwise no subscripts are checked.
+ -- Controls validity checking of subscripts. If this switch is set to True
+ -- using -gnatVs, or an 's' in the argument of a Validity_Checks pragma,
+ -- then all subscripts are checked for validity. Note that left-hand side
+ -- subscript checking is also controlled by Validity_Check_Default. If
+ -- Validity_Check_Subscripts is True, then all subscripts are checked,
+ -- otherwise if Validity_Check_Default is True, then left-hand side
+ -- subscripts are checked; otherwise no subscripts are checked.
Validity_Check_Tests : Boolean := False;
-- Controls validity checking of tests that occur in conditions (i.e. the
diff --git a/gcc/ada/warnsw.adb b/gcc/ada/warnsw.adb
index 472f1df..219d440 100644
--- a/gcc/ada/warnsw.adb
+++ b/gcc/ada/warnsw.adb
@@ -56,6 +56,7 @@ package body Warnsw is
Warn_On_Ada_2005_Compatibility := Setting;
Warn_On_Ada_2012_Compatibility := Setting;
Warn_On_All_Unread_Out_Parameters := Setting;
+ Warn_On_Anonymous_Allocators := Setting;
Warn_On_Assertion_Failure := Setting;
Warn_On_Assumed_Low_Bound := Setting;
Warn_On_Atomic_Synchronization := Setting;
@@ -129,6 +130,8 @@ package body Warnsw is
W.Warn_On_Ada_2012_Compatibility;
Warn_On_All_Unread_Out_Parameters :=
W.Warn_On_All_Unread_Out_Parameters;
+ Warn_On_Anonymous_Allocators :=
+ W.Warn_On_Anonymous_Allocators;
Warn_On_Assertion_Failure :=
W.Warn_On_Assertion_Failure;
Warn_On_Assumed_Low_Bound :=
@@ -235,6 +238,8 @@ package body Warnsw is
Warn_On_Ada_2012_Compatibility;
W.Warn_On_All_Unread_Out_Parameters :=
Warn_On_All_Unread_Out_Parameters;
+ W.Warn_On_Anonymous_Allocators :=
+ Warn_On_Anonymous_Allocators;
W.Warn_On_Assertion_Failure :=
Warn_On_Assertion_Failure;
W.Warn_On_Assumed_Low_Bound :=
@@ -478,6 +483,12 @@ package body Warnsw is
function Set_Underscore_Warning_Switch (C : Character) return Boolean is
begin
case C is
+ when 'a' =>
+ Warn_On_Anonymous_Allocators := True;
+
+ when 'A' =>
+ Warn_On_Anonymous_Allocators := False;
+
when others =>
if Ignore_Unrecognized_VWY_Switches then
Write_Line ("unrecognized switch -gnatw_" & C & " ignored");
@@ -705,6 +716,7 @@ package body Warnsw is
Ineffective_Inline_Warnings := True; -- -gnatwp
Warn_On_Ada_2005_Compatibility := True; -- -gnatwy
Warn_On_Ada_2012_Compatibility := True; -- -gnatwy
+ Warn_On_Anonymous_Allocators := True; -- -gnatw_a
Warn_On_Assertion_Failure := True; -- -gnatw.a
Warn_On_Assumed_Low_Bound := True; -- -gnatww
Warn_On_Bad_Fixed_Value := True; -- -gnatwb
diff --git a/gcc/ada/warnsw.ads b/gcc/ada/warnsw.ads
index 23970a9..422f8df 100644
--- a/gcc/ada/warnsw.ads
+++ b/gcc/ada/warnsw.ads
@@ -38,6 +38,12 @@ package Warnsw is
-- here as time goes by. And in fact a really nice idea would be to put
-- them all in a Warn_Record so that they would be easy to save/restore.
+ Warn_On_Anonymous_Allocators : Boolean := False;
+ -- Warn when allocators for anonymous access types are present, which,
+ -- although not illegal in Ada, may be confusing to users due to how
+ -- accessibility checks get generated. Off by default, modified by use
+ -- of -gnatw_a/_A and set as part of -gnatwa.
+
Warn_On_Late_Primitives : Boolean := False;
-- Warn when tagged type public primitives are defined after its private
-- extensions.
@@ -90,6 +96,7 @@ package Warnsw is
Warn_On_Ada_2005_Compatibility : Boolean;
Warn_On_Ada_2012_Compatibility : Boolean;
Warn_On_All_Unread_Out_Parameters : Boolean;
+ Warn_On_Anonymous_Allocators : Boolean;
Warn_On_Assertion_Failure : Boolean;
Warn_On_Assumed_Low_Bound : Boolean;
Warn_On_Atomic_Synchronization : Boolean;
diff --git a/gcc/ada/xoscons.adb b/gcc/ada/xoscons.adb
index 0d5f635..7c72e4e 100644
--- a/gcc/ada/xoscons.adb
+++ b/gcc/ada/xoscons.adb
@@ -229,8 +229,7 @@ procedure XOSCons is
case Lang is
when Lang_Ada =>
Put (" subtype " & Info.Constant_Name.all
- & " is Interfaces.C."
- & Info.Text_Value.all & ";");
+ & " is " & Info.Text_Value.all & ";");
when Lang_C =>
Put ("#define " & Info.Constant_Name.all & " "
& Info.Text_Value.all);
diff --git a/gcc/ada/xref_lib.adb b/gcc/ada/xref_lib.adb
index 8b9c70a..4d400f3 100644
--- a/gcc/ada/xref_lib.adb
+++ b/gcc/ada/xref_lib.adb
@@ -1876,7 +1876,7 @@ package body Xref_Lib is
end if;
exception
- when No_Xref_Information => null;
+ when No_Xref_Information => null;
end;
end loop;
end Search_Xref;
diff --git a/gcc/alias.c b/gcc/alias.c
index eece84a..2755df7 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1202,47 +1202,52 @@ record_component_aliases (tree type)
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
- if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
- {
- /* LTO type merging does not make any difference between
- component pointer types. We may have
-
- struct foo {int *a;};
-
- as TYPE_CANONICAL of
-
- struct bar {float *a;};
-
- Because accesses to int * and float * do not alias, we would get
- false negative when accessing the same memory location by
- float ** and bar *. We thus record the canonical type as:
-
- struct {void *a;};
-
- void * is special cased and works as a universal pointer type.
- Accesses to it conflicts with accesses to any other pointer
- type. */
- tree t = TREE_TYPE (field);
- if (in_lto_p)
- {
- /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
- element type and that type has to be normalized to void *,
- too, in the case it is a pointer. */
- while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
- {
- gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
- t = TREE_TYPE (t);
- }
- if (POINTER_TYPE_P (t))
- t = ptr_type_node;
- else if (flag_checking)
- gcc_checking_assert (get_alias_set (t)
- == get_alias_set (TREE_TYPE (field)));
- }
-
- record_alias_subset (superset, get_alias_set (t));
- }
+ {
+ /* LTO non-ODR type merging does not make any difference between
+ component pointer types. We may have
+
+ struct foo {int *a;};
+
+ as TYPE_CANONICAL of
+
+ struct bar {float *a;};
+
+ Because accesses to int * and float * do not alias, we would get
+ false negative when accessing the same memory location by
+ float ** and bar *. We thus record the canonical type as:
+
+ struct {void *a;};
+
+ void * is special cased and works as a universal pointer type.
+ Accesses to it conflicts with accesses to any other pointer
+ type. */
+ bool void_pointers = in_lto_p
+ && (!odr_type_p (type)
+ || !odr_based_tbaa_p (type));
+ for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field))
+ {
+ tree t = TREE_TYPE (field);
+ if (void_pointers)
+ {
+ /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
+ element type and that type has to be normalized to void *,
+ too, in the case it is a pointer. */
+ while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
+ {
+ gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
+ t = TREE_TYPE (t);
+ }
+ if (POINTER_TYPE_P (t))
+ t = ptr_type_node;
+ else if (flag_checking)
+ gcc_checking_assert (get_alias_set (t)
+ == get_alias_set (TREE_TYPE (field)));
+ }
+
+ record_alias_subset (superset, get_alias_set (t));
+ }
+ }
break;
case COMPLEX_TYPE:
diff --git a/gcc/align.h b/gcc/align.h
index 6768451..6c98e2d 100644
--- a/gcc/align.h
+++ b/gcc/align.h
@@ -45,8 +45,9 @@ struct align_flags_tuple
/* Alignment flags is structure used as value of -align-* options.
It's used in target-dependant code. */
-struct align_flags
+class align_flags
{
+public:
/* Default constructor. */
align_flags (int log0 = 0, int maxskip0 = 0, int log1 = 0, int maxskip1 = 0)
{
diff --git a/gcc/alloc-pool.h b/gcc/alloc-pool.h
index d320810..d8878b6 100644
--- a/gcc/alloc-pool.h
+++ b/gcc/alloc-pool.h
@@ -34,8 +34,9 @@ typedef unsigned long ALLOC_POOL_ID_TYPE;
extern ALLOC_POOL_ID_TYPE last_id;
/* Pool allocator memory usage. */
-struct pool_usage: public mem_usage
+class pool_usage: public mem_usage
{
+public:
/* Default contructor. */
pool_usage (): m_element_size (0), m_pool_name ("") {}
/* Constructor. */
diff --git a/gcc/asan.c b/gcc/asan.c
index 605d04f..a731bd4 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1225,8 +1225,9 @@ shadow_mem_size (unsigned HOST_WIDE_INT size)
#define RZ_BUFFER_SIZE 4
/* ASAN redzone buffer container that handles emission of shadow bytes. */
-struct asan_redzone_buffer
+class asan_redzone_buffer
{
+public:
/* Constructor. */
asan_redzone_buffer (rtx shadow_mem, HOST_WIDE_INT prev_offset):
m_shadow_mem (shadow_mem), m_prev_offset (prev_offset),
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 8e54016..f4777c6 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -1931,15 +1931,19 @@ decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist,
if (!has_attribute (tmpls[j], tmpl_attrs[j], blacklist[i]))
continue;
+ bool found = false;
unsigned kmax = 1 + !!decl_attrs[1];
for (unsigned k = 0; k != kmax; ++k)
{
if (has_attribute (decls[k], decl_attrs[k], blacklist[i]))
- break;
-
- if (!k && kmax > 1)
- continue;
+ {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
if (nattrs)
pp_string (attrstr, ", ");
pp_begin_quote (attrstr, pp_show_color (global_dc->printer));
@@ -1947,6 +1951,8 @@ decls_mismatched_attributes (tree tmpl, tree decl, tree attrlist,
pp_end_quote (attrstr, pp_show_color (global_dc->printer));
++nattrs;
}
+
+ break;
}
}
diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c
index 26353a2..ee1a83a 100644
--- a/gcc/auto-profile.c
+++ b/gcc/auto-profile.c
@@ -104,7 +104,7 @@ namespace autofdo
/* Intermediate edge info used when propagating AutoFDO profile information.
We can't edge->count() directly since it's computed from edge's probability
while probability is yet not decided during propagation. */
-#define AFDO_EINFO(e) ((struct edge_info *) e->aux)
+#define AFDO_EINFO(e) ((class edge_info *) e->aux)
class edge_info
{
public:
@@ -136,8 +136,9 @@ typedef std::map<unsigned, gcov_type> icall_target_map;
typedef std::set<gimple *> stmt_set;
/* Represent count info of an inline stack. */
-struct count_info
+class count_info
{
+public:
/* Sampled count of the inline stack. */
gcov_type count;
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index fba5526..2a0e826 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -23,7 +23,8 @@ along with GCC; see the file COPYING3. If not see
#include <profile-count.h>
/* Control flow edge information. */
-struct GTY((user)) edge_def {
+class GTY((user)) edge_def {
+public:
/* The two blocks at the ends of the edge. */
basic_block src;
basic_block dest;
@@ -122,7 +123,7 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d
PTR GTY ((skip (""))) aux;
/* Innermost loop containing the block. */
- struct loop *loop_father;
+ class loop *loop_father;
/* The dominance and postdominance information node. */
struct et_node * GTY ((skip (""))) dom[2];
@@ -507,6 +508,8 @@ ei_cond (edge_iterator ei, edge *p)
#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */
#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */
#define CLEANUP_NO_PARTITIONING 128 /* Do not try to fix partitions. */
+#define CLEANUP_FORCE_FAST_DCE 0x100 /* Force run_fast_dce to be called
+ at least once. */
/* Return true if BB is in a transaction. */
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index 894aefa..c99d646 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -775,7 +775,7 @@ bitmap_alloc (bitmap_obstack *bit_obstack MEM_STAT_DECL)
bit_obstack = &bitmap_default_obstack;
map = bit_obstack->heads;
if (map)
- bit_obstack->heads = (struct bitmap_head *) map->first;
+ bit_obstack->heads = (class bitmap_head *) map->first;
else
map = XOBNEW (&bit_obstack->obstack, bitmap_head);
bitmap_initialize (map, bit_obstack PASS_MEM_STAT);
diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index 39f509d..b0ca7b9 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -212,8 +212,9 @@ along with GCC; see the file COPYING3. If not see
#include "obstack.h"
/* Bitmap memory usage. */
-struct bitmap_usage: public mem_usage
+class bitmap_usage: public mem_usage
{
+public:
/* Default contructor. */
bitmap_usage (): m_nsearches (0), m_search_iter (0) {}
/* Constructor. */
@@ -289,7 +290,7 @@ typedef unsigned long BITMAP_WORD;
/* Obstack for allocating bitmaps and elements from. */
struct bitmap_obstack {
struct bitmap_element *elements;
- struct bitmap_head *heads;
+ bitmap_head *heads;
struct obstack obstack;
};
@@ -321,7 +322,8 @@ struct GTY((chain_next ("%h.next"))) bitmap_element {
/* Head of bitmap linked list. The 'current' member points to something
already pointed to by the chain started by first, so GTY((skip)) it. */
-struct GTY(()) bitmap_head {
+class GTY(()) bitmap_head {
+public:
static bitmap_obstack crashme;
/* Poison obstack to not make it not a valid initialized GC bitmap. */
CONSTEXPR bitmap_head()
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e2ba356..e5a9261 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1400,7 +1400,7 @@ expand_builtin_prefetch (tree exp)
if (targetm.have_prefetch ())
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
create_address_operand (&ops[0], op0);
create_integer_operand (&ops[1], INTVAL (op1));
@@ -2445,7 +2445,7 @@ expand_builtin_interclass_mathfn (tree exp, rtx target)
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[1];
+ class expand_operand ops[1];
rtx_insn *last = get_last_insn ();
tree orig_arg = arg;
@@ -2946,7 +2946,7 @@ expand_builtin_strlen (tree exp, rtx target,
if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
return NULL_RTX;
- struct expand_operand ops[4];
+ class expand_operand ops[4];
rtx pat;
tree len;
tree src = CALL_EXPR_ARG (exp, 0);
@@ -3923,7 +3923,7 @@ expand_builtin_mempcpy_args (tree dest, tree src, tree len,
static rtx
expand_movstr (tree dest, tree src, rtx target, memop_ret retmode)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
rtx dest_mem;
rtx src_mem;
@@ -4633,7 +4633,7 @@ expand_cmpstr (insn_code icode, rtx target, rtx arg1_rtx, rtx arg2_rtx,
if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
target = NULL_RTX;
- struct expand_operand ops[4];
+ class expand_operand ops[4];
create_output_operand (&ops[0], target, insn_mode);
create_fixed_operand (&ops[1], arg1_rtx);
create_fixed_operand (&ops[2], arg2_rtx);
@@ -5606,7 +5606,7 @@ expand_builtin___clear_cache (tree exp)
if (targetm.have_clear_cache ())
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
begin = CALL_EXPR_ARG (exp, 0);
begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
@@ -6566,7 +6566,7 @@ expand_ifn_atomic_bit_test_and (gcall *call)
machine_mode mode = TYPE_MODE (TREE_TYPE (flag));
enum rtx_code code;
optab optab;
- struct expand_operand ops[5];
+ class expand_operand ops[5];
gcc_assert (flag_inline_atomics);
@@ -6874,7 +6874,7 @@ expand_builtin_thread_pointer (tree exp, rtx target)
icode = direct_optab_handler (get_thread_pointer_optab, Pmode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand op;
+ class expand_operand op;
/* If the target is not sutitable then create a new target. */
if (target == NULL_RTX
|| !REG_P (target)
@@ -6897,7 +6897,7 @@ expand_builtin_set_thread_pointer (tree exp)
icode = direct_optab_handler (set_thread_pointer_optab, Pmode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand op;
+ class expand_operand op;
rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
Pmode, EXPAND_NORMAL);
create_input_operand (&op, val, Pmode);
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 84d1f2e..e645254 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,38 @@
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_LOOP.
+ (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_BIND.
+ * c-pragma.c (omp_pragmas_simd): Add PRAGMA_OMP_LOOP entry.
+ * c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_LOOP.
+ * c-omp.c (c_omp_split_clauses): Add support for 4 new combined
+ constructs with the loop construct.
+
+2019-07-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/91149
+ * c-omp.c (c_omp_split_clauses): Fix a pasto in
+ OMP_CLAUSE_REDUCTION_TASK handling.
+
+2019-07-12 Jakub Jelinek <jakub@redhat.com>
+
+ * c-pragma.h (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_ORDER.
+ * c-omp.c (c_omp_split_clauses): Handle splitting of OMP_CLAUSE_ORDER.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * c-opts.c (handle_deferred_opts): Change class-key of PODs to struct
+ and others to class.
+ * c-pretty-print.h: Same.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * c-format.c (check_argument_type): Change class-key from class to
+ struct and vice versa to match convention and avoid -Wclass-is-pod
+ and -Wstruct-no-pod.
+ * c-pretty-print.h: Same.
+
2019-07-03 Martin Liska <mliska@suse.cz>
* c-common.c (try_to_locate_new_include_insertion_point): Remove
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 5ac6e5e..117d729 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1148,7 +1148,8 @@ enum c_omp_clause_split
C_OMP_CLAUSE_SPLIT_SIMD,
C_OMP_CLAUSE_SPLIT_COUNT,
C_OMP_CLAUSE_SPLIT_SECTIONS = C_OMP_CLAUSE_SPLIT_FOR,
- C_OMP_CLAUSE_SPLIT_TASKLOOP = C_OMP_CLAUSE_SPLIT_FOR
+ C_OMP_CLAUSE_SPLIT_TASKLOOP = C_OMP_CLAUSE_SPLIT_FOR,
+ C_OMP_CLAUSE_SPLIT_LOOP = C_OMP_CLAUSE_SPLIT_FOR
};
enum c_omp_region_type
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 6363fa4..d134116 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -1839,8 +1839,9 @@ class flag_chars_t
/* Support struct for argument_parser and check_format_info_main.
Encapsulates any length modifier applied to the current argument. */
-struct length_modifier
+class length_modifier
{
+public:
length_modifier ()
: chars (NULL), val (FMT_LEN_none), std (STD_C89),
scalar_identity_flag (0)
@@ -2853,8 +2854,9 @@ check_argument_type (const format_char_info *fci,
/* Describes "paired tokens" within the format string that are
expected to be balanced. */
-struct baltoks_t
+class baltoks_t
{
+public:
baltoks_t (): singlequote (), doublequote () { }
typedef auto_vec<const char *> balanced_tokens_t;
diff --git a/gcc/c-family/c-omp.c b/gcc/c-family/c-omp.c
index 583305e..10f7c4e 100644
--- a/gcc/c-family/c-omp.c
+++ b/gcc/c-family/c-omp.c
@@ -1263,7 +1263,7 @@ c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
}
/* This function attempts to split or duplicate clauses for OpenMP
- combined/composite constructs. Right now there are 26 different
+ combined/composite constructs. Right now there are 30 different
constructs. CODE is the innermost construct in the combined construct,
and MASK allows to determine which constructs are combined together,
as every construct has at least one clause that no other construct
@@ -1278,6 +1278,7 @@ c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
#pragma omp master taskloop simd
#pragma omp parallel for
#pragma omp parallel for simd
+ #pragma omp parallel loop
#pragma omp parallel master
#pragma omp parallel master taskloop
#pragma omp parallel master taskloop simd
@@ -1285,17 +1286,20 @@ c_oacc_split_loop_clauses (tree clauses, tree *not_loop_clauses,
#pragma omp target parallel
#pragma omp target parallel for
#pragma omp target parallel for simd
+ #pragma omp target parallel loop
#pragma omp target teams
#pragma omp target teams distribute
#pragma omp target teams distribute parallel for
#pragma omp target teams distribute parallel for simd
#pragma omp target teams distribute simd
+ #pragma omp target teams loop
#pragma omp target simd
#pragma omp taskloop simd
#pragma omp teams distribute
#pragma omp teams distribute parallel for
#pragma omp teams distribute parallel for simd
- #pragma omp teams distribute simd */
+ #pragma omp teams distribute simd
+ #pragma omp teams loop */
void
c_omp_split_clauses (location_t loc, enum tree_code code,
@@ -1375,7 +1379,11 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
case OMP_CLAUSE_PRIORITY:
s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
break;
- /* Duplicate this to all of taskloop, distribute, for and simd. */
+ case OMP_CLAUSE_BIND:
+ s = C_OMP_CLAUSE_SPLIT_LOOP;
+ break;
+ /* Duplicate this to all of taskloop, distribute, for, simd and
+ loop. */
case OMP_CLAUSE_COLLAPSE:
if (code == OMP_SIMD)
{
@@ -1418,6 +1426,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
else if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
!= 0)
s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+ else if (code == OMP_LOOP)
+ s = C_OMP_CLAUSE_SPLIT_LOOP;
else
s = C_OMP_CLAUSE_SPLIT_DISTRIBUTE;
break;
@@ -1435,12 +1445,13 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
case OMP_TEAMS: s = C_OMP_CLAUSE_SPLIT_TEAMS; break;
case OMP_MASTER: s = C_OMP_CLAUSE_SPLIT_PARALLEL; break;
case OMP_TASKLOOP: s = C_OMP_CLAUSE_SPLIT_TASKLOOP; break;
+ case OMP_LOOP: s = C_OMP_CLAUSE_SPLIT_LOOP; break;
default: gcc_unreachable ();
}
break;
/* Firstprivate clause is supported on all constructs but
- simd and master. Put it on the outermost of those and duplicate on
- teams and parallel. */
+ simd, master and loop. Put it on the outermost of those and
+ duplicate on teams and parallel. */
case OMP_CLAUSE_FIRSTPRIVATE:
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP))
!= 0)
@@ -1486,7 +1497,7 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
else
/* This must be
- #pragma omp parallel{, for{, simd}, sections}
+ #pragma omp parallel{, for{, simd}, sections,loop}
or
#pragma omp target parallel. */
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
@@ -1495,10 +1506,11 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
!= 0)
{
/* This must be one of
- #pragma omp {,target }teams distribute
+ #pragma omp {,target }teams {distribute,loop}
#pragma omp target teams
#pragma omp {,target }teams distribute simd. */
gcc_assert (code == OMP_DISTRIBUTE
+ || code == OMP_LOOP
|| code == OMP_TEAMS
|| code == OMP_SIMD);
s = C_OMP_CLAUSE_SPLIT_TEAMS;
@@ -1526,9 +1538,9 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
s = C_OMP_CLAUSE_SPLIT_FOR;
}
break;
- /* Lastprivate is allowed on distribute, for, sections, taskloop and
- simd. In parallel {for{, simd},sections} we actually want to put
- it on parallel rather than for or sections. */
+ /* Lastprivate is allowed on distribute, for, sections, taskloop, loop
+ and simd. In parallel {for{, simd},sections} we actually want to
+ put it on parallel rather than for or sections. */
case OMP_CLAUSE_LASTPRIVATE:
if (code == OMP_DISTRIBUTE)
{
@@ -1560,6 +1572,11 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
break;
}
+ if (code == OMP_LOOP)
+ {
+ s = C_OMP_CLAUSE_SPLIT_LOOP;
+ break;
+ }
gcc_assert (code == OMP_SIMD);
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
{
@@ -1632,24 +1649,44 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
}
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
break;
- /* Reduction is allowed on simd, for, parallel, sections, taskloop
- and teams. Duplicate it on all of them, but omit on for or
+ /* order clauses are allowed on for, simd and loop. */
+ case OMP_CLAUSE_ORDER:
+ if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)) != 0)
+ {
+ if (code == OMP_SIMD)
+ {
+ c = build_omp_clause (OMP_CLAUSE_LOCATION (clauses),
+ OMP_CLAUSE_ORDER);
+ OMP_CLAUSE_CHAIN (c) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
+ cclauses[C_OMP_CLAUSE_SPLIT_FOR] = c;
+ s = C_OMP_CLAUSE_SPLIT_SIMD;
+ }
+ else
+ s = C_OMP_CLAUSE_SPLIT_FOR;
+ }
+ else if (code == OMP_LOOP)
+ s = C_OMP_CLAUSE_SPLIT_LOOP;
+ else
+ s = C_OMP_CLAUSE_SPLIT_SIMD;
+ break;
+ /* Reduction is allowed on simd, for, parallel, sections, taskloop,
+ teams and loop. Duplicate it on all of them, but omit on for or
sections if parallel is present (unless inscan, in that case
- omit on parallel). If taskloop is combined with
+ omit on parallel). If taskloop or loop is combined with
parallel, omit it on parallel. */
case OMP_CLAUSE_REDUCTION:
if (OMP_CLAUSE_REDUCTION_TASK (clauses))
{
- if (code == OMP_SIMD /* || code == OMP_LOOP */)
+ if (code == OMP_SIMD || code == OMP_LOOP)
{
error_at (OMP_CLAUSE_LOCATION (clauses),
"invalid %<task%> reduction modifier on construct "
- "combined with %<simd%>" /* or %<loop%> */);
+ "combined with %<simd%> or %<loop%>");
OMP_CLAUSE_REDUCTION_TASK (clauses) = 0;
}
else if (code != OMP_SECTIONS
&& (mask & (OMP_CLAUSE_MASK_1
- << PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0
+ << PRAGMA_OMP_CLAUSE_NUM_THREADS)) == 0
&& (mask & (OMP_CLAUSE_MASK_1
<< PRAGMA_OMP_CLAUSE_SCHEDULE)) == 0)
{
@@ -1721,6 +1758,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
s = C_OMP_CLAUSE_SPLIT_PARALLEL;
else if (code == OMP_TASKLOOP)
s = C_OMP_CLAUSE_SPLIT_TASKLOOP;
+ else if (code == OMP_LOOP)
+ s = C_OMP_CLAUSE_SPLIT_LOOP;
else if (code == OMP_SIMD)
{
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))
@@ -1912,7 +1951,8 @@ c_omp_split_clauses (location_t loc, enum tree_code code,
gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] == NULL_TREE);
if ((mask & ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP))) == 0
- && code != OMP_SECTIONS)
+ && code != OMP_SECTIONS
+ && code != OMP_LOOP)
gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_FOR] == NULL_TREE);
if (code != OMP_SIMD)
gcc_assert (cclauses[C_OMP_CLAUSE_SPLIT_SIMD] == NULL_TREE);
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 188da43..e97bbdf5 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1287,7 +1287,7 @@ handle_deferred_opts (void)
if (!deps_seen)
return;
- struct mkdeps *deps = cpp_get_deps (parse_in);
+ mkdeps *deps = cpp_get_deps (parse_in);
for (size_t i = 0; i < deferred_count; i++)
{
diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c
index 9af713d..9fee84b 100644
--- a/gcc/c-family/c-pragma.c
+++ b/gcc/c-family/c-pragma.c
@@ -1318,6 +1318,7 @@ static const struct omp_pragma_def omp_pragmas_simd[] = {
{ "declare", PRAGMA_OMP_DECLARE },
{ "distribute", PRAGMA_OMP_DISTRIBUTE },
{ "for", PRAGMA_OMP_FOR },
+ { "loop", PRAGMA_OMP_LOOP },
{ "ordered", PRAGMA_OMP_ORDERED },
{ "parallel", PRAGMA_OMP_PARALLEL },
{ "scan", PRAGMA_OMP_SCAN },
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index ed65036..e8a509f 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -52,6 +52,7 @@ enum pragma_kind {
PRAGMA_OMP_END_DECLARE_TARGET,
PRAGMA_OMP_FLUSH,
PRAGMA_OMP_FOR,
+ PRAGMA_OMP_LOOP,
PRAGMA_OMP_MASTER,
PRAGMA_OMP_ORDERED,
PRAGMA_OMP_PARALLEL,
@@ -84,6 +85,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_NONE = 0,
PRAGMA_OMP_CLAUSE_ALIGNED,
+ PRAGMA_OMP_CLAUSE_BIND,
PRAGMA_OMP_CLAUSE_COLLAPSE,
PRAGMA_OMP_CLAUSE_COPYIN,
PRAGMA_OMP_CLAUSE_COPYPRIVATE,
@@ -114,6 +116,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_NUM_TASKS,
PRAGMA_OMP_CLAUSE_NUM_TEAMS,
PRAGMA_OMP_CLAUSE_NUM_THREADS,
+ PRAGMA_OMP_CLAUSE_ORDER,
PRAGMA_OMP_CLAUSE_ORDERED,
PRAGMA_OMP_CLAUSE_PARALLEL,
PRAGMA_OMP_CLAUSE_PRIORITY,
diff --git a/gcc/c-family/c-pretty-print.h b/gcc/c-family/c-pretty-print.h
index 6084dcf..8d69620 100644
--- a/gcc/c-family/c-pretty-print.h
+++ b/gcc/c-family/c-pretty-print.h
@@ -36,7 +36,7 @@ enum pp_c_pretty_print_flags
/* The data type used to bundle information necessary for pretty-printing
a C or C++ entity. */
-struct c_pretty_printer;
+class c_pretty_printer;
/* The type of a C pretty-printer 'member' function. */
typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
@@ -47,8 +47,9 @@ typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
facilities provided here. A derived pretty-printer can override
any function listed in the vtable below. See cp/cxx-pretty-print.h
and cp/cxx-pretty-print.c for an example of derivation. */
-struct c_pretty_printer : pretty_printer
+class c_pretty_printer : public pretty_printer
{
+public:
c_pretty_printer ();
// Format string, possibly translated.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 271ed4ba..0bb1d4c 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,63 @@
+2019-07-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/83518
+ * gimple-parser.c (c_parser_parse_gimple_body): When we have
+ a CFG also rebuild cgraph edges.
+
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_omp_clause_name): Handle bind clause.
+ (c_parser_omp_clause_bind): New function.
+ (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_BIND.
+ (OMP_LOOP_CLAUSE_MASK): Define.
+ (c_parser_omp_loop): New function.
+ (c_parser_omp_parallel, c_parser_omp_teams): Handle parsing of
+ loop combined with parallel or teams.
+ (c_parser_omp_construct): Handle PRAGMA_OMP_LOOP.
+ * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_BIND.
+
+2019-07-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR c/53633
+ * c-decl.c (finish_function): Check targetm.warn_func_return
+ before issuing a -Wreturn-type warning.
+
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
+
+ * gimple-parser.c (c_parser_gimple_try_stmt): New.
+ (c_parser_compound_statement): Call it.
+
+2019-07-12 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_omp_clause_name): Handle order clause.
+ (c_parser_omp_clause_order): New function.
+ (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ORDER.
+ (OMP_SIMD_CLAUSE_MASK, OMP_FOR_CLAUSE_MASK): Add
+ PRAGMA_OMP_CLAUSE_ORDER.
+ * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_ORDER.
+
+2019-07-10 Richard Biener <rguenther@suse.de>
+
+ * gimple-parser.c (c_parser_gimple_postfix_expression): Support
+ _Literal (int *) &x for address literals.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * c-decl.c (xref_tag): Change class-key of PODs to struct and others
+ to class.
+ (field_decl_cmp): Same.
+ * c-parser.c (c_parser_struct_or_union_specifier): Same.
+ * c-tree.h: Same.
+ * gimple-parser.c (c_parser_gimple_compound_statement): Same.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * c-decl.c: Change class-key from class to struct and vice versa
+ to match convention and avoid -Wclass-is-pod and -Wstruct-no-pod.
+ * gimple-parser.c: Same.
+
2019-07-01 Richard Biener <rguenther@suse.de>
* gimple-parser.c (c_parser_gimple_postfix_expression): Handle
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index cb2f49f..0d107ad 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -574,8 +574,9 @@ typedef struct c_binding *c_binding_ptr;
/* Information that we keep for a struct or union while it is being
parsed. */
-struct c_struct_parse_info
+class c_struct_parse_info
{
+public:
/* If warn_cxx_compat, a list of types defined within this
struct. */
auto_vec<tree> struct_types;
@@ -591,7 +592,7 @@ struct c_struct_parse_info
/* Information for the struct or union currently being parsed, or
NULL if not parsing a struct or union. */
-static struct c_struct_parse_info *struct_parse_info;
+static class c_struct_parse_info *struct_parse_info;
/* Forward declarations. */
static tree lookup_name_in_scope (tree, struct c_scope *);
@@ -7767,7 +7768,7 @@ xref_tag (enum tree_code code, tree name)
tree
start_struct (location_t loc, enum tree_code code, tree name,
- struct c_struct_parse_info **enclosing_struct_parse_info)
+ class c_struct_parse_info **enclosing_struct_parse_info)
{
/* If there is already a tag defined at this scope
(as a forward reference), just return it. */
@@ -8182,7 +8183,7 @@ field_decl_cmp (const void *x_p, const void *y_p)
tree
finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
- struct c_struct_parse_info *enclosing_struct_parse_info)
+ class c_struct_parse_info *enclosing_struct_parse_info)
{
tree x;
bool toplevel = file_scope == current_scope;
@@ -9686,6 +9687,7 @@ finish_function (void)
/* Normally, with -Wreturn-type, flow will complain, but we might
optimize out static functions. */
&& !TREE_PUBLIC (fndecl)
+ && targetm.warn_func_return (fndecl)
&& warning (OPT_Wreturn_type,
"no return statement in function returning non-void"))
TREE_NO_WARNING (fndecl) = 1;
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 9850872..6721049 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -3145,7 +3145,7 @@ c_parser_struct_or_union_specifier (c_parser *parser)
{
/* Parse a struct or union definition. Start the scope of the
tag before parsing components. */
- struct c_struct_parse_info *struct_info;
+ class c_struct_parse_info *struct_info;
tree type = start_struct (struct_loc, code, ident, &struct_info);
tree postfix_attrs;
/* We chain the components in reverse order, then put them in
@@ -11688,6 +11688,10 @@ c_parser_omp_clause_name (c_parser *parser)
else if (!strcmp ("async", p))
result = PRAGMA_OACC_CLAUSE_ASYNC;
break;
+ case 'b':
+ if (!strcmp ("bind", p))
+ result = PRAGMA_OMP_CLAUSE_BIND;
+ break;
case 'c':
if (!strcmp ("collapse", p))
result = PRAGMA_OMP_CLAUSE_COLLAPSE;
@@ -11789,6 +11793,8 @@ c_parser_omp_clause_name (c_parser *parser)
case 'o':
if (!strcmp ("ordered", p))
result = PRAGMA_OMP_CLAUSE_ORDERED;
+ else if (!strcmp ("order", p))
+ result = PRAGMA_OMP_CLAUSE_ORDER;
break;
case 'p':
if (!strcmp ("parallel", p))
@@ -13467,6 +13473,83 @@ c_parser_oacc_clause_wait (c_parser *parser, tree list)
return list;
}
+
+/* OpenMP 5.0:
+ order ( concurrent ) */
+
+static tree
+c_parser_omp_clause_order (c_parser *parser, tree list)
+{
+ location_t loc = c_parser_peek_token (parser)->location;
+ tree c;
+ const char *p;
+
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+ if (!c_parser_next_token_is (parser, CPP_NAME))
+ {
+ c_parser_error (parser, "expected %<concurrent%>");
+ goto out_err;
+ }
+ p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "concurrent") != 0)
+ {
+ c_parser_error (parser, "expected %<concurrent%>");
+ goto out_err;
+ }
+ c_parser_consume_token (parser);
+ parens.skip_until_found_close (parser);
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */
+ c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ out_err:
+ parens.skip_until_found_close (parser);
+ return list;
+}
+
+
+/* OpenMP 5.0:
+ bind ( teams | parallel | thread ) */
+
+static tree
+c_parser_omp_clause_bind (c_parser *parser, tree list)
+{
+ location_t loc = c_parser_peek_token (parser)->location;
+ tree c;
+ const char *p;
+ enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
+
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+ if (!c_parser_next_token_is (parser, CPP_NAME))
+ {
+ invalid:
+ c_parser_error (parser,
+ "expected %<teams%>, %<parallel%> or %<thread%>");
+ parens.skip_until_found_close (parser);
+ return list;
+ }
+ p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "teams") == 0)
+ kind = OMP_CLAUSE_BIND_TEAMS;
+ else if (strcmp (p, "parallel") == 0)
+ kind = OMP_CLAUSE_BIND_PARALLEL;
+ else if (strcmp (p, "thread") != 0)
+ goto invalid;
+ c_parser_consume_token (parser);
+ parens.skip_until_found_close (parser);
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
+ c = build_omp_clause (loc, OMP_CLAUSE_BIND);
+ OMP_CLAUSE_BIND_KIND (c) = kind;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+}
+
+
/* OpenMP 2.5:
ordered
@@ -15026,6 +15109,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
switch (c_kind)
{
+ case PRAGMA_OMP_CLAUSE_BIND:
+ clauses = c_parser_omp_clause_bind (parser, clauses);
+ c_name = "bind";
+ break;
case PRAGMA_OMP_CLAUSE_COLLAPSE:
clauses = c_parser_omp_clause_collapse (parser, clauses);
c_name = "collapse";
@@ -15092,6 +15179,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
clauses = c_parser_omp_clause_num_threads (parser, clauses);
c_name = "num_threads";
break;
+ case PRAGMA_OMP_CLAUSE_ORDER:
+ clauses = c_parser_omp_clause_order (parser, clauses);
+ c_name = "order";
+ break;
case PRAGMA_OMP_CLAUSE_ORDERED:
clauses = c_parser_omp_clause_ordered (parser, clauses);
c_name = "ordered";
@@ -17204,6 +17295,46 @@ omp_split_clauses (location_t loc, enum tree_code code,
cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
}
+/* OpenMP 5.0:
+ #pragma omp loop loop-clause[optseq] new-line
+ for-loop
+
+ LOC is the location of the #pragma token.
+*/
+
+#define OMP_LOOP_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
+
+static tree
+c_parser_omp_loop (location_t loc, c_parser *parser,
+ char *p_name, omp_clause_mask mask, tree *cclauses,
+ bool *if_p)
+{
+ tree block, clauses, ret;
+
+ strcat (p_name, " loop");
+ mask |= OMP_LOOP_CLAUSE_MASK;
+
+ clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
+ if (cclauses)
+ {
+ omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
+ }
+
+ block = c_begin_compound_stmt (true);
+ ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
+ block = c_end_compound_stmt (loc, block, true);
+ add_stmt (block);
+
+ return ret;
+}
+
/* OpenMP 4.0:
#pragma omp simd simd-clause[optseq] new-line
for-loop
@@ -17221,7 +17352,8 @@ omp_split_clauses (location_t loc, enum tree_code code,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
static tree
c_parser_omp_simd (location_t loc, c_parser *parser,
@@ -17277,7 +17409,8 @@ c_parser_omp_simd (location_t loc, c_parser *parser,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
static tree
c_parser_omp_for (location_t loc, c_parser *parser,
@@ -17667,10 +17800,10 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
c_parser_skip_to_pragma_eol (parser);
return NULL_TREE;
}
- else if (cclauses == NULL && c_parser_next_token_is (parser, CPP_NAME))
+ else if (c_parser_next_token_is (parser, CPP_NAME))
{
const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
- if (strcmp (p, "master") == 0)
+ if (cclauses == NULL && strcmp (p, "master") == 0)
{
tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
cclauses = cclauses_buf;
@@ -17690,12 +17823,34 @@ c_parser_omp_parallel (location_t loc, c_parser *parser,
return ret;
return stmt;
}
+ else if (strcmp (p, "loop") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ c_parser_consume_token (parser);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
+ if_p);
+ block = c_begin_omp_parallel ();
+ tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
+ if_p);
+ stmt
+ = c_finish_omp_parallel (loc,
+ cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+ block);
+ if (ret == NULL_TREE)
+ return ret;
+ OMP_PARALLEL_COMBINED (stmt) = 1;
+ return stmt;
+ }
else if (!flag_openmp) /* flag_openmp_simd */
{
c_parser_skip_to_pragma_eol (parser, false);
return NULL_TREE;
}
- else if (strcmp (p, "sections") == 0)
+ else if (cclauses == NULL && strcmp (p, "sections") == 0)
{
tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
cclauses = cclauses_buf;
@@ -18075,6 +18230,30 @@ c_parser_omp_teams (location_t loc, c_parser *parser,
SET_EXPR_LOCATION (ret, loc);
return add_stmt (ret);
}
+ else if (strcmp (p, "loop") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ c_parser_consume_token (parser);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
+ if_p);
+ block = c_begin_omp_parallel ();
+ ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
+ block = c_end_compound_stmt (loc, block, true);
+ if (ret == NULL)
+ return ret;
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+ ret = make_node (OMP_TEAMS);
+ TREE_TYPE (ret) = void_type_node;
+ OMP_TEAMS_CLAUSES (ret) = clauses;
+ OMP_TEAMS_BODY (ret) = block;
+ OMP_TEAMS_COMBINED (ret) = 1;
+ SET_EXPR_LOCATION (ret, loc);
+ return add_stmt (ret);
+ }
}
if (!flag_openmp) /* flag_openmp_simd */
{
@@ -19624,6 +19803,10 @@ c_parser_omp_construct (c_parser *parser, bool *if_p)
strcpy (p_name, "#pragma omp");
stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
break;
+ case PRAGMA_OMP_LOOP:
+ strcpy (p_name, "#pragma omp");
+ stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
+ break;
case PRAGMA_OMP_MASTER:
strcpy (p_name, "#pragma omp");
stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p);
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 346f46a..dae2979 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -525,7 +525,7 @@ extern void gen_aux_info_record (tree, int, int, int);
/* in c-decl.c */
struct c_spot_bindings;
-struct c_struct_parse_info;
+class c_struct_parse_info;
extern struct obstack parser_obstack;
extern tree c_break_label;
extern tree c_cont_label;
@@ -562,7 +562,7 @@ extern void finish_decl (tree, location_t, tree, tree, tree);
extern tree finish_enum (tree, tree, tree);
extern void finish_function (void);
extern tree finish_struct (location_t, tree, tree, tree,
- struct c_struct_parse_info *);
+ class c_struct_parse_info *);
extern struct c_arg_info *build_arg_info (void);
extern struct c_arg_info *get_parm_info (bool, tree);
extern tree grokfield (location_t, struct c_declarator *,
@@ -586,7 +586,7 @@ extern bool start_function (struct c_declspecs *, struct c_declarator *, tree);
extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool,
tree);
extern tree start_struct (location_t, enum tree_code, tree,
- struct c_struct_parse_info **);
+ class c_struct_parse_info **);
extern void store_parm_decls (void);
extern void store_parm_decls_from (struct c_arg_info *);
extern void temp_store_parm_decls (tree, tree);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 6419ca9..9a1a910 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -13667,6 +13667,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
tree last_iterators = NULL_TREE;
bool last_iterators_remove = false;
tree *nogroup_seen = NULL;
+ tree *order_clause = NULL;
/* 1 if normal/task reduction has been seen, -1 if inscan reduction
has been seen, -2 if mixed inscan/normal reduction diagnosed. */
int reduction_seen = 0;
@@ -14631,6 +14632,25 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
pc = &OMP_CLAUSE_CHAIN (c);
continue;
+ case OMP_CLAUSE_ORDER:
+ if (ordered_clause)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<order%> clause must not be used together "
+ "with %<ordered%>");
+ remove = true;
+ break;
+ }
+ else if (order_clause)
+ {
+ /* Silently remove duplicates. */
+ remove = true;
+ break;
+ }
+ order_clause = pc;
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
+
case OMP_CLAUSE_IF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_NUM_TEAMS:
@@ -14654,6 +14674,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_HINT:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_NUM_GANGS:
case OMP_CLAUSE_NUM_WORKERS:
case OMP_CLAUSE_VECTOR_LENGTH:
@@ -14683,6 +14704,14 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_ORDERED:
ordered_clause = c;
+ if (order_clause)
+ {
+ error_at (OMP_CLAUSE_LOCATION (*order_clause),
+ "%<order%> clause must not be used together "
+ "with %<ordered%>");
+ *order_clause = OMP_CLAUSE_CHAIN (*order_clause);
+ order_clause = NULL;
+ }
pc = &OMP_CLAUSE_CHAIN (c);
continue;
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index b2b364c..3f57599 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -68,8 +68,9 @@ along with GCC; see the file COPYING3. If not see
/* GIMPLE parser state. */
-struct gimple_parser
+class gimple_parser
{
+public:
gimple_parser (c_parser *p) : parser (p), edges(), current_bb(NULL) {}
/* c_parser is not visible here, use composition and fake inheritance
via a conversion operator. */
@@ -77,8 +78,9 @@ struct gimple_parser
c_parser *parser;
/* CFG build state. */
- struct gimple_parser_edge
+ class gimple_parser_edge
{
+ public:
int src;
int dest;
int flags;
@@ -115,6 +117,7 @@ static struct c_expr c_parser_gimple_postfix_expression_after_primary
static void c_parser_gimple_declaration (gimple_parser &);
static void c_parser_gimple_goto_stmt (gimple_parser &, location_t,
tree, gimple_seq *);
+static void c_parser_gimple_try_stmt (gimple_parser &, gimple_seq *);
static void c_parser_gimple_if_stmt (gimple_parser &, gimple_seq *);
static void c_parser_gimple_switch_stmt (gimple_parser &, gimple_seq *);
static void c_parser_gimple_return_stmt (gimple_parser &, gimple_seq *);
@@ -353,6 +356,8 @@ c_parser_parse_gimple_body (c_parser *cparser, char *gimple_pass,
gcov_type t = PARAM_VALUE (PARAM_GIMPLE_FE_COMPUTED_HOT_BB_THRESHOLD);
set_hot_bb_threshold (t);
update_max_bb_count ();
+ cgraph_node::get_create (cfun->decl);
+ cgraph_edge::rebuild_edges ();
}
dump_function (TDI_gimple, current_function_decl);
}
@@ -405,6 +410,9 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
case CPP_KEYWORD:
switch (c_parser_peek_token (parser)->keyword)
{
+ case RID_AT_TRY:
+ c_parser_gimple_try_stmt (parser, seq);
+ break;
case RID_IF:
c_parser_gimple_if_stmt (parser, seq);
break;
@@ -446,6 +454,14 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
c_parser_gimple_label (parser, seq);
break;
}
+ if (c_parser_next_token_is (parser, CPP_NAME)
+ && c_parser_peek_token (parser)->id_kind == C_ID_ID
+ && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
+ "try") == 0)
+ {
+ c_parser_gimple_try_stmt (parser, seq);
+ break;
+ }
/* Basic block specification.
__BB (index, ...) */
if ((cfun->curr_properties & PROP_cfg)
@@ -583,7 +599,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
profile_probability::always ());
/* We leave the proper setting to fixup. */
- struct loop *loop_father = loops_for_fn (cfun)->tree_root;
+ class loop *loop_father = loops_for_fn (cfun)->tree_root;
/* If the new block is a loop header, allocate a loop
struct. Fixup will take care of proper placement within
the loop tree. */
@@ -596,7 +612,7 @@ c_parser_gimple_compound_statement (gimple_parser &parser, gimple_seq *seq)
}
else
{
- struct loop *loop = alloc_loop ();
+ class loop *loop = alloc_loop ();
loop->num = is_loop_header_of;
loop->header = bb;
vec_safe_grow_cleared (loops_for_fn (cfun)->larray,
@@ -1604,8 +1620,10 @@ c_parser_gimple_postfix_expression (gimple_parser &parser)
tree val = c_parser_gimple_postfix_expression (parser).value;
if (! val
|| val == error_mark_node
- || ! CONSTANT_CLASS_P (val)
- || (addr_p && TREE_CODE (val) != STRING_CST))
+ || (!CONSTANT_CLASS_P (val)
+ && !(addr_p
+ && (TREE_CODE (val) == STRING_CST
+ || DECL_P (val)))))
{
c_parser_error (parser, "invalid _Literal");
return expr;
@@ -2088,6 +2106,55 @@ c_parser_gimple_paren_condition (gimple_parser &parser)
return cond;
}
+/* Parse gimple try statement.
+
+ try-statement:
+ try { ... } finally { ... }
+ try { ... } finally { ... } else { ... }
+
+ This could support try/catch as well, but it's not implemented yet.
+ */
+
+static void
+c_parser_gimple_try_stmt (gimple_parser &parser, gimple_seq *seq)
+{
+ gimple_seq tryseq = NULL;
+ c_parser_consume_token (parser);
+ c_parser_gimple_compound_statement (parser, &tryseq);
+
+ if ((c_parser_next_token_is (parser, CPP_KEYWORD)
+ && c_parser_peek_token (parser)->keyword == RID_AT_FINALLY)
+ || (c_parser_next_token_is (parser, CPP_NAME)
+ && c_parser_peek_token (parser)->id_kind == C_ID_ID
+ && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
+ "finally") == 0))
+ {
+ gimple_seq finseq = NULL;
+ c_parser_consume_token (parser);
+ c_parser_gimple_compound_statement (parser, &finseq);
+
+ if (c_parser_next_token_is (parser, CPP_KEYWORD)
+ && c_parser_peek_token (parser)->keyword == RID_ELSE)
+ {
+ gimple_seq elsseq = NULL;
+ c_parser_consume_token (parser);
+ c_parser_gimple_compound_statement (parser, &elsseq);
+
+ geh_else *stmt = gimple_build_eh_else (finseq, elsseq);
+ finseq = NULL;
+ gimple_seq_add_stmt_without_update (&finseq, stmt);
+ }
+
+ gtry *stmt = gimple_build_try (tryseq, finseq, GIMPLE_TRY_FINALLY);
+ gimple_seq_add_stmt_without_update (seq, stmt);
+ }
+ else if (c_parser_next_token_is (parser, CPP_KEYWORD)
+ && c_parser_peek_token (parser)->keyword == RID_AT_CATCH)
+ c_parser_error (parser, "%<catch%> is not supported");
+ else
+ c_parser_error (parser, "expected %<finally%> or %<catch%>");
+}
+
/* Parse gimple if-else statement.
if-statement:
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index 9ff470c..7c1de89 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -88,11 +88,11 @@ static void mark_set_regs (rtx, const_rtx, void *);
static void mark_referenced_regs (rtx *, refmarker_fn *mark, void *mark_arg);
static refmarker_fn mark_reg_as_referenced;
static refmarker_fn replace_reg_with_saved_mem;
-static int insert_save (struct insn_chain *, int, HARD_REG_SET *,
+static int insert_save (class insn_chain *, int, HARD_REG_SET *,
machine_mode *);
-static int insert_restore (struct insn_chain *, int, int, int,
+static int insert_restore (class insn_chain *, int, int, int,
machine_mode *);
-static struct insn_chain *insert_one_insn (struct insn_chain *, int, int,
+static class insn_chain *insert_one_insn (class insn_chain *, int, int,
rtx);
static void add_stored_regs (rtx, const_rtx, void *);
@@ -419,7 +419,7 @@ setup_save_areas (void)
HARD_REG_SET hard_regs_used;
struct saved_hard_reg *saved_reg;
rtx_insn *insn;
- struct insn_chain *chain, *next;
+ class insn_chain *chain, *next;
unsigned int regno;
HARD_REG_SET hard_regs_to_save, used_regs, this_insn_sets;
reg_set_iterator rsi;
@@ -744,7 +744,7 @@ setup_save_areas (void)
void
save_call_clobbered_regs (void)
{
- struct insn_chain *chain, *next, *last = NULL;
+ class insn_chain *chain, *next, *last = NULL;
machine_mode save_mode [FIRST_PSEUDO_REGISTER];
/* Computed in mark_set_regs, holds all registers set by the current
@@ -1174,14 +1174,14 @@ replace_reg_with_saved_mem (rtx *loc,
Return the extra number of registers saved. */
static int
-insert_restore (struct insn_chain *chain, int before_p, int regno,
+insert_restore (class insn_chain *chain, int before_p, int regno,
int maxrestore, machine_mode *save_mode)
{
int i, k;
rtx pat = NULL_RTX;
int code;
unsigned int numregs = 0;
- struct insn_chain *new_chain;
+ class insn_chain *new_chain;
rtx mem;
/* A common failure mode if register status is not correct in the
@@ -1253,7 +1253,7 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
/* Like insert_restore above, but save registers instead. */
static int
-insert_save (struct insn_chain *chain, int regno,
+insert_save (class insn_chain *chain, int regno,
HARD_REG_SET *to_save, machine_mode *save_mode)
{
int i;
@@ -1261,7 +1261,7 @@ insert_save (struct insn_chain *chain, int regno,
rtx pat = NULL_RTX;
int code;
unsigned int numregs = 0;
- struct insn_chain *new_chain;
+ class insn_chain *new_chain;
rtx mem;
/* A common failure mode if register status is not correct in the
@@ -1351,11 +1351,11 @@ add_used_regs (rtx *loc, void *data)
}
/* Emit a new caller-save insn and set the code. */
-static struct insn_chain *
-insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
+static class insn_chain *
+insert_one_insn (class insn_chain *chain, int before_p, int code, rtx pat)
{
rtx_insn *insn = chain->insn;
- struct insn_chain *new_chain;
+ class insn_chain *new_chain;
/* If INSN references CC0, put our insns in front of the insn that sets
CC0. This is always safe, since the only way we could be passed an
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 983115e..4757bab 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -1145,7 +1145,7 @@ get_bb_copy (basic_block bb)
initialized so passes not needing this don't need to care. */
void
-set_loop_copy (struct loop *loop, struct loop *copy)
+set_loop_copy (class loop *loop, class loop *copy)
{
if (!copy)
copy_original_table_clear (loop_copy, loop->num);
@@ -1155,8 +1155,8 @@ set_loop_copy (struct loop *loop, struct loop *copy)
/* Get the copy of LOOP. */
-struct loop *
-get_loop_copy (struct loop *loop)
+class loop *
+get_loop_copy (class loop *loop)
{
struct htab_bb_copy_original_entry *entry;
struct htab_bb_copy_original_entry key;
diff --git a/gcc/cfg.h b/gcc/cfg.h
index b6f95bd..12cd760 100644
--- a/gcc/cfg.h
+++ b/gcc/cfg.h
@@ -122,8 +122,8 @@ extern void set_bb_original (basic_block, basic_block);
extern basic_block get_bb_original (basic_block);
extern void set_bb_copy (basic_block, basic_block);
extern basic_block get_bb_copy (basic_block);
-void set_loop_copy (struct loop *, struct loop *);
-struct loop *get_loop_copy (struct loop *);
+void set_loop_copy (class loop *, class loop *);
+class loop *get_loop_copy (class loop *);
/* Generic RAII class to allocate a bit from storage of integer type T.
The allocated bit is accessible as mask with the single bit set
diff --git a/gcc/cfganal.h b/gcc/cfganal.h
index ba889e2..c928fea 100644
--- a/gcc/cfganal.h
+++ b/gcc/cfganal.h
@@ -72,8 +72,8 @@ extern int rev_post_order_and_mark_dfs_back_seme (struct function *, edge,
extern int dfs_enumerate_from (basic_block, int,
bool (*)(const_basic_block, const void *),
basic_block *, int, const void *);
-extern void compute_dominance_frontiers (struct bitmap_head *);
-extern bitmap compute_idf (bitmap, struct bitmap_head *);
+extern void compute_dominance_frontiers (class bitmap_head *);
+extern bitmap compute_idf (bitmap, class bitmap_head *);
extern void bitmap_intersection_of_succs (sbitmap, sbitmap *, basic_block);
extern void bitmap_intersection_of_preds (sbitmap, sbitmap *, basic_block);
extern void bitmap_union_of_succs (sbitmap, sbitmap *, basic_block);
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 992912c..b930763 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "dce.h"
#include "dbgcnt.h"
#include "rtl-iter.h"
+#include "regs.h"
#define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK)
@@ -1224,6 +1225,14 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2)
}
}
}
+
+ HARD_REG_SET i1_used, i2_used;
+
+ get_call_reg_set_usage (i1, &i1_used, call_used_reg_set);
+ get_call_reg_set_usage (i2, &i2_used, call_used_reg_set);
+
+ if (!hard_reg_set_equal_p (i1_used, i2_used))
+ return dir_none;
}
/* If both i1 and i2 are frame related, verify all the CFA notes
@@ -3184,7 +3193,10 @@ cleanup_cfg (int mode)
&& !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
break;
if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occurred)
- run_fast_dce ();
+ {
+ run_fast_dce ();
+ mode &= ~CLEANUP_FORCE_FAST_DCE;
+ }
}
else
break;
@@ -3193,6 +3205,9 @@ cleanup_cfg (int mode)
if (mode & CLEANUP_CROSSJUMP)
remove_fake_exit_edges ();
+ if (mode & CLEANUP_FORCE_FAST_DCE)
+ run_fast_dce ();
+
/* Don't call delete_dead_jumptables in cfglayout mode, because
that function assumes that jump tables are in the insns stream.
But we also don't _have_ to delete dead jumptables in cfglayout
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 1e84d2c..33af991 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -305,8 +305,9 @@ set_rtl (tree t, rtx x)
/* This structure holds data relevant to one variable that will be
placed in a stack slot. */
-struct stack_var
+class stack_var
{
+public:
/* The Variable. */
tree decl;
@@ -331,7 +332,7 @@ struct stack_var
#define EOC ((size_t)-1)
/* We have an array of such objects while deciding allocation. */
-static struct stack_var *stack_vars;
+static class stack_var *stack_vars;
static size_t stack_vars_alloc;
static size_t stack_vars_num;
static hash_map<tree, size_t> *decl_to_stack_part;
@@ -425,7 +426,7 @@ alloc_stack_frame_space (poly_int64 size, unsigned HOST_WIDE_INT align)
static void
add_stack_var (tree decl, bool really_expand)
{
- struct stack_var *v;
+ class stack_var *v;
if (stack_vars_num >= stack_vars_alloc)
{
@@ -434,7 +435,7 @@ add_stack_var (tree decl, bool really_expand)
else
stack_vars_alloc = 32;
stack_vars
- = XRESIZEVEC (struct stack_var, stack_vars, stack_vars_alloc);
+ = XRESIZEVEC (class stack_var, stack_vars, stack_vars_alloc);
}
if (!decl_to_stack_part)
decl_to_stack_part = new hash_map<tree, size_t>;
@@ -473,8 +474,8 @@ add_stack_var (tree decl, bool really_expand)
static void
add_stack_var_conflict (size_t x, size_t y)
{
- struct stack_var *a = &stack_vars[x];
- struct stack_var *b = &stack_vars[y];
+ class stack_var *a = &stack_vars[x];
+ class stack_var *b = &stack_vars[y];
if (x == y)
return;
if (!a->conflicts)
@@ -490,8 +491,8 @@ add_stack_var_conflict (size_t x, size_t y)
static bool
stack_var_conflict_p (size_t x, size_t y)
{
- struct stack_var *a = &stack_vars[x];
- struct stack_var *b = &stack_vars[y];
+ class stack_var *a = &stack_vars[x];
+ class stack_var *b = &stack_vars[y];
if (x == y)
return false;
/* Partitions containing an SSA name result from gimple registers
@@ -606,7 +607,7 @@ add_scope_conflicts_1 (basic_block bb, bitmap work, bool for_conflict)
unsigned i;
EXECUTE_IF_SET_IN_BITMAP (work, 0, i, bi)
{
- struct stack_var *a = &stack_vars[i];
+ class stack_var *a = &stack_vars[i];
if (!a->conflicts)
a->conflicts = BITMAP_ALLOC (&stack_var_bitmap_obstack);
bitmap_ior_into (a->conflicts, work);
@@ -852,7 +853,7 @@ update_alias_info_with_stack_vars (void)
static void
union_stack_vars (size_t a, size_t b)
{
- struct stack_var *vb = &stack_vars[b];
+ class stack_var *vb = &stack_vars[b];
bitmap_iterator bi;
unsigned u;
@@ -1021,8 +1022,9 @@ expand_one_stack_var_at (tree decl, rtx base, unsigned base_align,
set_rtl (decl, x);
}
-struct stack_vars_data
+class stack_vars_data
{
+public:
/* Vector of offset pairs, always end of some padding followed
by start of the padding that needs Address Sanitizer protection.
The vector is in reversed, highest offset pairs come first. */
@@ -1043,7 +1045,7 @@ struct stack_vars_data
with that location. */
static void
-expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
+expand_stack_vars (bool (*pred) (size_t), class stack_vars_data *data)
{
size_t si, i, j, n = stack_vars_num;
poly_uint64 large_size = 0, large_alloc = 0;
@@ -2230,7 +2232,7 @@ expand_used_vars (void)
/* Assign rtl to each variable based on these partitions. */
if (stack_vars_num > 0)
{
- struct stack_vars_data data;
+ class stack_vars_data data;
data.asan_base = NULL_RTX;
data.asan_alignb = 0;
@@ -3712,6 +3714,12 @@ expand_gimple_stmt_1 (gimple *stmt)
{
op0 = gimple_return_retval (as_a <greturn *> (stmt));
+ /* If a return doesn't have a location, it very likely represents
+ multiple user returns so we cannot let it inherit the location
+ of the last statement of the previous basic block in RTL. */
+ if (!gimple_has_location (stmt))
+ set_curr_insn_location (cfun->function_end_locus);
+
if (op0 && op0 != error_mark_node)
{
tree result = DECL_RESULT (current_function_decl);
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index 76183ec..7c00fc3 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -496,7 +496,7 @@ redirect_edge_and_branch_force (edge e, basic_block dest)
{
if (ret != NULL)
{
- struct loop *loop
+ class loop *loop
= find_common_loop (single_pred (ret)->loop_father,
single_succ (ret)->loop_father);
add_bb_to_loop (ret, loop);
@@ -604,7 +604,7 @@ delete_basic_block (basic_block bb)
if (current_loops != NULL)
{
- struct loop *loop = bb->loop_father;
+ class loop *loop = bb->loop_father;
/* If we remove the header or the latch of a loop, mark the loop for
removal. */
@@ -640,7 +640,7 @@ split_edge (edge e)
profile_count count = e->count ();
edge f;
bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
- struct loop *loop;
+ class loop *loop;
basic_block src = e->src, dest = e->dest;
if (!cfg_hooks->split_edge)
@@ -870,7 +870,7 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
edge e, fallthru;
edge_iterator ei;
basic_block dummy, jump;
- struct loop *loop, *ploop, *cloop;
+ class loop *loop, *ploop, *cloop;
if (!cfg_hooks->make_forwarder_block)
internal_error ("%s does not support make_forwarder_block",
@@ -1035,7 +1035,7 @@ force_nonfallthru (edge e)
{
basic_block pred = single_pred (ret);
basic_block succ = single_succ (ret);
- struct loop *loop
+ class loop *loop
= find_common_loop (pred->loop_father, succ->loop_father);
rescan_loop_exit (e, false, true);
add_bb_to_loop (ret, loop);
@@ -1118,8 +1118,8 @@ duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
of BB if the loop is not being copied. */
if (current_loops != NULL)
{
- struct loop *cloop = bb->loop_father;
- struct loop *copy = get_loop_copy (cloop);
+ class loop *cloop = bb->loop_father;
+ class loop *copy = get_loop_copy (cloop);
/* If we copied the loop header block but not the loop
we have created a loop with multiple entries. Ditch the loop,
add the new block to the outer loop and arrange for a fixup. */
@@ -1228,7 +1228,7 @@ lv_flush_pending_stmts (edge e)
a need to call the tree_duplicate_loop_to_header_edge rather
than duplicate_loop_to_header_edge when we are in tree mode. */
bool
-cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge e,
+cfg_hook_duplicate_loop_to_header_edge (class loop *loop, edge e,
unsigned int ndupl,
sbitmap wont_exit, edge orig,
vec<edge> *to_remove,
@@ -1336,7 +1336,7 @@ end:
void
copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
edge *edges, unsigned num_edges, edge *new_edges,
- struct loop *base, basic_block after, bool update_dominance)
+ class loop *base, basic_block after, bool update_dominance)
{
unsigned i, j;
basic_block bb, new_bb, dom_bb;
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
index e9385c9..627eff9 100644
--- a/gcc/cfghooks.h
+++ b/gcc/cfghooks.h
@@ -58,8 +58,9 @@ typedef int_hash <unsigned short, 0> dependence_hash;
/* Optional data for duplicate_block. */
-struct copy_bb_data
+class copy_bb_data
{
+public:
copy_bb_data() : dependence_map (NULL) {}
~copy_bb_data () { delete dependence_map; }
@@ -165,7 +166,7 @@ struct cfg_hooks
/* A hook for duplicating loop in CFG, currently this is used
in loop versioning. */
- bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *, edge,
+ bool (*cfg_hook_duplicate_loop_to_header_edge) (class loop *, edge,
unsigned, sbitmap,
edge, vec<edge> *,
int);
@@ -249,7 +250,7 @@ extern bool block_ends_with_condjump_p (const_basic_block bb);
extern int flow_call_edges_add (sbitmap);
extern void execute_on_growing_pred (edge);
extern void execute_on_shrinking_pred (edge);
-extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge,
+extern bool cfg_hook_duplicate_loop_to_header_edge (class loop *loop, edge,
unsigned int ndupl,
sbitmap wont_exit,
edge orig,
@@ -265,7 +266,7 @@ extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block,
extern bool can_copy_bbs_p (basic_block *, unsigned);
extern void copy_bbs (basic_block *, unsigned, basic_block *,
- edge *, unsigned, edge *, struct loop *,
+ edge *, unsigned, edge *, class loop *,
basic_block, bool);
void profile_record_check_consistency (profile_record *);
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index f64326b..4ad1f65 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -59,7 +59,7 @@ flow_loops_cfg_dump (FILE *file)
/* Return nonzero if the nodes of LOOP are a subset of OUTER. */
bool
-flow_loop_nested_p (const struct loop *outer, const struct loop *loop)
+flow_loop_nested_p (const class loop *outer, const class loop *loop)
{
unsigned odepth = loop_depth (outer);
@@ -70,8 +70,8 @@ flow_loop_nested_p (const struct loop *outer, const struct loop *loop)
/* Returns the loop such that LOOP is nested DEPTH (indexed from zero)
loops within LOOP. */
-struct loop *
-superloop_at_depth (struct loop *loop, unsigned depth)
+class loop *
+superloop_at_depth (class loop *loop, unsigned depth)
{
unsigned ldepth = loop_depth (loop);
@@ -86,7 +86,7 @@ superloop_at_depth (struct loop *loop, unsigned depth)
/* Returns the list of the latch edges of LOOP. */
static vec<edge>
-get_loop_latch_edges (const struct loop *loop)
+get_loop_latch_edges (const class loop *loop)
{
edge_iterator ei;
edge e;
@@ -105,8 +105,8 @@ get_loop_latch_edges (const struct loop *loop)
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
void
-flow_loop_dump (const struct loop *loop, FILE *file,
- void (*loop_dump_aux) (const struct loop *, FILE *, int),
+flow_loop_dump (const class loop *loop, FILE *file,
+ void (*loop_dump_aux) (const class loop *, FILE *, int),
int verbose)
{
basic_block *bbs;
@@ -160,9 +160,9 @@ flow_loop_dump (const struct loop *loop, FILE *file,
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
void
-flow_loops_dump (FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
+flow_loops_dump (FILE *file, void (*loop_dump_aux) (const class loop *, FILE *, int), int verbose)
{
- struct loop *loop;
+ class loop *loop;
if (!current_loops || ! file)
return;
@@ -181,7 +181,7 @@ flow_loops_dump (FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *,
/* Free data allocated for LOOP. */
void
-flow_loop_free (struct loop *loop)
+flow_loop_free (class loop *loop)
{
struct loop_exit *exit, *next;
@@ -229,7 +229,7 @@ flow_loops_free (struct loops *loops)
Return the number of nodes within the loop. */
int
-flow_loop_nodes_find (basic_block header, struct loop *loop)
+flow_loop_nodes_find (basic_block header, class loop *loop)
{
vec<basic_block> stack = vNULL;
int num_nodes = 1;
@@ -278,7 +278,7 @@ flow_loop_nodes_find (basic_block header, struct loop *loop)
superloop is FATHER. */
static void
-establish_preds (struct loop *loop, struct loop *father)
+establish_preds (class loop *loop, class loop *father)
{
loop_p ploop;
unsigned depth = loop_depth (father) + 1;
@@ -302,8 +302,8 @@ establish_preds (struct loop *loop, struct loop *father)
of FATHERs siblings. */
void
-flow_loop_tree_node_add (struct loop *father, struct loop *loop,
- struct loop *after)
+flow_loop_tree_node_add (class loop *father, class loop *loop,
+ class loop *after)
{
if (after)
{
@@ -322,9 +322,9 @@ flow_loop_tree_node_add (struct loop *father, struct loop *loop,
/* Remove LOOP from the loop hierarchy tree. */
void
-flow_loop_tree_node_remove (struct loop *loop)
+flow_loop_tree_node_remove (class loop *loop)
{
- struct loop *prev, *father;
+ class loop *prev, *father;
father = loop_outer (loop);
@@ -343,10 +343,10 @@ flow_loop_tree_node_remove (struct loop *loop)
/* Allocates and returns new loop structure. */
-struct loop *
+class loop *
alloc_loop (void)
{
- struct loop *loop = ggc_cleared_alloc<struct loop> ();
+ class loop *loop = ggc_cleared_alloc<class loop> ();
loop->exits = ggc_cleared_alloc<loop_exit> ();
loop->exits->next = loop->exits->prev = loop->exits;
@@ -365,7 +365,7 @@ void
init_loops_structure (struct function *fn,
struct loops *loops, unsigned num_loops)
{
- struct loop *root;
+ class loop *root;
memset (loops, 0, sizeof *loops);
vec_alloc (loops->larray, num_loops);
@@ -460,7 +460,7 @@ flow_loops_find (struct loops *loops)
basic_block header = BASIC_BLOCK_FOR_FN (cfun, rc_order[b]);
if (bb_loop_header_p (header))
{
- struct loop *loop;
+ class loop *loop;
/* The current active loop tree has valid loop-fathers for
header blocks. */
@@ -503,7 +503,7 @@ flow_loops_find (struct loops *loops)
and assign basic-block ownership. */
for (i = 0; i < larray.length (); ++i)
{
- struct loop *loop = larray[i];
+ class loop *loop = larray[i];
basic_block header = loop->header;
edge_iterator ei;
edge e;
@@ -539,8 +539,8 @@ static int *sort_sibling_loops_cmp_rpo;
static int
sort_sibling_loops_cmp (const void *la_, const void *lb_)
{
- const struct loop *la = *(const struct loop * const *)la_;
- const struct loop *lb = *(const struct loop * const *)lb_;
+ const class loop *la = *(const class loop * const *)la_;
+ const class loop *lb = *(const class loop * const *)lb_;
return (sort_sibling_loops_cmp_rpo[la->header->index]
- sort_sibling_loops_cmp_rpo[lb->header->index]);
}
@@ -643,7 +643,7 @@ find_subloop_latch_edge_by_profile (vec<edge> latches)
another edge. */
static edge
-find_subloop_latch_edge_by_ivs (struct loop *loop ATTRIBUTE_UNUSED, vec<edge> latches)
+find_subloop_latch_edge_by_ivs (class loop *loop ATTRIBUTE_UNUSED, vec<edge> latches)
{
edge e, latch = latches[0];
unsigned i;
@@ -695,7 +695,7 @@ find_subloop_latch_edge_by_ivs (struct loop *loop ATTRIBUTE_UNUSED, vec<edge> la
returns NULL. */
static edge
-find_subloop_latch_edge (struct loop *loop)
+find_subloop_latch_edge (class loop *loop)
{
vec<edge> latches = get_loop_latch_edges (loop);
edge latch = NULL;
@@ -729,11 +729,11 @@ mfb_redirect_edges_in_set (edge e)
/* Creates a subloop of LOOP with latch edge LATCH. */
static void
-form_subloop (struct loop *loop, edge latch)
+form_subloop (class loop *loop, edge latch)
{
edge_iterator ei;
edge e, new_entry;
- struct loop *new_loop;
+ class loop *new_loop;
mfb_reis_set = new hash_set<edge>;
FOR_EACH_EDGE (e, ei, loop->header->preds)
@@ -759,7 +759,7 @@ form_subloop (struct loop *loop, edge latch)
a new latch of LOOP. */
static void
-merge_latch_edges (struct loop *loop)
+merge_latch_edges (class loop *loop)
{
vec<edge> latches = get_loop_latch_edges (loop);
edge latch, e;
@@ -792,7 +792,7 @@ merge_latch_edges (struct loop *loop)
loops with single latch edge. */
static void
-disambiguate_multiple_latches (struct loop *loop)
+disambiguate_multiple_latches (class loop *loop)
{
edge e;
@@ -836,7 +836,7 @@ disambiguate_multiple_latches (struct loop *loop)
void
disambiguate_loops_with_multiple_latches (void)
{
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, 0)
{
@@ -847,9 +847,9 @@ disambiguate_loops_with_multiple_latches (void)
/* Return nonzero if basic block BB belongs to LOOP. */
bool
-flow_bb_inside_loop_p (const struct loop *loop, const_basic_block bb)
+flow_bb_inside_loop_p (const class loop *loop, const_basic_block bb)
{
- struct loop *source_loop;
+ class loop *source_loop;
if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
|| bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
@@ -863,7 +863,7 @@ flow_bb_inside_loop_p (const struct loop *loop, const_basic_block bb)
static bool
glb_enum_p (const_basic_block bb, const void *glb_loop)
{
- const struct loop *const loop = (const struct loop *) glb_loop;
+ const class loop *const loop = (const class loop *) glb_loop;
return (bb != loop->header
&& dominated_by_p (CDI_DOMINATORS, bb, loop->header));
}
@@ -876,7 +876,7 @@ glb_enum_p (const_basic_block bb, const void *glb_loop)
returned. */
unsigned
-get_loop_body_with_size (const struct loop *loop, basic_block *body,
+get_loop_body_with_size (const class loop *loop, basic_block *body,
unsigned max_size)
{
return dfs_enumerate_from (loop->header, 1, glb_enum_p,
@@ -888,7 +888,7 @@ get_loop_body_with_size (const struct loop *loop, basic_block *body,
header != latch, latch is the 1-st block. */
basic_block *
-get_loop_body (const struct loop *loop)
+get_loop_body (const class loop *loop)
{
basic_block *body, bb;
unsigned tv = 0;
@@ -918,7 +918,7 @@ get_loop_body (const struct loop *loop)
array TOVISIT from index *TV. */
static void
-fill_sons_in_loop (const struct loop *loop, basic_block bb,
+fill_sons_in_loop (const class loop *loop, basic_block bb,
basic_block *tovisit, int *tv)
{
basic_block son, postpone = NULL;
@@ -948,7 +948,7 @@ fill_sons_in_loop (const struct loop *loop, basic_block bb,
the latch, then only blocks dominated by s are be after it. */
basic_block *
-get_loop_body_in_dom_order (const struct loop *loop)
+get_loop_body_in_dom_order (const class loop *loop)
{
basic_block *tovisit;
int tv;
@@ -970,7 +970,7 @@ get_loop_body_in_dom_order (const struct loop *loop)
/* Gets body of a LOOP sorted via provided BB_COMPARATOR. */
basic_block *
-get_loop_body_in_custom_order (const struct loop *loop,
+get_loop_body_in_custom_order (const class loop *loop,
int (*bb_comparator) (const void *, const void *))
{
basic_block *bbs = get_loop_body (loop);
@@ -983,7 +983,7 @@ get_loop_body_in_custom_order (const struct loop *loop,
/* Get body of a LOOP in breadth first sort order. */
basic_block *
-get_loop_body_in_bfs_order (const struct loop *loop)
+get_loop_body_in_bfs_order (const class loop *loop)
{
basic_block *blocks;
basic_block bb;
@@ -1069,7 +1069,7 @@ void
rescan_loop_exit (edge e, bool new_edge, bool removed)
{
struct loop_exit *exits = NULL, *exit;
- struct loop *aloop, *cloop;
+ class loop *aloop, *cloop;
if (!loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
return;
@@ -1190,7 +1190,7 @@ release_recorded_exits (function *fn)
/* Returns the list of the exit edges of a LOOP. */
vec<edge>
-get_loop_exit_edges (const struct loop *loop)
+get_loop_exit_edges (const class loop *loop)
{
vec<edge> edges = vNULL;
edge e;
@@ -1226,7 +1226,7 @@ get_loop_exit_edges (const struct loop *loop)
/* Counts the number of conditional branches inside LOOP. */
unsigned
-num_loop_branches (const struct loop *loop)
+num_loop_branches (const class loop *loop)
{
unsigned i, n;
basic_block * body;
@@ -1245,7 +1245,7 @@ num_loop_branches (const struct loop *loop)
/* Adds basic block BB to LOOP. */
void
-add_bb_to_loop (basic_block bb, struct loop *loop)
+add_bb_to_loop (basic_block bb, class loop *loop)
{
unsigned i;
loop_p ploop;
@@ -1273,7 +1273,7 @@ void
remove_bb_from_loops (basic_block bb)
{
unsigned i;
- struct loop *loop = bb->loop_father;
+ class loop *loop = bb->loop_father;
loop_p ploop;
edge_iterator ei;
edge e;
@@ -1295,8 +1295,8 @@ remove_bb_from_loops (basic_block bb)
}
/* Finds nearest common ancestor in loop tree for given loops. */
-struct loop *
-find_common_loop (struct loop *loop_s, struct loop *loop_d)
+class loop *
+find_common_loop (class loop *loop_s, class loop *loop_d)
{
unsigned sdepth, ddepth;
@@ -1322,7 +1322,7 @@ find_common_loop (struct loop *loop_s, struct loop *loop_d)
/* Removes LOOP from structures and frees its data. */
void
-delete_loop (struct loop *loop)
+delete_loop (class loop *loop)
{
/* Remove the loop from structure. */
flow_loop_tree_node_remove (loop);
@@ -1337,11 +1337,11 @@ delete_loop (struct loop *loop)
/* Cancels the LOOP; it must be innermost one. */
static void
-cancel_loop (struct loop *loop)
+cancel_loop (class loop *loop)
{
basic_block *bbs;
unsigned i;
- struct loop *outer = loop_outer (loop);
+ class loop *outer = loop_outer (loop);
gcc_assert (!loop->inner);
@@ -1356,7 +1356,7 @@ cancel_loop (struct loop *loop)
/* Cancels LOOP and all its subloops. */
void
-cancel_loop_tree (struct loop *loop)
+cancel_loop_tree (class loop *loop)
{
while (loop->inner)
cancel_loop_tree (loop->inner);
@@ -1385,7 +1385,7 @@ verify_loop_structure (void)
{
unsigned *sizes, i, j;
basic_block bb, *bbs;
- struct loop *loop;
+ class loop *loop;
int err = 0;
edge e;
unsigned num = number_of_loops (cfun);
@@ -1727,14 +1727,14 @@ verify_loop_structure (void)
/* Returns latch edge of LOOP. */
edge
-loop_latch_edge (const struct loop *loop)
+loop_latch_edge (const class loop *loop)
{
return find_edge (loop->latch, loop->header);
}
/* Returns preheader edge of LOOP. */
edge
-loop_preheader_edge (const struct loop *loop)
+loop_preheader_edge (const class loop *loop)
{
edge e;
edge_iterator ei;
@@ -1758,7 +1758,7 @@ loop_preheader_edge (const struct loop *loop)
/* Returns true if E is an exit of LOOP. */
bool
-loop_exit_edge_p (const struct loop *loop, const_edge e)
+loop_exit_edge_p (const class loop *loop, const_edge e)
{
return (flow_bb_inside_loop_p (loop, e->src)
&& !flow_bb_inside_loop_p (loop, e->dest));
@@ -1769,7 +1769,7 @@ loop_exit_edge_p (const struct loop *loop, const_edge e)
is returned always. */
edge
-single_exit (const struct loop *loop)
+single_exit (const class loop *loop)
{
struct loop_exit *exit = loop->exits->next;
@@ -1785,7 +1785,7 @@ single_exit (const struct loop *loop)
/* Returns true when BB has an incoming edge exiting LOOP. */
bool
-loop_exits_to_bb_p (struct loop *loop, basic_block bb)
+loop_exits_to_bb_p (class loop *loop, basic_block bb)
{
edge e;
edge_iterator ei;
@@ -1800,7 +1800,7 @@ loop_exits_to_bb_p (struct loop *loop, basic_block bb)
/* Returns true when BB has an outgoing edge exiting LOOP. */
bool
-loop_exits_from_bb_p (struct loop *loop, basic_block bb)
+loop_exits_from_bb_p (class loop *loop, basic_block bb)
{
edge e;
edge_iterator ei;
@@ -1815,10 +1815,10 @@ loop_exits_from_bb_p (struct loop *loop, basic_block bb)
/* Return location corresponding to the loop control condition if possible. */
dump_user_location_t
-get_loop_location (struct loop *loop)
+get_loop_location (class loop *loop)
{
rtx_insn *insn = NULL;
- struct niter_desc *desc = NULL;
+ class niter_desc *desc = NULL;
edge exit;
/* For a for or while loop, we would like to return the location
@@ -1869,7 +1869,7 @@ get_loop_location (struct loop *loop)
I_BOUND times. */
void
-record_niter_bound (struct loop *loop, const widest_int &i_bound,
+record_niter_bound (class loop *loop, const widest_int &i_bound,
bool realistic, bool upper)
{
/* Update the bounds only when there is no previous estimation, or when the
@@ -1920,7 +1920,7 @@ record_niter_bound (struct loop *loop, const widest_int &i_bound,
on the number of iterations of LOOP could not be derived, returns -1. */
HOST_WIDE_INT
-get_estimated_loop_iterations_int (struct loop *loop)
+get_estimated_loop_iterations_int (class loop *loop)
{
widest_int nit;
HOST_WIDE_INT hwi_nit;
@@ -1940,7 +1940,7 @@ get_estimated_loop_iterations_int (struct loop *loop)
the number of execution of the latch by one. */
HOST_WIDE_INT
-max_stmt_executions_int (struct loop *loop)
+max_stmt_executions_int (class loop *loop)
{
HOST_WIDE_INT nit = get_max_loop_iterations_int (loop);
HOST_WIDE_INT snit;
@@ -1959,7 +1959,7 @@ max_stmt_executions_int (struct loop *loop)
the number of execution of the latch by one. */
HOST_WIDE_INT
-likely_max_stmt_executions_int (struct loop *loop)
+likely_max_stmt_executions_int (class loop *loop)
{
HOST_WIDE_INT nit = get_likely_max_loop_iterations_int (loop);
HOST_WIDE_INT snit;
@@ -1978,7 +1978,7 @@ likely_max_stmt_executions_int (struct loop *loop)
returns true. */
bool
-get_estimated_loop_iterations (struct loop *loop, widest_int *nit)
+get_estimated_loop_iterations (class loop *loop, widest_int *nit)
{
/* Even if the bound is not recorded, possibly we can derrive one from
profile. */
@@ -2002,7 +2002,7 @@ get_estimated_loop_iterations (struct loop *loop, widest_int *nit)
false, otherwise returns true. */
bool
-get_max_loop_iterations (const struct loop *loop, widest_int *nit)
+get_max_loop_iterations (const class loop *loop, widest_int *nit)
{
if (!loop->any_upper_bound)
return false;
@@ -2016,7 +2016,7 @@ get_max_loop_iterations (const struct loop *loop, widest_int *nit)
on the number of iterations of LOOP could not be derived, returns -1. */
HOST_WIDE_INT
-get_max_loop_iterations_int (const struct loop *loop)
+get_max_loop_iterations_int (const class loop *loop)
{
widest_int nit;
HOST_WIDE_INT hwi_nit;
@@ -2036,7 +2036,7 @@ get_max_loop_iterations_int (const struct loop *loop)
false, otherwise returns true. */
bool
-get_likely_max_loop_iterations (struct loop *loop, widest_int *nit)
+get_likely_max_loop_iterations (class loop *loop, widest_int *nit)
{
if (!loop->any_likely_upper_bound)
return false;
@@ -2050,7 +2050,7 @@ get_likely_max_loop_iterations (struct loop *loop, widest_int *nit)
on the number of iterations of LOOP could not be derived, returns -1. */
HOST_WIDE_INT
-get_likely_max_loop_iterations_int (struct loop *loop)
+get_likely_max_loop_iterations_int (class loop *loop)
{
widest_int nit;
HOST_WIDE_INT hwi_nit;
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 2f8ab10..0b0154f 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -46,7 +46,8 @@ enum iv_extend_code
/* The structure describing a bound on number of iterations of a loop. */
-struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
+class GTY ((chain_next ("%h.next"))) nb_iter_bound {
+public:
/* The statement STMT is executed at most ... */
gimple *stmt;
@@ -65,7 +66,7 @@ struct GTY ((chain_next ("%h.next"))) nb_iter_bound {
bool is_exit;
/* The next bound in the list. */
- struct nb_iter_bound *next;
+ class nb_iter_bound *next;
};
/* Description of the loop exit. */
@@ -91,7 +92,7 @@ struct loop_exit_hasher : ggc_ptr_hash<loop_exit>
static void remove (loop_exit *);
};
-typedef struct loop *loop_p;
+typedef class loop *loop_p;
/* An integer estimation of the number of iterations. Estimate_state
describes what is the state of the estimation. */
@@ -113,7 +114,8 @@ struct GTY ((chain_next ("%h.next"))) control_iv {
};
/* Structure to hold information for each natural loop. */
-struct GTY ((chain_next ("%h.next"))) loop {
+class GTY ((chain_next ("%h.next"))) loop {
+public:
/* Index into loops array. Note indices will never be reused after loop
is destroyed. */
int num;
@@ -140,10 +142,10 @@ struct GTY ((chain_next ("%h.next"))) loop {
vec<loop_p, va_gc> *superloops;
/* The first inner (child) loop or NULL if innermost loop. */
- struct loop *inner;
+ class loop *inner;
/* Link to the next (sibling) loop. */
- struct loop *next;
+ class loop *next;
/* Auxiliary info specific to a pass. */
PTR GTY ((skip (""))) aux;
@@ -250,7 +252,7 @@ struct GTY ((chain_next ("%h.next"))) loop {
int orig_loop_num;
/* Upper bound on number of iterations of a loop. */
- struct nb_iter_bound *bounds;
+ class nb_iter_bound *bounds;
/* Non-overflow control ivs of a loop. */
struct control_iv *control_ivs;
@@ -259,7 +261,7 @@ struct GTY ((chain_next ("%h.next"))) loop {
struct loop_exit *exits;
/* Number of iteration analysis data for RTL. */
- struct niter_desc *simple_loop_desc;
+ class niter_desc *simple_loop_desc;
/* For sanity checking during loop fixup we record here the former
loop header for loops marked for removal. Note that this prevents
@@ -275,21 +277,21 @@ struct GTY ((chain_next ("%h.next"))) loop {
/* Set C to the LOOP constraint. */
static inline void
-loop_constraint_set (struct loop *loop, unsigned c)
+loop_constraint_set (class loop *loop, unsigned c)
{
loop->constraints |= c;
}
/* Clear C from the LOOP constraint. */
static inline void
-loop_constraint_clear (struct loop *loop, unsigned c)
+loop_constraint_clear (class loop *loop, unsigned c)
{
loop->constraints &= ~c;
}
/* Check if C is set in the LOOP constraint. */
static inline bool
-loop_constraint_set_p (struct loop *loop, unsigned c)
+loop_constraint_set_p (class loop *loop, unsigned c)
{
return (loop->constraints & c) == c;
}
@@ -325,7 +327,7 @@ struct GTY (()) loops {
hash_table<loop_exit_hasher> *GTY(()) exits;
/* Pointer to root of loop hierarchy tree. */
- struct loop *tree_root;
+ class loop *tree_root;
};
/* Loop recognition. */
@@ -335,12 +337,12 @@ extern struct loops *flow_loops_find (struct loops *);
extern void disambiguate_loops_with_multiple_latches (void);
extern void flow_loops_free (struct loops *);
extern void flow_loops_dump (FILE *,
- void (*)(const struct loop *, FILE *, int), int);
-extern void flow_loop_dump (const struct loop *, FILE *,
- void (*)(const struct loop *, FILE *, int), int);
-struct loop *alloc_loop (void);
-extern void flow_loop_free (struct loop *);
-int flow_loop_nodes_find (basic_block, struct loop *);
+ void (*)(const class loop *, FILE *, int), int);
+extern void flow_loop_dump (const class loop *, FILE *,
+ void (*)(const class loop *, FILE *, int), int);
+class loop *alloc_loop (void);
+extern void flow_loop_free (class loop *);
+int flow_loop_nodes_find (basic_block, class loop *);
unsigned fix_loop_structure (bitmap changed_bbs);
bool mark_irreducible_loops (void);
void release_recorded_exits (function *);
@@ -349,54 +351,54 @@ void rescan_loop_exit (edge, bool, bool);
void sort_sibling_loops (function *);
/* Loop data structure manipulation/querying. */
-extern void flow_loop_tree_node_add (struct loop *, struct loop *,
- struct loop * = NULL);
-extern void flow_loop_tree_node_remove (struct loop *);
-extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
-extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block);
-extern struct loop * find_common_loop (struct loop *, struct loop *);
-struct loop *superloop_at_depth (struct loop *, unsigned);
+extern void flow_loop_tree_node_add (class loop *, class loop *,
+ class loop * = NULL);
+extern void flow_loop_tree_node_remove (class loop *);
+extern bool flow_loop_nested_p (const class loop *, const class loop *);
+extern bool flow_bb_inside_loop_p (const class loop *, const_basic_block);
+extern class loop * find_common_loop (class loop *, class loop *);
+class loop *superloop_at_depth (class loop *, unsigned);
struct eni_weights;
-extern int num_loop_insns (const struct loop *);
-extern int average_num_loop_insns (const struct loop *);
-extern unsigned get_loop_level (const struct loop *);
-extern bool loop_exit_edge_p (const struct loop *, const_edge);
-extern bool loop_exits_to_bb_p (struct loop *, basic_block);
-extern bool loop_exits_from_bb_p (struct loop *, basic_block);
+extern int num_loop_insns (const class loop *);
+extern int average_num_loop_insns (const class loop *);
+extern unsigned get_loop_level (const class loop *);
+extern bool loop_exit_edge_p (const class loop *, const_edge);
+extern bool loop_exits_to_bb_p (class loop *, basic_block);
+extern bool loop_exits_from_bb_p (class loop *, basic_block);
extern void mark_loop_exit_edges (void);
-extern dump_user_location_t get_loop_location (struct loop *loop);
+extern dump_user_location_t get_loop_location (class loop *loop);
/* Loops & cfg manipulation. */
-extern basic_block *get_loop_body (const struct loop *);
-extern unsigned get_loop_body_with_size (const struct loop *, basic_block *,
+extern basic_block *get_loop_body (const class loop *);
+extern unsigned get_loop_body_with_size (const class loop *, basic_block *,
unsigned);
-extern basic_block *get_loop_body_in_dom_order (const struct loop *);
-extern basic_block *get_loop_body_in_bfs_order (const struct loop *);
-extern basic_block *get_loop_body_in_custom_order (const struct loop *,
+extern basic_block *get_loop_body_in_dom_order (const class loop *);
+extern basic_block *get_loop_body_in_bfs_order (const class loop *);
+extern basic_block *get_loop_body_in_custom_order (const class loop *,
int (*) (const void *, const void *));
-extern vec<edge> get_loop_exit_edges (const struct loop *);
-extern edge single_exit (const struct loop *);
-extern edge single_likely_exit (struct loop *loop);
-extern unsigned num_loop_branches (const struct loop *);
+extern vec<edge> get_loop_exit_edges (const class loop *);
+extern edge single_exit (const class loop *);
+extern edge single_likely_exit (class loop *loop);
+extern unsigned num_loop_branches (const class loop *);
-extern edge loop_preheader_edge (const struct loop *);
-extern edge loop_latch_edge (const struct loop *);
+extern edge loop_preheader_edge (const class loop *);
+extern edge loop_latch_edge (const class loop *);
-extern void add_bb_to_loop (basic_block, struct loop *);
+extern void add_bb_to_loop (basic_block, class loop *);
extern void remove_bb_from_loops (basic_block);
-extern void cancel_loop_tree (struct loop *);
-extern void delete_loop (struct loop *);
+extern void cancel_loop_tree (class loop *);
+extern void delete_loop (class loop *);
extern void verify_loop_structure (void);
/* Loop analysis. */
-extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
-gcov_type expected_loop_iterations_unbounded (const struct loop *,
+extern bool just_once_each_iteration_p (const class loop *, const_basic_block);
+gcov_type expected_loop_iterations_unbounded (const class loop *,
bool *read_profile_p = NULL, bool by_profile_only = false);
-extern unsigned expected_loop_iterations (struct loop *);
+extern unsigned expected_loop_iterations (class loop *);
extern rtx doloop_condition_get (rtx_insn *);
void mark_loop_for_removal (loop_p);
@@ -422,8 +424,9 @@ void mark_loop_for_removal (loop_p);
computation is done, which would enable it to be different from the
outer one? */
-struct rtx_iv
+class rtx_iv
{
+public:
/* Its base and step (mode of base and step is supposed to be extend_mode,
see the description above). */
rtx base, step;
@@ -448,8 +451,9 @@ struct rtx_iv
/* The description of an exit from the loop and of the number of iterations
till we take the exit. */
-struct GTY(()) niter_desc
+class GTY(()) niter_desc
{
+public:
/* The edge out of the loop. */
edge out_edge;
@@ -486,21 +490,21 @@ struct GTY(()) niter_desc
rtx niter_expr;
};
-extern void iv_analysis_loop_init (struct loop *);
-extern bool iv_analyze (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *);
-extern bool iv_analyze_result (rtx_insn *, rtx, struct rtx_iv *);
+extern void iv_analysis_loop_init (class loop *);
+extern bool iv_analyze (rtx_insn *, scalar_int_mode, rtx, class rtx_iv *);
+extern bool iv_analyze_result (rtx_insn *, rtx, class rtx_iv *);
extern bool iv_analyze_expr (rtx_insn *, scalar_int_mode, rtx,
- struct rtx_iv *);
-extern rtx get_iv_value (struct rtx_iv *, rtx);
+ class rtx_iv *);
+extern rtx get_iv_value (class rtx_iv *, rtx);
extern bool biv_p (rtx_insn *, scalar_int_mode, rtx);
-extern void find_simple_exit (struct loop *, struct niter_desc *);
+extern void find_simple_exit (class loop *, class niter_desc *);
extern void iv_analysis_done (void);
-extern struct niter_desc *get_simple_loop_desc (struct loop *loop);
-extern void free_simple_loop_desc (struct loop *loop);
+extern class niter_desc *get_simple_loop_desc (class loop *loop);
+extern void free_simple_loop_desc (class loop *loop);
-static inline struct niter_desc *
-simple_loop_desc (struct loop *loop)
+static inline class niter_desc *
+simple_loop_desc (class loop *loop)
{
return loop->simple_loop_desc;
}
@@ -509,7 +513,7 @@ simple_loop_desc (struct loop *loop)
/* Returns the loop with index NUM from FNs loop tree. */
-static inline struct loop *
+static inline class loop *
get_loop (struct function *fn, unsigned num)
{
return (*loops_for_fn (fn)->larray)[num];
@@ -518,7 +522,7 @@ get_loop (struct function *fn, unsigned num)
/* Returns the number of superloops of LOOP. */
static inline unsigned
-loop_depth (const struct loop *loop)
+loop_depth (const class loop *loop)
{
return vec_safe_length (loop->superloops);
}
@@ -526,8 +530,8 @@ loop_depth (const struct loop *loop)
/* Returns the immediate superloop of LOOP, or NULL if LOOP is the outermost
loop. */
-static inline struct loop *
-loop_outer (const struct loop *loop)
+static inline class loop *
+loop_outer (const class loop *loop)
{
unsigned n = vec_safe_length (loop->superloops);
@@ -540,7 +544,7 @@ loop_outer (const struct loop *loop)
/* Returns true if LOOP has at least one exit edge. */
static inline bool
-loop_has_exit_edges (const struct loop *loop)
+loop_has_exit_edges (const class loop *loop)
{
return loop->exits->next->e != NULL;
}
@@ -651,8 +655,9 @@ enum li_flags
/* The iterator for loops. */
-struct loop_iterator
+class loop_iterator
{
+public:
loop_iterator (function *fn, loop_p *loop, unsigned flags);
~loop_iterator ();
@@ -687,7 +692,7 @@ loop_iterator::next ()
inline
loop_iterator::loop_iterator (function *fn, loop_p *loop, unsigned flags)
{
- struct loop *aloop;
+ class loop *aloop;
unsigned i;
int mn;
@@ -838,11 +843,11 @@ enum
extern void doloop_optimize_loops (void);
extern void move_loop_invariants (void);
-extern vec<basic_block> get_loop_hot_path (const struct loop *loop);
+extern vec<basic_block> get_loop_hot_path (const class loop *loop);
/* Returns the outermost loop of the loop nest that contains LOOP.*/
-static inline struct loop *
-loop_outermost (struct loop *loop)
+static inline class loop *
+loop_outermost (class loop *loop)
{
unsigned n = vec_safe_length (loop->superloops);
@@ -852,13 +857,13 @@ loop_outermost (struct loop *loop)
return (*loop->superloops)[1];
}
-extern void record_niter_bound (struct loop *, const widest_int &, bool, bool);
-extern HOST_WIDE_INT get_estimated_loop_iterations_int (struct loop *);
-extern HOST_WIDE_INT get_max_loop_iterations_int (const struct loop *);
-extern HOST_WIDE_INT get_likely_max_loop_iterations_int (struct loop *);
-extern bool get_estimated_loop_iterations (struct loop *loop, widest_int *nit);
-extern bool get_max_loop_iterations (const struct loop *loop, widest_int *nit);
-extern bool get_likely_max_loop_iterations (struct loop *loop, widest_int *nit);
+extern void record_niter_bound (class loop *, const widest_int &, bool, bool);
+extern HOST_WIDE_INT get_estimated_loop_iterations_int (class loop *);
+extern HOST_WIDE_INT get_max_loop_iterations_int (const class loop *);
+extern HOST_WIDE_INT get_likely_max_loop_iterations_int (class loop *);
+extern bool get_estimated_loop_iterations (class loop *loop, widest_int *nit);
+extern bool get_max_loop_iterations (const class loop *loop, widest_int *nit);
+extern bool get_likely_max_loop_iterations (class loop *loop, widest_int *nit);
extern int bb_loop_depth (const_basic_block);
/* Converts VAL to widest_int. */
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 6dbe96f..10037f0 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -41,7 +41,7 @@ struct target_cfgloop *this_target_cfgloop = &default_target_cfgloop;
/* Checks whether BB is executed exactly once in each LOOP iteration. */
bool
-just_once_each_iteration_p (const struct loop *loop, const_basic_block bb)
+just_once_each_iteration_p (const class loop *loop, const_basic_block bb)
{
/* It must be executed at least once each iteration. */
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
@@ -81,7 +81,7 @@ mark_irreducible_loops (void)
unsigned depth;
struct graph *g;
int num = number_of_loops (cfun);
- struct loop *cloop;
+ class loop *cloop;
bool irred_loop_found = false;
int i;
@@ -173,7 +173,7 @@ mark_irreducible_loops (void)
/* Counts number of insns inside LOOP. */
int
-num_loop_insns (const struct loop *loop)
+num_loop_insns (const class loop *loop)
{
basic_block *bbs, bb;
unsigned i, ninsns = 0;
@@ -197,7 +197,7 @@ num_loop_insns (const struct loop *loop)
/* Counts number of insns executed on average per iteration LOOP. */
int
-average_num_loop_insns (const struct loop *loop)
+average_num_loop_insns (const class loop *loop)
{
basic_block *bbs, bb;
unsigned i, binsns;
@@ -238,7 +238,7 @@ average_num_loop_insns (const struct loop *loop)
return -1 in those scenarios. */
gcov_type
-expected_loop_iterations_unbounded (const struct loop *loop,
+expected_loop_iterations_unbounded (const class loop *loop,
bool *read_profile_p,
bool by_profile_only)
{
@@ -310,7 +310,7 @@ expected_loop_iterations_unbounded (const struct loop *loop,
by REG_BR_PROB_BASE. */
unsigned
-expected_loop_iterations (struct loop *loop)
+expected_loop_iterations (class loop *loop)
{
gcov_type expected = expected_loop_iterations_unbounded (loop);
return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
@@ -319,9 +319,9 @@ expected_loop_iterations (struct loop *loop)
/* Returns the maximum level of nesting of subloops of LOOP. */
unsigned
-get_loop_level (const struct loop *loop)
+get_loop_level (const class loop *loop)
{
- const struct loop *ploop;
+ const class loop *ploop;
unsigned mx = 0, l;
for (ploop = loop->inner; ploop; ploop = ploop->next)
@@ -463,7 +463,7 @@ mark_loop_exit_edges (void)
to noreturn call. */
edge
-single_likely_exit (struct loop *loop)
+single_likely_exit (class loop *loop)
{
edge found = single_exit (loop);
vec<edge> exits;
@@ -500,7 +500,7 @@ single_likely_exit (struct loop *loop)
header != latch, latch is the 1-st block. */
vec<basic_block>
-get_loop_hot_path (const struct loop *loop)
+get_loop_hot_path (const class loop *loop)
{
basic_block bb = loop->header;
vec<basic_block> path = vNULL;
diff --git a/gcc/cfgloopmanip.c b/gcc/cfgloopmanip.c
index b5f6a47..727e951 100644
--- a/gcc/cfgloopmanip.c
+++ b/gcc/cfgloopmanip.c
@@ -32,13 +32,13 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop-manip.h"
#include "dumpfile.h"
-static void copy_loops_to (struct loop **, int,
- struct loop *);
+static void copy_loops_to (class loop **, int,
+ class loop *);
static void loop_redirect_edge (edge, basic_block);
static void remove_bbs (basic_block *, int);
static bool rpe_enum_p (const_basic_block, const void *);
static int find_path (edge, basic_block **);
-static void fix_loop_placements (struct loop *, bool *);
+static void fix_loop_placements (class loop *, bool *);
static bool fix_bb_placement (basic_block);
static void fix_bb_placements (basic_block, bool *, bitmap);
@@ -89,7 +89,7 @@ fix_bb_placement (basic_block bb)
{
edge e;
edge_iterator ei;
- struct loop *loop = current_loops->tree_root, *act;
+ class loop *loop = current_loops->tree_root, *act;
FOR_EACH_EDGE (e, ei, bb->succs)
{
@@ -122,12 +122,12 @@ fix_bb_placement (basic_block bb)
invalidate the information about irreducible regions. */
static bool
-fix_loop_placement (struct loop *loop, bool *irred_invalidated)
+fix_loop_placement (class loop *loop, bool *irred_invalidated)
{
unsigned i;
edge e;
vec<edge> exits = get_loop_exit_edges (loop);
- struct loop *father = current_loops->tree_root, *act;
+ class loop *father = current_loops->tree_root, *act;
bool ret = false;
FOR_EACH_VEC_ELT (exits, i, e)
@@ -182,7 +182,7 @@ fix_bb_placements (basic_block from,
bitmap loop_closed_ssa_invalidated)
{
basic_block *queue, *qtop, *qbeg, *qend;
- struct loop *base_loop, *target_loop;
+ class loop *base_loop, *target_loop;
edge e;
/* We pass through blocks back-reachable from FROM, testing whether some
@@ -255,7 +255,7 @@ fix_bb_placements (basic_block from,
FOR_EACH_EDGE (e, ei, from->preds)
{
basic_block pred = e->src;
- struct loop *nca;
+ class loop *nca;
if (e->flags & EDGE_IRREDUCIBLE_LOOP)
*irred_invalidated = true;
@@ -307,7 +307,7 @@ remove_path (edge e, bool *irred_invalidated,
int i, nrem, n_bord_bbs;
bool local_irred_invalidated = false;
edge_iterator ei;
- struct loop *l, *f;
+ class loop *l, *f;
if (! irred_invalidated)
irred_invalidated = &local_irred_invalidated;
@@ -427,7 +427,7 @@ remove_path (edge e, bool *irred_invalidated,
/* Creates place for a new LOOP in loops structure of FN. */
void
-place_new_loop (struct function *fn, struct loop *loop)
+place_new_loop (struct function *fn, class loop *loop)
{
loop->num = number_of_loops (fn);
vec_safe_push (loops_for_fn (fn)->larray, loop);
@@ -438,11 +438,11 @@ place_new_loop (struct function *fn, struct loop *loop)
outer. */
void
-add_loop (struct loop *loop, struct loop *outer)
+add_loop (class loop *loop, class loop *outer)
{
basic_block *bbs;
int i, n;
- struct loop *subloop;
+ class loop *subloop;
edge e;
edge_iterator ei;
@@ -490,7 +490,7 @@ add_loop (struct loop *loop, struct loop *outer)
/* Scale profile of loop by P. */
void
-scale_loop_frequencies (struct loop *loop, profile_probability p)
+scale_loop_frequencies (class loop *loop, profile_probability p)
{
basic_block *bbs;
@@ -508,7 +508,7 @@ scale_loop_frequencies (struct loop *loop, profile_probability p)
they need to be scaled synchronously. */
void
-scale_loop_profile (struct loop *loop, profile_probability p,
+scale_loop_profile (class loop *loop, profile_probability p,
gcov_type iteration_bound)
{
edge e, preheader_e;
@@ -618,7 +618,7 @@ scale_loop_profile (struct loop *loop, profile_probability p,
/* Recompute dominance information for basic blocks outside LOOP. */
static void
-update_dominators_in_loop (struct loop *loop)
+update_dominators_in_loop (class loop *loop)
{
vec<basic_block> dom_bbs = vNULL;
basic_block *body;
@@ -763,17 +763,17 @@ create_empty_if_region_on_edge (edge entry_edge, tree condition)
should be used only when the UPPER_BOUND expression is a loop
invariant. */
-struct loop *
+class loop *
create_empty_loop_on_edge (edge entry_edge,
tree initial_value,
tree stride, tree upper_bound,
tree iv,
tree *iv_before,
tree *iv_after,
- struct loop *outer)
+ class loop *outer)
{
basic_block loop_header, loop_latch, succ_bb, pred_bb;
- struct loop *loop;
+ class loop *loop;
gimple_stmt_iterator gsi;
gimple_seq stmts;
gcond *cond_expr;
@@ -857,7 +857,7 @@ create_empty_loop_on_edge (edge entry_edge,
Returns the newly created loop. Frequencies and counts in the new loop
are scaled by FALSE_SCALE and in the old one by TRUE_SCALE. */
-struct loop *
+class loop *
loopify (edge latch_edge, edge header_edge,
basic_block switch_bb, edge true_edge, edge false_edge,
bool redirect_all_edges, profile_probability true_scale,
@@ -865,8 +865,8 @@ loopify (edge latch_edge, edge header_edge,
{
basic_block succ_bb = latch_edge->dest;
basic_block pred_bb = header_edge->src;
- struct loop *loop = alloc_loop ();
- struct loop *outer = loop_outer (succ_bb->loop_father);
+ class loop *loop = alloc_loop ();
+ class loop *outer = loop_outer (succ_bb->loop_father);
profile_count cnt;
loop->header = header_edge->dest;
@@ -923,11 +923,11 @@ loopify (edge latch_edge, edge header_edge,
basic blocks that had non-trivial update on their loop_father.*/
void
-unloop (struct loop *loop, bool *irred_invalidated,
+unloop (class loop *loop, bool *irred_invalidated,
bitmap loop_closed_ssa_invalidated)
{
basic_block *body;
- struct loop *ploop;
+ class loop *ploop;
unsigned i, n;
basic_block latch = loop->latch;
bool dummy = false;
@@ -978,9 +978,9 @@ unloop (struct loop *loop, bool *irred_invalidated,
invalidate the information about irreducible regions. */
static void
-fix_loop_placements (struct loop *loop, bool *irred_invalidated)
+fix_loop_placements (class loop *loop, bool *irred_invalidated)
{
- struct loop *outer;
+ class loop *outer;
while (loop_outer (loop))
{
@@ -1003,7 +1003,7 @@ fix_loop_placements (struct loop *loop, bool *irred_invalidated)
the loop into its duplicate. */
void
-copy_loop_info (struct loop *loop, struct loop *target)
+copy_loop_info (class loop *loop, class loop *target)
{
gcc_checking_assert (!target->any_upper_bound && !target->any_estimate);
target->any_upper_bound = loop->any_upper_bound;
@@ -1031,10 +1031,10 @@ copy_loop_info (struct loop *loop, struct loop *target)
created loop into loops structure. If AFTER is non-null
the new loop is added at AFTER->next, otherwise in front of TARGETs
sibling list. */
-struct loop *
-duplicate_loop (struct loop *loop, struct loop *target, struct loop *after)
+class loop *
+duplicate_loop (class loop *loop, class loop *target, class loop *after)
{
- struct loop *cloop;
+ class loop *cloop;
cloop = alloc_loop ();
place_new_loop (cfun, cloop);
@@ -1053,9 +1053,9 @@ duplicate_loop (struct loop *loop, struct loop *target, struct loop *after)
newly created loops into loop tree at the end of TARGETs sibling
list in the original order. */
void
-duplicate_subloops (struct loop *loop, struct loop *target)
+duplicate_subloops (class loop *loop, class loop *target)
{
- struct loop *aloop, *cloop, *tail;
+ class loop *aloop, *cloop, *tail;
for (tail = target->inner; tail && tail->next; tail = tail->next)
;
@@ -1072,9 +1072,9 @@ duplicate_subloops (struct loop *loop, struct loop *target)
into TARGET loop, placing newly created loops into loop tree adding
them to TARGETs sibling list at the end in order. */
static void
-copy_loops_to (struct loop **copied_loops, int n, struct loop *target)
+copy_loops_to (class loop **copied_loops, int n, class loop *target)
{
- struct loop *aloop, *tail;
+ class loop *aloop, *tail;
int i;
for (tail = target->inner; tail && tail->next; tail = tail->next)
@@ -1100,7 +1100,7 @@ loop_redirect_edge (edge e, basic_block dest)
/* Check whether LOOP's body can be duplicated. */
bool
-can_duplicate_loop_p (const struct loop *loop)
+can_duplicate_loop_p (const class loop *loop)
{
int ret;
basic_block *bbs = get_loop_body (loop);
@@ -1124,13 +1124,13 @@ can_duplicate_loop_p (const struct loop *loop)
impossible. */
bool
-duplicate_loop_to_header_edge (struct loop *loop, edge e,
+duplicate_loop_to_header_edge (class loop *loop, edge e,
unsigned int ndupl, sbitmap wont_exit,
edge orig, vec<edge> *to_remove,
int flags)
{
- struct loop *target, *aloop;
- struct loop **orig_loops;
+ class loop *target, *aloop;
+ class loop **orig_loops;
unsigned n_orig_loops;
basic_block header = loop->header, latch = loop->latch;
basic_block *new_bbs, *bbs, *first_active;
@@ -1276,7 +1276,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
n_orig_loops = 0;
for (aloop = loop->inner; aloop; aloop = aloop->next)
n_orig_loops++;
- orig_loops = XNEWVEC (struct loop *, n_orig_loops);
+ orig_loops = XNEWVEC (class loop *, n_orig_loops);
for (aloop = loop->inner, i = 0; aloop; aloop = aloop->next, i++)
orig_loops[i] = aloop;
@@ -1453,7 +1453,7 @@ mfb_keep_just (edge e)
/* True when a candidate preheader BLOCK has predecessors from LOOP. */
static bool
-has_preds_from_loop (basic_block block, struct loop *loop)
+has_preds_from_loop (basic_block block, class loop *loop)
{
edge e;
edge_iterator ei;
@@ -1473,7 +1473,7 @@ has_preds_from_loop (basic_block block, struct loop *loop)
The function also updates dominators. */
basic_block
-create_preheader (struct loop *loop, int flags)
+create_preheader (class loop *loop, int flags)
{
edge e;
basic_block dummy;
@@ -1573,7 +1573,7 @@ create_preheader (struct loop *loop, int flags)
void
create_preheaders (int flags)
{
- struct loop *loop;
+ class loop *loop;
if (!current_loops)
return;
@@ -1588,7 +1588,7 @@ create_preheaders (int flags)
void
force_single_succ_latches (void)
{
- struct loop *loop;
+ class loop *loop;
edge e;
FOR_EACH_LOOP (loop, 0)
@@ -1677,8 +1677,8 @@ lv_adjust_loop_entry_edge (basic_block first_head, basic_block second_head,
If PLACE_AFTER is true, we place the new loop after LOOP in the
instruction stream, otherwise it is placed before LOOP. */
-struct loop *
-loop_version (struct loop *loop,
+class loop *
+loop_version (class loop *loop,
void *cond_expr, basic_block *condition_bb,
profile_probability then_prob, profile_probability else_prob,
profile_probability then_scale, profile_probability else_scale,
@@ -1687,7 +1687,7 @@ loop_version (struct loop *loop,
basic_block first_head, second_head;
edge entry, latch_edge, true_edge, false_edge;
int irred_flag;
- struct loop *nloop;
+ class loop *nloop;
basic_block cond_bb;
/* Record entry and latch edges for the loop */
diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h
index d57aead..d14f490 100644
--- a/gcc/cfgloopmanip.h
+++ b/gcc/cfgloopmanip.h
@@ -35,30 +35,30 @@ enum
extern edge mfb_kj_edge;
extern bool remove_path (edge, bool * = NULL, bitmap = NULL);
-extern void place_new_loop (struct function *, struct loop *);
-extern void add_loop (struct loop *, struct loop *);
-extern void scale_loop_frequencies (struct loop *, profile_probability);
-extern void scale_loop_profile (struct loop *, profile_probability, gcov_type);
+extern void place_new_loop (struct function *, class loop *);
+extern void add_loop (class loop *, class loop *);
+extern void scale_loop_frequencies (class loop *, profile_probability);
+extern void scale_loop_profile (class loop *, profile_probability, gcov_type);
extern edge create_empty_if_region_on_edge (edge, tree);
-extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
- tree *, tree *, struct loop *);
-extern struct loop *loopify (edge, edge,
+extern class loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree,
+ tree *, tree *, class loop *);
+extern class loop *loopify (edge, edge,
basic_block, edge, edge, bool,
profile_probability, profile_probability);
-extern void unloop (struct loop *, bool *, bitmap);
-extern void copy_loop_info (struct loop *loop, struct loop *target);
-extern struct loop * duplicate_loop (struct loop *, struct loop *,
- struct loop * = NULL);
-extern void duplicate_subloops (struct loop *, struct loop *);
-extern bool can_duplicate_loop_p (const struct loop *loop);
-extern bool duplicate_loop_to_header_edge (struct loop *, edge,
+extern void unloop (class loop *, bool *, bitmap);
+extern void copy_loop_info (class loop *loop, class loop *target);
+extern class loop * duplicate_loop (class loop *, class loop *,
+ class loop * = NULL);
+extern void duplicate_subloops (class loop *, class loop *);
+extern bool can_duplicate_loop_p (const class loop *loop);
+extern bool duplicate_loop_to_header_edge (class loop *, edge,
unsigned, sbitmap, edge,
vec<edge> *, int);
extern bool mfb_keep_just (edge);
-basic_block create_preheader (struct loop *, int);
+basic_block create_preheader (class loop *, int);
extern void create_preheaders (int);
extern void force_single_succ_latches (void);
-struct loop * loop_version (struct loop *, void *,
+class loop * loop_version (class loop *, void *,
basic_block *,
profile_probability, profile_probability,
profile_probability, profile_probability, bool);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 4853ce4..bdef400 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -2198,7 +2198,7 @@ print_rtl_with_bb (FILE *outf, const rtx_insn *rtx_first, dump_flags_t flags)
if (df)
df_dump_start (outf);
- if (flags & TDF_BLOCKS)
+ if (cfun->curr_properties & PROP_cfg)
{
FOR_EACH_BB_REVERSE_FN (bb, cfun)
{
@@ -2206,16 +2206,19 @@ print_rtl_with_bb (FILE *outf, const rtx_insn *rtx_first, dump_flags_t flags)
start[INSN_UID (BB_HEAD (bb))] = bb;
end[INSN_UID (BB_END (bb))] = bb;
- for (x = BB_HEAD (bb); x != NULL_RTX; x = NEXT_INSN (x))
+ if (flags & TDF_BLOCKS)
{
- enum bb_state state = IN_MULTIPLE_BB;
+ for (x = BB_HEAD (bb); x != NULL_RTX; x = NEXT_INSN (x))
+ {
+ enum bb_state state = IN_MULTIPLE_BB;
- if (in_bb_p[INSN_UID (x)] == NOT_IN_BB)
- state = IN_ONE_BB;
- in_bb_p[INSN_UID (x)] = state;
+ if (in_bb_p[INSN_UID (x)] == NOT_IN_BB)
+ state = IN_ONE_BB;
+ in_bb_p[INSN_UID (x)] = state;
- if (x == BB_END (bb))
- break;
+ if (x == BB_END (bb))
+ break;
+ }
}
}
}
@@ -2249,16 +2252,36 @@ print_rtl_with_bb (FILE *outf, const rtx_insn *rtx_first, dump_flags_t flags)
if (flags & TDF_DETAILS)
df_dump_insn_bottom (tmp_rtx, outf);
- if (flags & TDF_BLOCKS)
+ bb = end[INSN_UID (tmp_rtx)];
+ if (bb != NULL)
{
- bb = end[INSN_UID (tmp_rtx)];
- if (bb != NULL)
+ if (flags & TDF_BLOCKS)
{
dump_bb_info (outf, bb, 0, dump_flags, false, true);
if (df && (flags & TDF_DETAILS))
df_dump_bottom (bb, outf);
putc ('\n', outf);
}
+ /* Emit a hint if the fallthrough target of current basic block
+ isn't the one placed right next. */
+ else if (EDGE_COUNT (bb->succs) > 0)
+ {
+ gcc_assert (BB_END (bb) == tmp_rtx);
+ const rtx_insn *ninsn = NEXT_INSN (tmp_rtx);
+ /* Bypass intervening deleted-insn notes and debug insns. */
+ while (ninsn
+ && !NONDEBUG_INSN_P (ninsn)
+ && !start[INSN_UID (ninsn)])
+ ninsn = NEXT_INSN (ninsn);
+ edge e = find_fallthru_edge (bb->succs);
+ if (e && ninsn)
+ {
+ basic_block dest = e->dest;
+ if (start[INSN_UID (ninsn)] != dest)
+ fprintf (outf, "%s ; pc falls through to BB %d\n",
+ print_rtx_head, dest->index);
+ }
+ }
}
}
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index d161db9..477db38 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -2204,6 +2204,22 @@ cgraph_node::dump (FILE *f)
}
}
+/* Dump call graph node to file F in graphviz format. */
+
+void
+cgraph_node::dump_graphviz (FILE *f)
+{
+ cgraph_edge *edge;
+
+ for (edge = callees; edge; edge = edge->next_callee)
+ {
+ cgraph_node *callee = edge->callee;
+
+ fprintf (f, "\t\"%s\" -> \"%s\"\n", name (), callee->name ());
+ }
+}
+
+
/* Dump call graph node NODE to stderr. */
DEBUG_FUNCTION void
@@ -3618,7 +3634,7 @@ cgraph_node::get_body (void)
set_dump_file (NULL);
push_cfun (DECL_STRUCT_FUNCTION (decl));
- execute_all_ipa_transforms ();
+ execute_all_ipa_transforms (true);
cgraph_edge::rebuild_edges ();
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 18839a4..a7c97de 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -100,8 +100,8 @@ enum symbol_partitioning_class
/* Base of all entries in the symbol table.
The symtab_node is inherited by cgraph and varpol nodes. */
-class GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),
- chain_next ("%h.next"), chain_prev ("%h.previous")))
+struct GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),
+ chain_next ("%h.next"), chain_prev ("%h.previous")))
symtab_node
{
public:
@@ -135,6 +135,9 @@ public:
/* Dump symtab node to F. */
void dump (FILE *f);
+ /* Dump symtab callgraph in graphviz format. */
+ void dump_graphviz (FILE *f);
+
/* Dump symtab node to stderr. */
void DEBUG_FUNCTION debug (void);
@@ -912,8 +915,8 @@ struct cgraph_edge_hasher : ggc_ptr_hash<cgraph_edge>
/* The cgraph data structure.
Each function decl has assigned cgraph_node listing callees and callers. */
-struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node {
-public:
+struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
+{
friend class symbol_table;
/* Remove the node from cgraph and all inline clones inlined into it.
@@ -1106,6 +1109,9 @@ public:
/* Dump call graph node to file F. */
void dump (FILE *f);
+ /* Dump call graph node to file F. */
+ void dump_graphviz (FILE *f);
+
/* Dump call graph node to stderr. */
void DEBUG_FUNCTION debug (void);
@@ -1505,7 +1511,7 @@ struct cgraph_node_set_def
typedef cgraph_node_set_def *cgraph_node_set;
typedef struct varpool_node_set_def *varpool_node_set;
-class varpool_node;
+struct varpool_node;
/* A varpool node set is a collection of varpool nodes. A varpool node
can appear in multiple sets. */
@@ -1619,7 +1625,7 @@ public:
/* LTO streaming. */
void stream_out (struct output_block *) const;
- void stream_in (struct lto_input_block *, struct data_in *data_in);
+ void stream_in (class lto_input_block *, class data_in *data_in);
private:
bool combine_speculation_with (tree, HOST_WIDE_INT, bool, tree);
@@ -1632,8 +1638,9 @@ private:
/* Structure containing additional information about an indirect call. */
-struct GTY(()) cgraph_indirect_call_info
+class GTY(()) cgraph_indirect_call_info
{
+public:
/* When agg_content is set, an offset where the call pointer is located
within the aggregate. */
HOST_WIDE_INT offset;
@@ -1673,9 +1680,11 @@ struct GTY(()) cgraph_indirect_call_info
unsigned vptr_changed : 1;
};
-struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
- for_user)) cgraph_edge {
- friend class cgraph_node;
+class GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
+ for_user)) cgraph_edge
+{
+public:
+ friend struct cgraph_node;
friend class symbol_table;
/* Remove the edge in the cgraph. */
@@ -1856,8 +1865,8 @@ private:
/* The varpool data structure.
Each static variable decl has assigned varpool_node. */
-class GTY((tag ("SYMTAB_VARIABLE"))) varpool_node : public symtab_node {
-public:
+struct GTY((tag ("SYMTAB_VARIABLE"))) varpool_node : public symtab_node
+{
/* Dump given varpool node to F. */
void dump (FILE *f);
@@ -2074,9 +2083,9 @@ struct asmname_hasher : ggc_ptr_hash <symtab_node>
class GTY((tag ("SYMTAB"))) symbol_table
{
public:
- friend class symtab_node;
- friend class cgraph_node;
- friend class cgraph_edge;
+ friend struct symtab_node;
+ friend struct cgraph_node;
+ friend struct cgraph_edge;
symbol_table (): cgraph_max_uid (1), cgraph_max_summary_id (0),
edges_max_uid (1), edges_max_summary_id (0)
@@ -2279,6 +2288,9 @@ public:
/* Dump symbol table to F. */
void dump (FILE *f);
+ /* Dump symbol table to F in graphviz format. */
+ void dump_graphviz (FILE *f);
+
/* Dump symbol table to stderr. */
void DEBUG_FUNCTION debug (void);
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 97c0105..2e7d0b5 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
struct record_reference_ctx
{
bool only_vars;
- class varpool_node *varpool_node;
+ struct varpool_node *varpool_node;
};
/* Walk tree and record all calls and references to functions/variables.
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index f4d6688..5999b9e 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2184,7 +2184,7 @@ cgraph_node::expand (void)
bitmap_obstack_initialize (&reg_obstack); /* FIXME, only at RTL generation*/
- execute_all_ipa_transforms ();
+ execute_all_ipa_transforms (false);
/* Perform all tree transforms and optimizations. */
diff --git a/gcc/collect2.c b/gcc/collect2.c
index d6a7355..e25e339 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -616,7 +616,7 @@ static const char *const target_machine = TARGET_MACHINE;
Return 0 if not found, otherwise return its name, allocated with malloc. */
-#if defined (OBJECT_FORMAT_NONE) || defined (OBJECT_FORMAT_COFF)
+#ifdef OBJECT_FORMAT_NONE
/* Add an entry for the object file NAME to object file list LIST.
New entries are added at the end of the list. The original pointer
@@ -636,7 +636,7 @@ add_lto_object (struct lto_object_list *list, const char *name)
list->last = n;
}
-#endif
+#endif /* OBJECT_FORMAT_NONE */
/* Perform a link-time recompilation and relink if any of the object
@@ -2799,10 +2799,8 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
LDFILE *ldptr = NULL;
int sym_index, sym_count;
int is_shared = 0;
- int found_lto = 0;
- if (which_pass != PASS_FIRST && which_pass != PASS_OBJ
- && which_pass != PASS_LTOINFO)
+ if (which_pass != PASS_FIRST && which_pass != PASS_OBJ)
return;
#ifdef COLLECT_EXPORT_LIST
@@ -2815,7 +2813,6 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
eliminate scan_libraries() function. */
do
{
- found_lto = 0;
#endif
/* Some platforms (e.g. OSF4) declare ldopen as taking a
non-const char * filename parameter, even though it will not
@@ -2858,19 +2855,6 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
++name;
#endif
- if (which_pass == PASS_LTOINFO)
- {
- if (found_lto)
- continue;
- if (strncmp (name, "__gnu_lto_v1", 12) == 0)
- {
- add_lto_object (&lto_objects, prog_name);
- found_lto = 1;
- break;
- }
- continue;
- }
-
switch (is_ctor_dtor (name))
{
#if TARGET_AIX_VERSION
diff --git a/gcc/combine.c b/gcc/combine.c
index 1be922d..f7b1ebc 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7829,7 +7829,7 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos,
For memory, assume that the desired extraction_mode and pos_mode
are the same as for a register operation, since at present we don't
have named patterns for aligned memory structures. */
- struct extraction_insn insn;
+ class extraction_insn insn;
unsigned int inner_size;
if (GET_MODE_BITSIZE (inner_mode).is_constant (&inner_size)
&& get_best_reg_extraction_insn (&insn, pattern, inner_size, mode))
diff --git a/gcc/common.opt b/gcc/common.opt
index 41514df..b998b25 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2430,6 +2430,10 @@ fsplit-wide-types
Common Report Var(flag_split_wide_types) Optimization
Split wide types into independent registers.
+fsplit-wide-types-early
+Common Report Var(flag_split_wide_types_early) Optimization
+Split wide types into independent registers earlier.
+
fssa-backprop
Common Report Var(flag_ssa_backprop) Init(1) Optimization
Enable backward propagation of use properties at the SSA level.
diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index a394f87..1f77f7d 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -1760,7 +1760,7 @@ const pta processor_alias_table[] =
| PTA_RDRND | PTA_MOVBE | PTA_MWAITX | PTA_ADX | PTA_RDSEED
| PTA_CLZERO | PTA_CLFLUSHOPT | PTA_XSAVEC | PTA_XSAVES
| PTA_SHA | PTA_LZCNT | PTA_POPCNT},
- {"znver2", PROCESSOR_ZNVER2, CPU_ZNVER1,
+ {"znver2", PROCESSOR_ZNVER2, CPU_ZNVER2,
PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3
| PTA_SSE4A | PTA_CX16 | PTA_ABM | PTA_SSSE3 | PTA_SSE4_1
| PTA_SSE4_2 | PTA_AES | PTA_PCLMUL | PTA_AVX | PTA_AVX2
diff --git a/gcc/common/config/rs6000/rs6000-common.c b/gcc/common/config/rs6000/rs6000-common.c
index 9857b54..4b0c205 100644
--- a/gcc/common/config/rs6000/rs6000-common.c
+++ b/gcc/common/config/rs6000/rs6000-common.c
@@ -31,6 +31,8 @@
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
static const struct default_options rs6000_option_optimization_table[] =
{
+ /* Split multi-word types early. */
+ { OPT_LEVELS_ALL, OPT_fsplit_wide_types_early, NULL, 1 },
/* Enable -fsched-pressure for first pass instruction scheduling. */
{ OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
{ OPT_LEVELS_NONE, 0, NULL, 0 }
diff --git a/gcc/config.gcc b/gcc/config.gcc
index c281c41..58262e5 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -499,7 +499,7 @@ or1k*-*-*)
;;
powerpc*-*-*)
cpu_type=rs6000
- extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
+ extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o rs6000-call.o"
extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h"
extra_headers="${extra_headers} bmi2intrin.h bmiintrin.h"
extra_headers="${extra_headers} xmmintrin.h mm_malloc.h emmintrin.h"
@@ -513,7 +513,7 @@ powerpc*-*-*)
;;
esac
extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
- target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-logue.c"
+ target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-logue.c \$(srcdir)/config/rs6000/rs6000-call.c"
;;
pru-*-*)
cpu_type=pru
@@ -525,8 +525,8 @@ riscv*)
;;
rs6000*-*-*)
extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
- extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
- target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-logue.c"
+ extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o rs6000-call.o"
+ target_gtfiles="$target_gtfiles \$(srcdir)/config/rs6000/rs6000-logue.c \$(srcdir)/config/rs6000/rs6000-call.c"
;;
sparc*-*-*)
cpu_type=sparc
@@ -2578,6 +2578,8 @@ or1k*-*-*)
for or1k_multilib in ${or1k_multilibs}; do
case ${or1k_multilib} in
mcmov | msext | msfimm | \
+ mror | mrori | \
+ mhard-float | mdouble-float | munordered-float | msoft-float | \
mhard-div | mhard-mul | \
msoft-div | msoft-mul )
TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${or1k_multilib}"
diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def
index 4b10c62..403a694 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -58,13 +58,13 @@
/* Enabling "fp" just enables "fp".
Disabling "fp" also disables "simd", "crypto", "fp16", "aes", "sha2",
"sha3", sm3/sm4, "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and
- "bitperm". */
+ "sve2-bitperm". */
AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "fp")
/* Enabling "simd" also enables "fp".
Disabling "simd" also disables "crypto", "dotprod", "aes", "sha2", "sha3",
- "sm3/sm4", "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and "bitperm".
- */
+ "sm3/sm4", "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and
+ "sve2-bitperm". */
AARCH64_OPT_EXTENSION("simd", AARCH64_FL_SIMD, AARCH64_FL_FP, AARCH64_FL_CRYPTO | AARCH64_FL_DOTPROD | AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "asimd")
/* Enabling "crypto" also enables "fp", "simd", "aes" and "sha2".
@@ -80,7 +80,7 @@ AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, false, "atomics")
/* Enabling "fp16" also enables "fp".
Disabling "fp16" disables "fp16", "fp16fml", "sve", "sve2", "sve2-aes",
- "sve2-sha3", "sve2-sm4", and "bitperm". */
+ "sve2-sha3", "sve2-sm4", and "sve2-bitperm". */
AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, AARCH64_FL_F16FML | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "fphp asimdhp")
/* Enabling or disabling "rcpc" only changes "rcpc". */
@@ -116,7 +116,7 @@ AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, AARCH64_FL_FP | AARCH64_FL_F
/* Enabling "sve" also enables "fp16", "fp" and "simd".
Disabling "sve" disables "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4"
- and "bitperm". */
+ and "sve2-bitperm". */
AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "sve")
/* Enabling/Disabling "profile" does not enable/disable any other feature. */
@@ -139,7 +139,7 @@ AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, false, "")
/* Enabling "sve2" also enables "sve", "fp16", "fp", and "simd".
Disabling "sve2" disables "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and
- "bitperm". */
+ "sve2-bitperm". */
AARCH64_OPT_EXTENSION("sve2", AARCH64_FL_SVE2, AARCH64_FL_SVE | AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "")
/* Enabling "sve2-sm4" also enables "sm4", "simd", "fp16", "fp", "sve", and
@@ -154,8 +154,8 @@ AARCH64_OPT_EXTENSION("sve2-aes", AARCH64_FL_SVE2_AES, AARCH64_FL_AES | AARCH64_
"sve2". Disabling "sve2-sha3" just disables "sve2-sha3". */
AARCH64_OPT_EXTENSION("sve2-sha3", AARCH64_FL_SVE2_SHA3, AARCH64_FL_SHA3 | AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
-/* Enabling "bitperm" also enables "simd", "fp16", "fp", "sve", and "sve2".
- Disabling "bitperm" just disables "bitperm". */
-AARCH64_OPT_EXTENSION("bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
+/* Enabling "sve2-bitperm" also enables "simd", "fp16", "fp", "sve", and
+ "sve2". Disabling "sve2-bitperm" just disables "sve2-bitperm". */
+AARCH64_OPT_EXTENSION("sve2-bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
#undef AARCH64_OPT_EXTENSION
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 837242c..c6ccc99 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -986,6 +986,18 @@
[(set_attr "type" "neon_shift_imm<q>")]
)
+(define_insn "*aarch64_simd_sra<mode>"
+ [(set (match_operand:VDQ_I 0 "register_operand" "=w")
+ (plus:VDQ_I
+ (SHIFTRT:VDQ_I
+ (match_operand:VDQ_I 1 "register_operand" "w")
+ (match_operand:VDQ_I 2 "aarch64_simd_rshift_imm" "Dr"))
+ (match_operand:VDQ_I 3 "register_operand" "0")))]
+ "TARGET_SIMD"
+ "<sra_op>sra\t%0.<Vtype>, %1.<Vtype>, %2"
+ [(set_attr "type" "neon_shift_acc<q>")]
+)
+
(define_insn "aarch64_simd_imm_shl<mode>"
[(set (match_operand:VDQ_I 0 "register_operand" "=w")
(ashift:VDQ_I (match_operand:VDQ_I 1 "register_operand" "w")
@@ -3135,30 +3147,31 @@
(define_insn "*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>"
[(set (match_operand:GPI 0 "register_operand" "=r")
(sign_extend:GPI
- (vec_select:<VEL>
+ (vec_select:<VDQQH:VEL>
(match_operand:VDQQH 1 "register_operand" "w")
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
{
- operands[2] = aarch64_endian_lane_rtx (<MODE>mode, INTVAL (operands[2]));
+ operands[2] = aarch64_endian_lane_rtx (<VDQQH:MODE>mode,
+ INTVAL (operands[2]));
return "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]";
}
- [(set_attr "type" "neon_to_gp<q>")]
-)
-
-(define_insn "*aarch64_get_lane_zero_extend<GPI:mode><VDQQH:mode>"
- [(set (match_operand:GPI 0 "register_operand" "=r")
- (zero_extend:GPI
- (vec_select:<VEL>
- (match_operand:VDQQH 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
- "TARGET_SIMD"
- {
- operands[2] = aarch64_endian_lane_rtx (<VDQQH:MODE>mode,
- INTVAL (operands[2]));
- return "umov\\t%w0, %1.<Vetype>[%2]";
- }
- [(set_attr "type" "neon_to_gp<q>")]
+ [(set_attr "type" "neon_to_gp<VDQQH:q>")]
+)
+
+(define_insn "*aarch64_get_lane_zero_extend<GPI:mode><VDQQH:mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (zero_extend:GPI
+ (vec_select:<VDQQH:VEL>
+ (match_operand:VDQQH 1 "register_operand" "w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_SIMD"
+ {
+ operands[2] = aarch64_endian_lane_rtx (<VDQQH:MODE>mode,
+ INTVAL (operands[2]));
+ return "umov\\t%w0, %1.<VDQQH:Vetype>[%2]";
+ }
+ [(set_attr "type" "neon_to_gp<VDQQH:q>")]
)
;; Lane extraction of a value, neither sign nor zero extension
@@ -6053,56 +6066,23 @@
(define_insn "aarch64_crypto_aes<aes_op>v16qi"
[(set (match_operand:V16QI 0 "register_operand" "=w")
- (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "%0")
- (match_operand:V16QI 2 "register_operand" "w")]
+ (unspec:V16QI
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
CRYPTO_AES))]
"TARGET_SIMD && TARGET_AES"
"aes<aes_op>\\t%0.16b, %2.16b"
[(set_attr "type" "crypto_aese")]
)
-(define_insn "*aarch64_crypto_aes<aes_op>v16qi_xor_combine"
- [(set (match_operand:V16QI 0 "register_operand" "=w")
- (unspec:V16QI [(xor:V16QI
- (match_operand:V16QI 1 "register_operand" "%0")
- (match_operand:V16QI 2 "register_operand" "w"))
- (match_operand:V16QI 3 "aarch64_simd_imm_zero" "")]
- CRYPTO_AES))]
- "TARGET_SIMD && TARGET_AES"
- "aes<aes_op>\\t%0.16b, %2.16b"
- [(set_attr "type" "crypto_aese")]
-)
-
-(define_insn "*aarch64_crypto_aes<aes_op>v16qi_xor_combine"
- [(set (match_operand:V16QI 0 "register_operand" "=w")
- (unspec:V16QI [(match_operand:V16QI 3 "aarch64_simd_imm_zero" "")
- (xor:V16QI (match_operand:V16QI 1 "register_operand" "%0")
- (match_operand:V16QI 2 "register_operand" "w"))]
- CRYPTO_AES))]
- "TARGET_SIMD && TARGET_AES"
- "aes<aes_op>\\t%0.16b, %2.16b"
- [(set_attr "type" "crypto_aese")]
-)
-
-;; When AES/AESMC fusion is enabled we want the register allocation to
-;; look like:
-;; AESE Vn, _
-;; AESMC Vn, Vn
-;; So prefer to tie operand 1 to operand 0 when fusing.
-
(define_insn "aarch64_crypto_aes<aesmc_op>v16qi"
- [(set (match_operand:V16QI 0 "register_operand" "=w,w")
- (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "0,w")]
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
+ (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "w")]
CRYPTO_AESMC))]
"TARGET_SIMD && TARGET_AES"
"aes<aesmc_op>\\t%0.16b, %1.16b"
- [(set_attr "type" "crypto_aesmc")
- (set_attr_alternative "enabled"
- [(if_then_else (match_test
- "aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)")
- (const_string "yes" )
- (const_string "no"))
- (const_string "yes")])]
+ [(set_attr "type" "crypto_aesmc")]
)
;; When AESE/AESMC fusion is enabled we really want to keep the two together
@@ -6111,12 +6091,14 @@
;; Mash the two together during combine.
(define_insn "*aarch64_crypto_aese_fused"
- [(set (match_operand:V16QI 0 "register_operand" "=&w")
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
(unspec:V16QI
[(unspec:V16QI
- [(match_operand:V16QI 1 "register_operand" "0")
- (match_operand:V16QI 2 "register_operand" "w")] UNSPEC_AESE)
- ] UNSPEC_AESMC))]
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
+ UNSPEC_AESE)]
+ UNSPEC_AESMC))]
"TARGET_SIMD && TARGET_AES
&& aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
"aese\\t%0.16b, %2.16b\;aesmc\\t%0.16b, %0.16b"
@@ -6130,12 +6112,14 @@
;; Mash the two together during combine.
(define_insn "*aarch64_crypto_aesd_fused"
- [(set (match_operand:V16QI 0 "register_operand" "=&w")
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
(unspec:V16QI
[(unspec:V16QI
- [(match_operand:V16QI 1 "register_operand" "0")
- (match_operand:V16QI 2 "register_operand" "w")] UNSPEC_AESD)
- ] UNSPEC_AESIMC))]
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
+ UNSPEC_AESD)]
+ UNSPEC_AESIMC))]
"TARGET_SIMD && TARGET_AES
&& aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)"
"aesd\\t%0.16b, %2.16b\;aesimc\\t%0.16b, %0.16b"
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index c4670b6..e489afb 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -1363,7 +1363,7 @@
;; don't have an unnecessary PTRUE.
"&& !CONSTANT_P (operands[1])"
{
- operands[1] = CONSTM1_RTX (<MODE>mode);
+ operands[1] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
}
)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 5a923ca..5bf182c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -3457,6 +3457,7 @@ aarch64_emit_sve_pred_move (rtx dest, rtx pred, rtx src)
create_output_operand (&ops[0], dest, mode);
create_input_operand (&ops[1], pred, GET_MODE(pred));
create_input_operand (&ops[2], src, mode);
+ temporary_volatile_ok v (true);
expand_insn (code_for_aarch64_pred_mov (mode), 3, ops);
}
@@ -15745,7 +15746,7 @@ aarch64_asm_output_external (FILE *stream, tree decl, const char* name)
void
aarch64_post_cfi_startproc (FILE *f, tree ignored ATTRIBUTE_UNUSED)
{
- if (!cfun->is_thunk && aarch64_return_address_signing_enabled ()
+ if (cfun->machine->frame.laid_out && aarch64_return_address_signing_enabled ()
&& aarch64_ra_sign_key == AARCH64_KEY_B)
asm_fprintf (f, "\t.cfi_b_key_frame\n");
}
@@ -17965,10 +17966,6 @@ aarch_macro_fusion_pair_p (rtx_insn *prev, rtx_insn *curr)
}
}
- if (aarch64_fusion_enabled_p (AARCH64_FUSE_AES_AESMC)
- && aarch_crypto_can_dual_issue (prev, curr))
- return true;
-
if (aarch64_fusion_enabled_p (AARCH64_FUSE_CMP_BRANCH)
&& any_condjump_p (curr))
{
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 4d559c4..d1b2c20 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -567,14 +567,14 @@
;; sub x0, x1, #(CST & 0xfff000)
;; subs x0, x0, #(CST & 0x000fff)
;; b<ne,eq> .Label
-(define_insn_and_split "*compare_condjump<mode>"
+(define_insn_and_split "*compare_condjump<GPI:mode>"
[(set (pc) (if_then_else (EQL
(match_operand:GPI 0 "register_operand" "r")
(match_operand:GPI 1 "aarch64_imm24" "n"))
(label_ref:P (match_operand 2 "" ""))
(pc)))]
- "!aarch64_move_imm (INTVAL (operands[1]), <MODE>mode)
- && !aarch64_plus_operand (operands[1], <MODE>mode)
+ "!aarch64_move_imm (INTVAL (operands[1]), <GPI:MODE>mode)
+ && !aarch64_plus_operand (operands[1], <GPI:MODE>mode)
&& !reload_completed"
"#"
"&& true"
@@ -582,11 +582,12 @@
{
HOST_WIDE_INT lo_imm = UINTVAL (operands[1]) & 0xfff;
HOST_WIDE_INT hi_imm = UINTVAL (operands[1]) & 0xfff000;
- rtx tmp = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_add<mode>3 (tmp, operands[0], GEN_INT (-hi_imm)));
- emit_insn (gen_add<mode>3_compare0 (tmp, tmp, GEN_INT (-lo_imm)));
+ rtx tmp = gen_reg_rtx (<GPI:MODE>mode);
+ emit_insn (gen_add<GPI:mode>3 (tmp, operands[0], GEN_INT (-hi_imm)));
+ emit_insn (gen_add<GPI:mode>3_compare0 (tmp, tmp, GEN_INT (-lo_imm)));
rtx cc_reg = gen_rtx_REG (CC_NZmode, CC_REGNUM);
- rtx cmp_rtx = gen_rtx_fmt_ee (<EQL:CMP>, <MODE>mode, cc_reg, const0_rtx);
+ rtx cmp_rtx = gen_rtx_fmt_ee (<EQL:CMP>, <GPI:MODE>mode,
+ cc_reg, const0_rtx);
emit_jump_insn (gen_condjump (cmp_rtx, cc_reg, operands[2]));
DONE;
}
@@ -1505,8 +1506,8 @@
(mem:GPI (plus:P (match_dup 1)
(match_operand:P 5 "const_int_operand" "n"))))])]
"INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
- "ldp\\t%<w>2, %<w>3, [%1], %4"
- [(set_attr "type" "load_<ldpstp_sz>")]
+ "ldp\\t%<GPI:w>2, %<GPI:w>3, [%1], %4"
+ [(set_attr "type" "load_<GPI:ldpstp_sz>")]
)
(define_insn "loadwb_pair<GPF:mode>_<P:mode>"
@@ -1520,7 +1521,7 @@
(mem:GPF (plus:P (match_dup 1)
(match_operand:P 5 "const_int_operand" "n"))))])]
"INTVAL (operands[5]) == GET_MODE_SIZE (<GPF:MODE>mode)"
- "ldp\\t%<w>2, %<w>3, [%1], %4"
+ "ldp\\t%<GPF:w>2, %<GPF:w>3, [%1], %4"
[(set_attr "type" "neon_load1_2reg")]
)
@@ -1553,8 +1554,8 @@
(match_operand:P 5 "const_int_operand" "n")))
(match_operand:GPI 3 "register_operand" "r"))])]
"INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
- "stp\\t%<w>2, %<w>3, [%0, %4]!"
- [(set_attr "type" "store_<ldpstp_sz>")]
+ "stp\\t%<GPI:w>2, %<GPI:w>3, [%0, %4]!"
+ [(set_attr "type" "store_<GPI:ldpstp_sz>")]
)
(define_insn "storewb_pair<GPF:mode>_<P:mode>"
@@ -1569,7 +1570,7 @@
(match_operand:P 5 "const_int_operand" "n")))
(match_operand:GPF 3 "register_operand" "w"))])]
"INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPF:MODE>mode)"
- "stp\\t%<w>2, %<w>3, [%0, %4]!"
+ "stp\\t%<GPF:w>2, %<GPF:w>3, [%0, %4]!"
[(set_attr "type" "neon_store1_2reg<q>")]
)
@@ -4782,7 +4783,7 @@
[(set_attr "type" "alus_imm")]
)
-(define_insn "*ands<mode>_compare0"
+(define_insn "*ands<GPI:mode>_compare0"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ
(zero_extend:GPI (match_operand:SHORT 1 "register_operand" "r"))
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 410423b..198fc5d 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1169,6 +1169,8 @@
;; This code iterator allows the shifts supported in arithmetic instructions
(define_code_iterator ASHIFT [ashift ashiftrt lshiftrt])
+(define_code_iterator SHIFTRT [ashiftrt lshiftrt])
+
;; Code iterator for logical operations
(define_code_iterator LOGICAL [and ior xor])
@@ -1351,6 +1353,9 @@
(define_code_attr shift [(ashift "lsl") (ashiftrt "asr")
(lshiftrt "lsr") (rotatert "ror")])
+;; Op prefix for shift right and accumulate.
+(define_code_attr sra_op [(ashiftrt "s") (lshiftrt "u")])
+
;; Map shift operators onto underlying bit-field instructions
(define_code_attr bfshift [(ashift "ubfiz") (ashiftrt "sbfx")
(lshiftrt "ubfx") (rotatert "extr")])
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 5decf91..71e6576 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -8959,7 +8959,7 @@ prepare_move_operands (rtx *operands, machine_mode mode)
if (GET_CODE (operands[1]) == SYMBOL_REF)
{
enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
- if (MEM_P (operands[0]) && flag_pic)
+ if (MEM_P (operands[0]))
operands[1] = force_reg (mode, operands[1]);
else if (model)
operands[1] = arc_legitimize_tls_address (operands[1], model);
diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h
index 11cd514..3bf38a1 100644
--- a/gcc/config/arm/aarch-common-protos.h
+++ b/gcc/config/arm/aarch-common-protos.h
@@ -24,7 +24,6 @@
#define GCC_AARCH_COMMON_PROTOS_H
extern int aarch_accumulator_forwarding (rtx_insn *, rtx_insn *);
-extern int aarch_crypto_can_dual_issue (rtx_insn *, rtx_insn *);
extern bool aarch_rev16_p (rtx);
extern bool aarch_rev16_shleft_mask_imm_p (rtx, machine_mode);
extern bool aarch_rev16_shright_mask_imm_p (rtx, machine_mode);
diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c
index c7af12d..965a07a 100644
--- a/gcc/config/arm/aarch-common.c
+++ b/gcc/config/arm/aarch-common.c
@@ -31,46 +31,6 @@
#include "rtl-iter.h"
#include "memmodel.h"
-/* In ARMv8-A there's a general expectation that AESE/AESMC
- and AESD/AESIMC sequences of the form:
-
- AESE Vn, _
- AESMC Vn, Vn
-
- will issue both instructions in a single cycle on super-scalar
- implementations. This function identifies such pairs. */
-
-int
-aarch_crypto_can_dual_issue (rtx_insn *producer_insn, rtx_insn *consumer_insn)
-{
- rtx producer_set, consumer_set;
- rtx producer_src, consumer_src;
-
- producer_set = single_set (producer_insn);
- consumer_set = single_set (consumer_insn);
-
- producer_src = producer_set ? SET_SRC (producer_set) : NULL;
- consumer_src = consumer_set ? SET_SRC (consumer_set) : NULL;
-
- if (producer_src && consumer_src
- && GET_CODE (producer_src) == UNSPEC && GET_CODE (consumer_src) == UNSPEC
- && ((XINT (producer_src, 1) == UNSPEC_AESE
- && XINT (consumer_src, 1) == UNSPEC_AESMC)
- || (XINT (producer_src, 1) == UNSPEC_AESD
- && XINT (consumer_src, 1) == UNSPEC_AESIMC)))
- {
- unsigned int regno = REGNO (SET_DEST (producer_set));
-
- /* Before reload the registers are virtual, so the destination of
- consumer_set doesn't need to match. */
-
- return (REGNO (SET_DEST (consumer_set)) == regno || !reload_completed)
- && REGNO (XVECEXP (consumer_src, 0, 0)) == regno;
- }
-
- return 0;
-}
-
/* Return TRUE if X is either an arithmetic shift left, or
is a multiplication by a power of two. */
bool
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 55bbb48..8f2c937 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -1993,25 +1993,12 @@ arm_expand_ternop_builtin (enum insn_code icode,
rtx op0 = expand_normal (arg0);
rtx op1 = expand_normal (arg1);
rtx op2 = expand_normal (arg2);
- rtx op3 = NULL_RTX;
- /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select
- lane operand depending on endianness. */
- bool builtin_sha1cpm_p = false;
-
- if (insn_data[icode].n_operands == 5)
- {
- gcc_assert (icode == CODE_FOR_crypto_sha1c
- || icode == CODE_FOR_crypto_sha1p
- || icode == CODE_FOR_crypto_sha1m);
- builtin_sha1cpm_p = true;
- }
machine_mode tmode = insn_data[icode].operand[0].mode;
machine_mode mode0 = insn_data[icode].operand[1].mode;
machine_mode mode1 = insn_data[icode].operand[2].mode;
machine_mode mode2 = insn_data[icode].operand[3].mode;
-
if (VECTOR_MODE_P (mode0))
op0 = safe_vector_operand (op0, mode0);
if (VECTOR_MODE_P (mode1))
@@ -2034,13 +2021,8 @@ arm_expand_ternop_builtin (enum insn_code icode,
op1 = copy_to_mode_reg (mode1, op1);
if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
op2 = copy_to_mode_reg (mode2, op2);
- if (builtin_sha1cpm_p)
- op3 = GEN_INT (TARGET_BIG_END ? 1 : 0);
- if (builtin_sha1cpm_p)
- pat = GEN_FCN (icode) (target, op0, op1, op2, op3);
- else
- pat = GEN_FCN (icode) (target, op0, op1, op2);
+ pat = GEN_FCN (icode) (target, op0, op1, op2);
if (! pat)
return 0;
emit_insn (pat);
@@ -2096,16 +2078,8 @@ arm_expand_unop_builtin (enum insn_code icode,
rtx pat;
tree arg0 = CALL_EXPR_ARG (exp, 0);
rtx op0 = expand_normal (arg0);
- rtx op1 = NULL_RTX;
machine_mode tmode = insn_data[icode].operand[0].mode;
machine_mode mode0 = insn_data[icode].operand[1].mode;
- bool builtin_sha1h_p = false;
-
- if (insn_data[icode].n_operands == 3)
- {
- gcc_assert (icode == CODE_FOR_crypto_sha1h);
- builtin_sha1h_p = true;
- }
if (! target
|| GET_MODE (target) != tmode
@@ -2121,13 +2095,9 @@ arm_expand_unop_builtin (enum insn_code icode,
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
}
- if (builtin_sha1h_p)
- op1 = GEN_INT (TARGET_BIG_END ? 1 : 0);
- if (builtin_sha1h_p)
- pat = GEN_FCN (icode) (target, op0, op1);
- else
- pat = GEN_FCN (icode) (target, op0);
+ pat = GEN_FCN (icode) (target, op0);
+
if (! pat)
return 0;
emit_insn (pat);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 820502a..81286ca 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -12471,7 +12471,7 @@ neon_expand_vector_init (rtx target, rtx vals)
if (n_var == 1)
{
rtx copy = copy_rtx (vals);
- rtx index = GEN_INT (one_var);
+ rtx merge_mask = GEN_INT (1 << one_var);
/* Load constant part of vector, substitute neighboring value for
varying element. */
@@ -12480,38 +12480,7 @@ neon_expand_vector_init (rtx target, rtx vals)
/* Insert variable. */
x = copy_to_mode_reg (inner_mode, XVECEXP (vals, 0, one_var));
- switch (mode)
- {
- case E_V8QImode:
- emit_insn (gen_neon_vset_lanev8qi (target, x, target, index));
- break;
- case E_V16QImode:
- emit_insn (gen_neon_vset_lanev16qi (target, x, target, index));
- break;
- case E_V4HImode:
- emit_insn (gen_neon_vset_lanev4hi (target, x, target, index));
- break;
- case E_V8HImode:
- emit_insn (gen_neon_vset_lanev8hi (target, x, target, index));
- break;
- case E_V2SImode:
- emit_insn (gen_neon_vset_lanev2si (target, x, target, index));
- break;
- case E_V4SImode:
- emit_insn (gen_neon_vset_lanev4si (target, x, target, index));
- break;
- case E_V2SFmode:
- emit_insn (gen_neon_vset_lanev2sf (target, x, target, index));
- break;
- case E_V4SFmode:
- emit_insn (gen_neon_vset_lanev4sf (target, x, target, index));
- break;
- case E_V2DImode:
- emit_insn (gen_neon_vset_lanev2di (target, x, target, index));
- break;
- default:
- gcc_unreachable ();
- }
+ emit_insn (gen_vec_set_internal (mode, target, x, merge_mask, target));
return;
}
@@ -30606,10 +30575,6 @@ aarch_macro_fusion_pair_p (rtx_insn* prev, rtx_insn* curr)
if (!arm_macro_fusion_p ())
return false;
- if (current_tune->fusible_ops & tune_params::FUSE_AES_AESMC
- && aarch_crypto_can_dual_issue (prev, curr))
- return true;
-
if (current_tune->fusible_ops & tune_params::FUSE_MOVW_MOVT
&& arm_sets_movw_movt_fusible_p (prev_set, curr_set))
return true;
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8f4a4c2..dcb5737 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -1110,7 +1110,7 @@
(parallel [(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 4) (match_dup 5)))
(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -1141,7 +1141,7 @@
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
(minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz")
(match_operand:SI 2 "s_register_operand" "r,r,r"))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (match_operand:SI 3 "arm_borrow_operation" "")))]
"TARGET_32BIT"
"@
sbc%?\\t%0, %1, %2
@@ -1155,9 +1155,10 @@
(define_insn "*subsi3_carryin_const"
[(set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (minus:SI (plus:SI
+ (match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_neg_immediate_operand" "L"))
+ (match_operand:SI 3 "arm_borrow_operation" "")))]
"TARGET_32BIT"
"sbc\\t%0, %1, #%n2"
[(set_attr "conds" "use")
@@ -1166,8 +1167,8 @@
(define_insn "*subsi3_carryin_const0"
[(set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_operand:SI 1 "s_register_operand" "r")
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (minus:SI (match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_borrow_operation" "")))]
"TARGET_32BIT"
"sbc\\t%0, %1, #0"
[(set_attr "conds" "use")
@@ -1176,12 +1177,11 @@
(define_insn "*subsi3_carryin_compare"
[(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:SI 1 "s_register_operand" "r")
- (match_operand:SI 2 "s_register_operand" "r")))
+ (compare:CC (match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "s_register_operand" "r")))
(set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (minus:SI (match_dup 1)
- (match_dup 2))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (minus:SI (minus:SI (match_dup 1) (match_dup 2))
+ (match_operand:SI 3 "arm_borrow_operation" "")))]
"TARGET_32BIT"
"sbcs\\t%0, %1, %2"
[(set_attr "conds" "set")
@@ -1190,12 +1190,13 @@
(define_insn "*subsi3_carryin_compare_const"
[(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
- (match_operand:SI 2 "const_int_I_operand" "I")))
+ (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
+ (match_operand:SI 2 "const_int_I_operand" "I")))
(set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (plus:SI (match_dup 1)
- (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (minus:SI (plus:SI
+ (match_dup 1)
+ (match_operand:SI 3 "arm_neg_immediate_operand" "L"))
+ (match_operand:SI 4 "arm_borrow_operation" "")))]
"TARGET_32BIT
&& (INTVAL (operands[2])
== trunc_int_for_mode (-INTVAL (operands[3]), SImode))"
@@ -1206,11 +1207,11 @@
(define_insn "*subsi3_carryin_compare_const0"
[(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
+ (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r")
(const_int 0)))
(set (match_operand:SI 0 "s_register_operand" "=r")
- (minus:SI (match_dup 1)
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (minus:SI (match_dup 1)
+ (match_operand:SI 2 "arm_borrow_operation" "")))]
"TARGET_32BIT"
"sbcs\\t%0, %1, #0"
[(set_attr "conds" "set")
@@ -1220,28 +1221,28 @@
(define_insn "*subsi3_carryin_shift"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (minus:SI
- (match_operand:SI 1 "s_register_operand" "r")
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "reg_or_int_operand" "rM")]))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (match_operand:SI 1 "s_register_operand" "r")
+ (match_operator:SI 2 "shift_operator"
+ [(match_operand:SI 3 "s_register_operand" "r")
+ (match_operand:SI 4 "reg_or_int_operand" "rM")]))
+ (match_operand:SI 5 "arm_borrow_operation" "")))]
"TARGET_32BIT"
"sbc%?\\t%0, %1, %3%S2"
[(set_attr "conds" "use")
(set_attr "predicable" "yes")
(set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "alu_shift_imm")
- (const_string "alu_shift_reg")))]
+ (const_string "alu_shift_imm")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*rsbsi3_carryin_shift"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (minus:SI
- (match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r")
- (match_operand:SI 4 "reg_or_int_operand" "rM")])
+ (match_operator:SI 2 "shift_operator"
+ [(match_operand:SI 3 "s_register_operand" "r")
+ (match_operand:SI 4 "reg_or_int_operand" "rM")])
(match_operand:SI 1 "s_register_operand" "r"))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (match_operand:SI 5 "arm_borrow_operation" "")))]
"TARGET_ARM"
"rsc%?\\t%0, %1, %3%S2"
[(set_attr "conds" "use")
@@ -1311,7 +1312,7 @@
(compare:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -1338,7 +1339,7 @@
(compare:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
(set (match_dup 3) (minus:SI (match_dup 4)
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -1365,7 +1366,7 @@
(set (match_dup 3) (minus:SI (minus:SI (match_dup 4)
(ashiftrt:SI (match_dup 2)
(const_int 31)))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -1392,7 +1393,7 @@
(compare:CC (match_dup 2) (match_dup 1)))
(set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))])
(set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -1422,7 +1423,7 @@
(ashiftrt:SI (match_dup 2)
(const_int 31))
(match_dup 4))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -1448,7 +1449,7 @@
(compare:CC (match_dup 1) (match_dup 2)))
(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -4661,7 +4662,7 @@
(set (match_dup 2)
(minus:SI
(minus:SI (const_int 0) (match_dup 3))
- (ltu:SI (reg:CC_C CC_REGNUM)
+ (ltu:SI (reg:CC CC_REGNUM)
(const_int 0))))])]
{
operands[2] = gen_highpart (SImode, operands[0]);
@@ -4703,7 +4704,7 @@
(compare:CC (const_int 0) (match_dup 1)))
(set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
(set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -4722,7 +4723,7 @@
(set (match_operand:SI 0 "s_register_operand" "=r")
(minus:SI (minus:SI (const_int 0)
(match_dup 1))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (match_operand:SI 2 "arm_borrow_operation" "")))]
"TARGET_ARM"
"rscs\\t%0, %1, #0"
[(set_attr "conds" "set")
@@ -4799,7 +4800,7 @@
asr Rhi, Rin, #31
rsbs Rlo, Rin, #0
rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */
- rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM);
+ rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
emit_insn (gen_rtx_SET (high,
gen_rtx_ASHIFTRT (SImode, operands[1],
@@ -4861,10 +4862,10 @@
;; since we just need to propagate the carry.
"&& reload_completed"
[(parallel [(set (reg:CC CC_REGNUM)
- (compare:CC (const_int 0) (match_dup 1)))
- (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
+ (compare:CC (const_int 0) (match_dup 1)))
+ (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
(set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2))
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))]
{
operands[2] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
@@ -7448,12 +7449,12 @@
"#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1"
"&& reload_completed"
[(set (reg:CC CC_REGNUM)
- (compare:CC (match_dup 0) (match_dup 1)))
+ (compare:CC (match_dup 0) (match_dup 1)))
(parallel [(set (reg:CC CC_REGNUM)
- (compare:CC (match_dup 3) (match_dup 4)))
- (set (match_dup 2)
- (minus:SI (match_dup 5)
- (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])]
+ (compare:CC (match_dup 3) (match_dup 4)))
+ (set (match_dup 2)
+ (minus:SI (match_dup 5)
+ (ltu:SI (reg:CC CC_REGNUM) (const_int 0))))])]
{
operands[3] = gen_highpart (SImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h
index 6b98239..1f200d4 100644
--- a/gcc/config/arm/arm_neon.h
+++ b/gcc/config/arm/arm_neon.h
@@ -16938,37 +16938,32 @@ __extension__ extern __inline uint32_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vsha1h_u32 (uint32_t __hash_e)
{
- uint32x4_t __t = vdupq_n_u32 (0);
- __t = vsetq_lane_u32 (__hash_e, __t, 0);
- __t = __builtin_arm_crypto_sha1h (__t);
- return vgetq_lane_u32 (__t, 0);
+ return vgetq_lane_u32 (__builtin_arm_crypto_sha1h (vdupq_n_u32 (__hash_e)),
+ 0);
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vsha1cq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk)
{
- uint32x4_t __t = vdupq_n_u32 (0);
- __t = vsetq_lane_u32 (__hash_e, __t, 0);
- return __builtin_arm_crypto_sha1c (__hash_abcd, __t, __wk);
+ return __builtin_arm_crypto_sha1c (__hash_abcd, vdupq_n_u32 (__hash_e),
+ __wk);
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vsha1pq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk)
{
- uint32x4_t __t = vdupq_n_u32 (0);
- __t = vsetq_lane_u32 (__hash_e, __t, 0);
- return __builtin_arm_crypto_sha1p (__hash_abcd, __t, __wk);
+ return __builtin_arm_crypto_sha1p (__hash_abcd, vdupq_n_u32 (__hash_e),
+ __wk);
}
__extension__ extern __inline uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
vsha1mq_u32 (uint32x4_t __hash_abcd, uint32_t __hash_e, uint32x4_t __wk)
{
- uint32x4_t __t = vdupq_n_u32 (0);
- __t = vsetq_lane_u32 (__hash_e, __t, 0);
- return __builtin_arm_crypto_sha1m (__hash_abcd, __t, __wk);
+ return __builtin_arm_crypto_sha1m (__hash_abcd, vdupq_n_u32 (__hash_e),
+ __wk);
}
__extension__ extern __inline uint32x4_t
diff --git a/gcc/config/arm/cortex-a53.md b/gcc/config/arm/cortex-a53.md
index b55d34e..58619aa 100644
--- a/gcc/config/arm/cortex-a53.md
+++ b/gcc/config/arm/cortex-a53.md
@@ -723,9 +723,3 @@
"cortex_a53_fpmac"
"aarch_accumulator_forwarding")
-;; We want AESE and AESMC to end up consecutive to one another.
-
-(define_bypass 0 "cortex_a53_crypto_aese"
- "cortex_a53_crypto_aesmc"
- "aarch_crypto_can_dual_issue")
-
diff --git a/gcc/config/arm/cortex-a57.md b/gcc/config/arm/cortex-a57.md
index a5f0b10..2d96a9c 100644
--- a/gcc/config/arm/cortex-a57.md
+++ b/gcc/config/arm/cortex-a57.md
@@ -801,9 +801,3 @@
;; help.
(define_bypass 1 "cortex_a57_*"
"cortex_a57_call,cortex_a57_branch")
-
-;; AESE+AESMC and AESD+AESIMC pairs forward with zero latency
-(define_bypass 0 "cortex_a57_crypto_simple"
- "cortex_a57_crypto_simple"
- "aarch_crypto_can_dual_issue")
-
diff --git a/gcc/config/arm/crypto.md b/gcc/config/arm/crypto.md
index 63d9d9f..03596fe 100644
--- a/gcc/config/arm/crypto.md
+++ b/gcc/config/arm/crypto.md
@@ -19,33 +19,76 @@
;; <http://www.gnu.org/licenses/>.
-;; When AES/AESMC fusion is enabled we want the register allocation to
-;; look like:
-;; AESE Vn, _
-;; AESMC Vn, Vn
-;; So prefer to tie operand 1 to operand 0 when fusing.
-
(define_insn "crypto_<crypto_pattern>"
- [(set (match_operand:<crypto_mode> 0 "register_operand" "=w,w")
- (unspec:<crypto_mode> [(match_operand:<crypto_mode> 1
- "register_operand" "0,w")]
- CRYPTO_UNARY))]
+ [(set (match_operand:<crypto_mode> 0 "register_operand" "=w")
+ (unspec:<crypto_mode>
+ [(match_operand:<crypto_mode> 1 "register_operand" "w")]
+ CRYPTO_AESMC))]
"TARGET_CRYPTO"
"<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q1"
- [(set_attr "type" "<crypto_type>")
- (set_attr_alternative "enabled"
- [(if_then_else (match_test
- "arm_fusion_enabled_p (tune_params::FUSE_AES_AESMC)")
- (const_string "yes" )
- (const_string "no"))
- (const_string "yes")])]
+ [(set_attr "type" "<crypto_type>")]
+)
+
+(define_insn "crypto_<crypto_pattern>"
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
+ (unspec:V16QI
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
+ CRYPTO_AES))]
+ "TARGET_CRYPTO"
+ "<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q2"
+ [(set_attr "type" "<crypto_type>")]
+)
+
+;; When AESE/AESMC fusion is enabled we really want to keep the two together
+;; and enforce the register dependency without scheduling or register
+;; allocation messing up the order or introducing moves inbetween.
+;; Mash the two together during combine.
+
+(define_insn "*aarch32_crypto_aese_fused"
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
+ (unspec:V16QI
+ [(unspec:V16QI
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
+ UNSPEC_AESE)]
+ UNSPEC_AESMC))]
+ "TARGET_CRYPTO
+ && arm_fusion_enabled_p (tune_params::FUSE_AES_AESMC)"
+ "aese.8\\t%q0, %q2\;aesmc.8\\t%q0, %q0"
+ [(set_attr "type" "crypto_aese")
+ (set_attr "length" "8")]
+)
+
+;; When AESD/AESIMC fusion is enabled we really want to keep the two together
+;; and enforce the register dependency without scheduling or register
+;; allocation messing up the order or introducing moves inbetween.
+;; Mash the two together during combine.
+
+(define_insn "*aarch32_crypto_aesd_fused"
+ [(set (match_operand:V16QI 0 "register_operand" "=w")
+ (unspec:V16QI
+ [(unspec:V16QI
+ [(xor:V16QI
+ (match_operand:V16QI 1 "register_operand" "%0")
+ (match_operand:V16QI 2 "register_operand" "w"))]
+ UNSPEC_AESD)]
+ UNSPEC_AESIMC))]
+ "TARGET_CRYPTO
+ && arm_fusion_enabled_p (tune_params::FUSE_AES_AESMC)"
+ "aesd.8\\t%q0, %q2\;aesimc.8\\t%q0, %q0"
+ [(set_attr "type" "crypto_aese")
+ (set_attr "length" "8")]
)
(define_insn "crypto_<crypto_pattern>"
[(set (match_operand:<crypto_mode> 0 "register_operand" "=w")
- (unspec:<crypto_mode> [(match_operand:<crypto_mode> 1 "register_operand" "0")
- (match_operand:<crypto_mode> 2 "register_operand" "w")]
- CRYPTO_BINARY))]
+ (unspec:<crypto_mode>
+ [(match_operand:<crypto_mode> 1 "register_operand" "0")
+ (match_operand:<crypto_mode> 2 "register_operand" "w")]
+ CRYPTO_BINARY))]
"TARGET_CRYPTO"
"<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q2"
[(set_attr "type" "<crypto_type>")]
@@ -62,14 +105,28 @@
[(set_attr "type" "<crypto_type>")]
)
-(define_insn "crypto_sha1h"
- [(set (match_operand:V4SI 0 "register_operand" "=w")
- (zero_extend:V4SI
- (unspec:SI [(vec_select:SI
- (match_operand:V4SI 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")]))]
- UNSPEC_SHA1H)))]
+/* The vec_select operation always selects index 0 from the lower V2SI subreg
+ of the V4SI, adjusted for endianness. Required due to neon_vget_lane and
+ neon_set_lane that change the element ordering in memory for big-endian. */
+
+(define_expand "crypto_sha1h"
+ [(set (match_operand:V4SI 0 "register_operand")
+ (match_operand:V4SI 1 "register_operand"))]
"TARGET_CRYPTO"
+{
+ rtx op2 = GEN_INT (NEON_ENDIAN_LANE_N (V2SImode, 0));
+ emit_insn (gen_crypto_sha1h_lb (operands[0], operands[1], op2));
+ DONE;
+})
+
+(define_insn "crypto_sha1h_lb"
+ [(set (match_operand:V4SI 0 "register_operand" "=w")
+ (unspec:V4SI
+ [(vec_select:SI
+ (match_operand:V4SI 1 "register_operand" "w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i")]))]
+ UNSPEC_SHA1H))]
+ "TARGET_CRYPTO && INTVAL (operands[2]) == NEON_ENDIAN_LANE_N (V2SImode, 0)"
"sha1h.32\\t%q0, %q1"
[(set_attr "type" "crypto_sha1_fast")]
)
@@ -84,7 +141,26 @@
[(set_attr "type" "crypto_pmull")]
)
-(define_insn "crypto_<crypto_pattern>"
+/* The vec_select operation always selects index 0 from the lower V2SI subreg
+ of the V4SI, adjusted for endianness. Required due to neon_vget_lane and
+ neon_set_lane that change the element ordering in memory for big-endian. */
+
+(define_expand "crypto_<crypto_pattern>"
+ [(set (match_operand:V4SI 0 "register_operand")
+ (unspec:<crypto_mode>
+ [(match_operand:<crypto_mode> 1 "register_operand")
+ (match_operand:<crypto_mode> 2 "register_operand")
+ (match_operand:<crypto_mode> 3 "register_operand")]
+ CRYPTO_SELECTING))]
+ "TARGET_CRYPTO"
+{
+ rtx op4 = GEN_INT (NEON_ENDIAN_LANE_N (V2SImode, 0));
+ emit_insn (gen_crypto_<crypto_pattern>_lb
+ (operands[0], operands[1], operands[2], operands[3], op4));
+ DONE;
+})
+
+(define_insn "crypto_<crypto_pattern>_lb"
[(set (match_operand:V4SI 0 "register_operand" "=w")
(unspec:<crypto_mode>
[(match_operand:<crypto_mode> 1 "register_operand" "0")
@@ -93,7 +169,7 @@
(parallel [(match_operand:SI 4 "immediate_operand" "i")]))
(match_operand:<crypto_mode> 3 "register_operand" "w")]
CRYPTO_SELECTING))]
- "TARGET_CRYPTO"
+ "TARGET_CRYPTO && INTVAL (operands[4]) == NEON_ENDIAN_LANE_N (V2SImode, 0)"
"<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q2, %q3"
[(set_attr "type" "<crypto_type>")]
)
diff --git a/gcc/config/arm/exynos-m1.md b/gcc/config/arm/exynos-m1.md
index 3d04a52..150ac85 100644
--- a/gcc/config/arm/exynos-m1.md
+++ b/gcc/config/arm/exynos-m1.md
@@ -950,11 +950,6 @@
"exynos_m1_crypto_simple, exynos_m1_crypto_complex,\
exynos_m1_crypto_poly*")
-;; AES{D,E}/AESMC pairs can feed each other instantly.
-(define_bypass 0 "exynos_m1_crypto_simple"
- "exynos_m1_crypto_simple"
- "aarch_crypto_can_dual_issue")
-
;; Predicted branches take no time, but mispredicted ones take forever anyway.
(define_bypass 1 "exynos_m1_*"
"exynos_m1_call, exynos_m1_branch")
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 2462b8c..eca1663 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -186,6 +186,9 @@
;; Modes with 8-bit elements.
(define_mode_iterator VE [V8QI V16QI])
+;; V2DI only (for use with @ patterns).
+(define_mode_iterator V2DI_ONLY [V2DI])
+
;; Modes with 64-bit elements only.
(define_mode_iterator V64 [DI V2DI])
@@ -413,10 +416,11 @@
(define_int_iterator CRC [UNSPEC_CRC32B UNSPEC_CRC32H UNSPEC_CRC32W
UNSPEC_CRC32CB UNSPEC_CRC32CH UNSPEC_CRC32CW])
-(define_int_iterator CRYPTO_UNARY [UNSPEC_AESMC UNSPEC_AESIMC])
+(define_int_iterator CRYPTO_AESMC [UNSPEC_AESMC UNSPEC_AESIMC])
+
+(define_int_iterator CRYPTO_AES [UNSPEC_AESD UNSPEC_AESE])
-(define_int_iterator CRYPTO_BINARY [UNSPEC_AESD UNSPEC_AESE
- UNSPEC_SHA1SU1 UNSPEC_SHA256SU0])
+(define_int_iterator CRYPTO_BINARY [UNSPEC_SHA1SU1 UNSPEC_SHA256SU0])
(define_int_iterator CRYPTO_TERNARY [UNSPEC_SHA1SU0 UNSPEC_SHA256H
UNSPEC_SHA256H2 UNSPEC_SHA256SU1])
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 4bfe770..6333e0e 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -319,7 +319,7 @@
"vld1.<V_sz_elem>\t{%q0}, %A1"
[(set_attr "type" "neon_load1_1reg<q>")])
-(define_insn "vec_set<mode>_internal"
+(define_insn "@vec_set<mode>_internal"
[(set (match_operand:VD_LANE 0 "s_register_operand" "=w,w")
(vec_merge:VD_LANE
(vec_duplicate:VD_LANE
@@ -340,7 +340,7 @@
}
[(set_attr "type" "neon_load1_all_lanes<q>,neon_from_gp<q>")])
-(define_insn "vec_set<mode>_internal"
+(define_insn "@vec_set<mode>_internal"
[(set (match_operand:VQ2 0 "s_register_operand" "=w,w")
(vec_merge:VQ2
(vec_duplicate:VQ2
@@ -369,12 +369,12 @@
[(set_attr "type" "neon_load1_all_lanes<q>,neon_from_gp<q>")]
)
-(define_insn "vec_setv2di_internal"
- [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
- (vec_merge:V2DI
- (vec_duplicate:V2DI
+(define_insn "@vec_set<mode>_internal"
+ [(set (match_operand:V2DI_ONLY 0 "s_register_operand" "=w,w")
+ (vec_merge:V2DI_ONLY
+ (vec_duplicate:V2DI_ONLY
(match_operand:DI 1 "nonimmediate_operand" "Um,r"))
- (match_operand:V2DI 3 "s_register_operand" "0,0")
+ (match_operand:V2DI_ONLY 3 "s_register_operand" "0,0")
(match_operand:SI 2 "immediate_operand" "i,i")))]
"TARGET_NEON"
{
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index f53378a..25f8647 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -358,6 +358,27 @@
(define_special_predicate "lt_ge_comparison_operator"
(match_code "lt,ge"))
+;; Match a "borrow" operation for use with SBC. The precise code will
+;; depend on the form of the comparison. This is generally the inverse of
+;; a carry operation, since the logic of SBC uses "not borrow" in it's
+;; calculation.
+(define_special_predicate "arm_borrow_operation"
+ (match_code "geu,ltu")
+ {
+ if (XEXP (op, 1) != const0_rtx)
+ return false;
+ rtx op0 = XEXP (op, 0);
+ if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
+ return false;
+ machine_mode ccmode = GET_MODE (op0);
+ if (ccmode == CC_Cmode)
+ return GET_CODE (op) == GEU;
+ else if (ccmode == CCmode)
+ return GET_CODE (op) == LTU;
+ return false;
+ }
+)
+
;; The vsel instruction only accepts the ARM condition codes listed below.
(define_special_predicate "arm_vsel_comparison_operator"
(and (match_operand 0 "expandable_comparison_operator")
diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md
index 3d49aef..ed857d6 100644
--- a/gcc/config/arm/sync.md
+++ b/gcc/config/arm/sync.md
@@ -201,7 +201,7 @@
(match_operand:SI 7 "const_int_operand")] ;; mod_f
VUNSPEC_ATOMIC_CAS))
(clobber (match_scratch:SI 8 "=&r,X,X,X"))]
- "<sync_predtab>"
+ "<NARROW:sync_predtab>"
"#"
"&& reload_completed"
[(const_int 0)]
@@ -225,14 +225,14 @@
(match_operand:SIDI 2 "mem_noofs_operand" "+Ua,Ua,Ua,Ua")) ;; memory
(set (match_dup 2)
(unspec_volatile:SIDI
- [(match_operand:SIDI 3 "<cas_cmp_operand>" "<cas_cmp_str>,lIL*h,J,*r") ;; expect
+ [(match_operand:SIDI 3 "<SIDI:cas_cmp_operand>" "<SIDI:cas_cmp_str>,lIL*h,J,*r") ;; expect
(match_operand:SIDI 4 "s_register_operand" "r,r,r,r") ;; desired
(match_operand:SI 5 "const_int_operand") ;; is_weak
(match_operand:SI 6 "const_int_operand") ;; mod_s
(match_operand:SI 7 "const_int_operand")] ;; mod_f
VUNSPEC_ATOMIC_CAS))
(clobber (match_scratch:SI 8 "=&r,X,X,X"))]
- "<sync_predtab>"
+ "<SIDI:sync_predtab>"
"#"
"&& reload_completed"
[(const_int 0)]
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index b97faaf..760e937 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -10163,7 +10163,7 @@ avr_asm_output_aligned_decl_common (FILE * stream,
return;
}
- /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
+ /* __gnu_lto_slim is just a marker for the linker injected by toplev.c.
There is no need to trigger __do_clear_bss code for them. */
if (!STR_PREFIX_P (name, "__gnu_lto"))
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index 93841e4..f6c9bbf 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -1083,6 +1083,14 @@ c6x_section_type_flags (tree decl, const char *name, int reloc)
flags |= default_section_type_flags (decl, name, reloc);
+ /* The ".far" section will be declared with @nobits elsewhere.
+ But when declared via this path it will not have the @nobits
+ flag because of SECTION_NOTYPE. This causes linker warnings
+ due to the mismatched attribute. Clearing SECTION_NOTYPE
+ for the ".far" section is sufficient to fix this problem. */
+ if (strcmp (name, ".far") == 0)
+ flags &= ~SECTION_NOTYPE;
+
return flags;
}
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index ef6e389..5ac0925 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -3232,8 +3232,6 @@ darwin_override_options (void)
/* so no tables either.. */
flag_unwind_tables = 0;
flag_asynchronous_unwind_tables = 0;
- /* We still need to emit branch islands for kernel context. */
- darwin_picsymbol_stubs = true;
}
if (flag_var_tracking_uninit == 0
@@ -3243,6 +3241,8 @@ darwin_override_options (void)
&& write_symbols == DWARF2_DEBUG)
flag_var_tracking_uninit = flag_var_tracking;
+ /* Final check on PCI options; for Darwin these are not dependent on the PIE
+ ones, although PIE does require PIC to support it. */
if (MACHO_DYNAMIC_NO_PIC_P)
{
if (flag_pic)
@@ -3251,9 +3251,11 @@ darwin_override_options (void)
" %<-fpie%> or %<-fPIE%>");
flag_pic = 0;
}
- else if (flag_pic == 1)
+ else if (flag_pic == 1
+ || (flag_pic == 0 && !(flag_mkernel || flag_apple_kext)))
{
- /* Darwin's -fpic is -fPIC. */
+ /* Darwin's -fpic is -fPIC.
+ We only support "static" code in the kernel and kernel exts. */
flag_pic = 2;
}
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index e17bc64..ed87984 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -118,13 +118,23 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* True if pragma ms_struct is in effect. */
extern GTY(()) int darwin_ms_struct;
-#define DRIVER_SELF_SPECS \
- "%{gfull:-g -fno-eliminate-unused-debug-symbols} %<gfull", \
- "%{gused:-g -feliminate-unused-debug-symbols} %<gused", \
- "%{fapple-kext|mkernel:-static}", \
- "%{shared:-Zdynamiclib} %<shared", \
- "%{gsplit-dwarf:%ngsplit-dwarf is not supported on this platform} \
- %<gsplit-dwarf"
+/* The majority of Darwin's special driver opts are direct access to ld flags
+ (to save the user typing -Wl,xxxxx or Xlinker xxxxx) but we can't process
+ them here, since doing so will make it appear that there are linker infiles
+ and the linker will invoked even when it is not necessary.
+
+ However, a few can be handled and we can elide options that are silently-
+ ignored defaults, plus warn on obsolete ones that no longer function. */
+#define DRIVER_SELF_SPECS \
+"%{fapple-kext|mkernel:-static}", \
+"%{gfull:-g -fno-eliminate-unused-debug-symbols} %<gfull", \
+"%{gsplit-dwarf:%ngsplit-dwarf is not supported on this platform} \
+ %<gsplit-dwarf", \
+"%{gused:-g -feliminate-unused-debug-symbols} %<gused", \
+"%{shared:-Zdynamiclib} %<shared", \
+"%{static:%{Zdynamic:%e conflicting code gen style switches are used}}",\
+"%{y*:%nthe y option is obsolete and ignored} %<y*", \
+"%<Mach %<X"
#if LD64_HAS_EXPORT_DYNAMIC
#define DARWIN_RDYNAMIC "%{rdynamic:-export_dynamic}"
@@ -342,13 +352,11 @@ extern GTY(()) int darwin_ms_struct;
%{Zunexported_symbols_list*:-unexported_symbols_list %*} \
%{Zweak_reference_mismatches*:-weak_reference_mismatches %*} \
%{!Zweak_reference_mismatches*:-weak_reference_mismatches non-weak} \
- %{X} \
- %{y*} \
%{w} \
%{pagezero_size*} %{segs_read_*} %{seglinkedit} %{noseglinkedit} \
%{sectalign*} %{sectobjectsymbols*} %{segcreate*} %{whyload} \
%{whatsloaded} %{dylinker_install_name*} \
- %{dylinker} %{Mach} "
+ %{dylinker} "
/* Machine dependent libraries. */
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index 3cc59dd..c7e8b16 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -2574,10 +2574,10 @@
""
{
rtx tmp = gen_reg_rtx (DImode);
- emit_insn (gen_vec_cmp<mode>di (tmp, operands[3], operands[4],
- operands[5]));
- emit_insn (gen_vcond_mask_<mode>di (operands[0], operands[1], operands[2],
- tmp));
+ emit_insn (gen_vec_cmp<VEC_1REG_ALT:mode>di
+ (tmp, operands[3], operands[4], operands[5]));
+ emit_insn (gen_vcond_mask_<VEC_1REG_MODE:mode>di
+ (operands[0], operands[1], operands[2], tmp));
DONE;
})
@@ -2592,10 +2592,10 @@
""
{
rtx tmp = gen_reg_rtx (DImode);
- emit_insn (gen_vec_cmp<mode>di_exec (tmp, operands[3], operands[4],
- operands[5], operands[6]));
- emit_insn (gen_vcond_mask_<mode>di (operands[0], operands[1], operands[2],
- tmp));
+ emit_insn (gen_vec_cmp<VEC_1REG_ALT:mode>di_exec
+ (tmp, operands[3], operands[4], operands[5], operands[6]));
+ emit_insn (gen_vcond_mask_<VEC_1REG_MODE:mode>di
+ (operands[0], operands[1], operands[2], tmp));
DONE;
})
@@ -2609,10 +2609,10 @@
""
{
rtx tmp = gen_reg_rtx (DImode);
- emit_insn (gen_vec_cmp<mode>di (tmp, operands[3], operands[4],
- operands[5]));
- emit_insn (gen_vcond_mask_<mode>di (operands[0], operands[1], operands[2],
- tmp));
+ emit_insn (gen_vec_cmp<VEC_1REG_INT_ALT:mode>di
+ (tmp, operands[3], operands[4], operands[5]));
+ emit_insn (gen_vcond_mask_<VEC_1REG_INT_MODE:mode>di
+ (operands[0], operands[1], operands[2], tmp));
DONE;
})
@@ -2627,10 +2627,10 @@
""
{
rtx tmp = gen_reg_rtx (DImode);
- emit_insn (gen_vec_cmp<mode>di_exec (tmp, operands[3], operands[4],
- operands[5], operands[6]));
- emit_insn (gen_vcond_mask_<mode>di (operands[0], operands[1], operands[2],
- tmp));
+ emit_insn (gen_vec_cmp<VEC_1REG_INT_ALT:mode>di_exec
+ (tmp, operands[3], operands[4], operands[5], operands[6]));
+ emit_insn (gen_vcond_mask_<VEC_1REG_INT_MODE:mode>di
+ (operands[0], operands[1], operands[2], tmp));
DONE;
})
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md
index 42610fd..778d3e1 100644
--- a/gcc/config/h8300/h8300.md
+++ b/gcc/config/h8300/h8300.md
@@ -728,7 +728,7 @@
"mov.w\\t%T0,@-r7"
[(set_attr "length" "2")])
-(define_insn "*push1_h8300hs_<mode>"
+(define_insn "*push1_h8300hs_<QHI:mode>"
[(set (mem:QHI
(pre_modify:P
(reg:P SP_REG)
diff --git a/gcc/config/i386/avx512fintrin.h b/gcc/config/i386/avx512fintrin.h
index e35eedb..454fd3d 100644
--- a/gcc/config/i386/avx512fintrin.h
+++ b/gcc/config/i386/avx512fintrin.h
@@ -6352,6 +6352,13 @@ _mm_mask_store_sd (double *__P, __mmask8 __U, __m128d __A)
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_loadu_epi64 (void const *__P)
+{
+ return *(__m512i_u *) __P;
+}
+
+extern __inline __m512i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_loadu_epi64 (__m512i __W, __mmask8 __U, void const *__P)
{
return (__m512i) __builtin_ia32_loaddqudi512_mask ((const long long *) __P,
@@ -6371,6 +6378,13 @@ _mm512_maskz_loadu_epi64 (__mmask8 __U, void const *__P)
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_storeu_epi64 (void *__P, __m512i __A)
+{
+ *(__m512i_u *) __P = (__m512i_u) __A;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_storeu_epi64 (void *__P, __mmask8 __U, __m512i __A)
{
__builtin_ia32_storedqudi512_mask ((long long *) __P, (__v8di) __A,
@@ -6386,6 +6400,13 @@ _mm512_loadu_si512 (void const *__P)
extern __inline __m512i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_loadu_epi32 (void const *__P)
+{
+ return *(__m512i_u *) __P;
+}
+
+extern __inline __m512i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_loadu_epi32 (__m512i __W, __mmask16 __U, void const *__P)
{
return (__m512i) __builtin_ia32_loaddqusi512_mask ((const int *) __P,
@@ -6412,6 +6433,13 @@ _mm512_storeu_si512 (void *__P, __m512i __A)
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_storeu_epi32 (void *__P, __m512i __A)
+{
+ *(__m512i_u *) __P = (__m512i_u) __A;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_mask_storeu_epi32 (void *__P, __mmask16 __U, __m512i __A)
{
__builtin_ia32_storedqusi512_mask ((int *) __P, (__v16si) __A,
diff --git a/gcc/config/i386/avx512vlintrin.h b/gcc/config/i386/avx512vlintrin.h
index 3eaf817..bd8746d 100644
--- a/gcc/config/i386/avx512vlintrin.h
+++ b/gcc/config/i386/avx512vlintrin.h
@@ -757,6 +757,13 @@ _mm_maskz_loadu_epi64 (__mmask8 __U, void const *__P)
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_storeu_epi64 (void *__P, __m256i __A)
+{
+ *(__m256i_u *) __P = (__m256i_u) __A;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_storeu_epi64 (void *__P, __mmask8 __U, __m256i __A)
{
__builtin_ia32_storedqudi256_mask ((long long *) __P,
@@ -766,6 +773,13 @@ _mm256_mask_storeu_epi64 (void *__P, __mmask8 __U, __m256i __A)
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_storeu_epi64 (void *__P, __m128i __A)
+{
+ *(__m128i_u *) __P = (__m128i_u) __A;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_storeu_epi64 (void *__P, __mmask8 __U, __m128i __A)
{
__builtin_ia32_storedqudi128_mask ((long long *) __P,
@@ -813,6 +827,13 @@ _mm_maskz_loadu_epi32 (__mmask8 __U, void const *__P)
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_storeu_epi32 (void *__P, __m256i __A)
+{
+ *(__m256i_u *) __P = (__m256i_u) __A;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_mask_storeu_epi32 (void *__P, __mmask8 __U, __m256i __A)
{
__builtin_ia32_storedqusi256_mask ((int *) __P,
@@ -822,6 +843,13 @@ _mm256_mask_storeu_epi32 (void *__P, __mmask8 __U, __m256i __A)
extern __inline void
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm_storeu_epi32 (void *__P, __m128i __A)
+{
+ *(__m128i_u *) __P = (__m128i_u) __A;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm_mask_storeu_epi32 (void *__P, __mmask8 __U, __m128i __A)
{
__builtin_ia32_storedqusi128_mask ((int *) __P,
diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def
index 221c0e7..38fea5c 100644
--- a/gcc/config/i386/i386-builtin-types.def
+++ b/gcc/config/i386/i386-builtin-types.def
@@ -1252,17 +1252,8 @@ DEF_FUNCTION_TYPE (V8HI, V8HI, V8HI, INT, V8HI, INT)
DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, INT, V4SI, INT)
DEF_FUNCTION_TYPE (V2DI, V2DI, V2DI, INT, V2DI, INT)
DEF_FUNCTION_TYPE (V32HI, V32HI, V32HI, V32HI)
-DEF_FUNCTION_TYPE (V32HI, V32HI, V32HI, V32HI, INT)
-DEF_FUNCTION_TYPE (V16HI, V16HI, V16HI, V16HI, INT)
-DEF_FUNCTION_TYPE (V8HI, V8HI, V8HI, V8HI, INT)
-DEF_FUNCTION_TYPE (V8SI, V8SI, V8SI, V8SI, INT)
-DEF_FUNCTION_TYPE (V4SI, V4SI, V4SI, V4SI, INT)
DEF_FUNCTION_TYPE (V8DI, V8DI, V8DI, V8DI)
-DEF_FUNCTION_TYPE (V8DI, V8DI, V8DI, V8DI, INT)
-DEF_FUNCTION_TYPE (V4DI, V4DI, V4DI, V4DI, INT)
DEF_FUNCTION_TYPE (V16SI, V16SI, V16SI, V16SI)
-DEF_FUNCTION_TYPE (V16SI, V16SI, V16SI, V16SI, INT)
-DEF_FUNCTION_TYPE (V2DI, V2DI, V2DI, V2DI, INT)
# BITALG builtins
DEF_FUNCTION_TYPE (V4DI, V4DI)
diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def
index ef45311..6ac820e 100644
--- a/gcc/config/i386/i386-builtin.def
+++ b/gcc/config/i386/i386-builtin.def
@@ -2528,60 +2528,60 @@ BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshl
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshld_v2di_mask, "__builtin_ia32_vpshld_v2di_mask", IX86_BUILTIN_VPSHLDV2DI_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT_V2DI_INT)
BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v32hi, "__builtin_ia32_vpshrdv_v32hi", IX86_BUILTIN_VPSHRDVV32HI, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshrdv_v32hi_mask, "__builtin_ia32_vpshrdv_v32hi_mask", IX86_BUILTIN_VPSHRDVV32HI_MASK, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshrdv_v32hi_maskz, "__builtin_ia32_vpshrdv_v32hi_maskz", IX86_BUILTIN_VPSHRDVV32HI_MASKZ, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshrdv_v32hi_mask, "__builtin_ia32_vpshrdv_v32hi_mask", IX86_BUILTIN_VPSHRDVV32HI_MASK, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_USI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshrdv_v32hi_maskz, "__builtin_ia32_vpshrdv_v32hi_maskz", IX86_BUILTIN_VPSHRDVV32HI_MASKZ, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_USI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v16hi, "__builtin_ia32_vpshrdv_v16hi", IX86_BUILTIN_VPSHRDVV16HI, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v16hi_mask, "__builtin_ia32_vpshrdv_v16hi_mask", IX86_BUILTIN_VPSHRDVV16HI_MASK, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v16hi_maskz, "__builtin_ia32_vpshrdv_v16hi_maskz", IX86_BUILTIN_VPSHRDVV16HI_MASKZ, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v16hi_mask, "__builtin_ia32_vpshrdv_v16hi_mask", IX86_BUILTIN_VPSHRDVV16HI_MASK, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v16hi_maskz, "__builtin_ia32_vpshrdv_v16hi_maskz", IX86_BUILTIN_VPSHRDVV16HI_MASKZ, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8hi, "__builtin_ia32_vpshrdv_v8hi", IX86_BUILTIN_VPSHRDVV8HI, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8hi_mask, "__builtin_ia32_vpshrdv_v8hi_mask", IX86_BUILTIN_VPSHRDVV8HI_MASK, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8hi_maskz, "__builtin_ia32_vpshrdv_v8hi_maskz", IX86_BUILTIN_VPSHRDVV8HI_MASKZ, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8hi_mask, "__builtin_ia32_vpshrdv_v8hi_mask", IX86_BUILTIN_VPSHRDVV8HI_MASK, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8hi_maskz, "__builtin_ia32_vpshrdv_v8hi_maskz", IX86_BUILTIN_VPSHRDVV8HI_MASKZ, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v16si, "__builtin_ia32_vpshrdv_v16si", IX86_BUILTIN_VPSHRDVV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v16si_mask, "__builtin_ia32_vpshrdv_v16si_mask", IX86_BUILTIN_VPSHRDVV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v16si_maskz, "__builtin_ia32_vpshrdv_v16si_maskz", IX86_BUILTIN_VPSHRDVV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v16si_mask, "__builtin_ia32_vpshrdv_v16si_mask", IX86_BUILTIN_VPSHRDVV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v16si_maskz, "__builtin_ia32_vpshrdv_v16si_maskz", IX86_BUILTIN_VPSHRDVV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8si, "__builtin_ia32_vpshrdv_v8si", IX86_BUILTIN_VPSHRDVV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8si_mask, "__builtin_ia32_vpshrdv_v8si_mask", IX86_BUILTIN_VPSHRDVV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8si_maskz, "__builtin_ia32_vpshrdv_v8si_maskz", IX86_BUILTIN_VPSHRDVV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8si_mask, "__builtin_ia32_vpshrdv_v8si_mask", IX86_BUILTIN_VPSHRDVV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v8si_maskz, "__builtin_ia32_vpshrdv_v8si_maskz", IX86_BUILTIN_VPSHRDVV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4si, "__builtin_ia32_vpshrdv_v4si", IX86_BUILTIN_VPSHRDVV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4si_mask, "__builtin_ia32_vpshrdv_v4si_mask", IX86_BUILTIN_VPSHRDVV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4si_maskz, "__builtin_ia32_vpshrdv_v4si_maskz", IX86_BUILTIN_VPSHRDVV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4si_mask, "__builtin_ia32_vpshrdv_v4si_mask", IX86_BUILTIN_VPSHRDVV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4si_maskz, "__builtin_ia32_vpshrdv_v4si_maskz", IX86_BUILTIN_VPSHRDVV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v8di, "__builtin_ia32_vpshrdv_v8di", IX86_BUILTIN_VPSHRDVV8DI, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v8di_mask, "__builtin_ia32_vpshrdv_v8di_mask", IX86_BUILTIN_VPSHRDVV8DI_MASK, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v8di_maskz, "__builtin_ia32_vpshrdv_v8di_maskz", IX86_BUILTIN_VPSHRDVV8DI_MASKZ, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v8di_mask, "__builtin_ia32_vpshrdv_v8di_mask", IX86_BUILTIN_VPSHRDVV8DI_MASK, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshrdv_v8di_maskz, "__builtin_ia32_vpshrdv_v8di_maskz", IX86_BUILTIN_VPSHRDVV8DI_MASKZ, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4di, "__builtin_ia32_vpshrdv_v4di", IX86_BUILTIN_VPSHRDVV4DI, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4di_mask, "__builtin_ia32_vpshrdv_v4di_mask", IX86_BUILTIN_VPSHRDVV4DI_MASK, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4di_maskz, "__builtin_ia32_vpshrdv_v4di_maskz", IX86_BUILTIN_VPSHRDVV4DI_MASKZ, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4di_mask, "__builtin_ia32_vpshrdv_v4di_mask", IX86_BUILTIN_VPSHRDVV4DI_MASK, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v4di_maskz, "__builtin_ia32_vpshrdv_v4di_maskz", IX86_BUILTIN_VPSHRDVV4DI_MASKZ, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v2di, "__builtin_ia32_vpshrdv_v2di", IX86_BUILTIN_VPSHRDVV2DI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v2di_mask, "__builtin_ia32_vpshrdv_v2di_mask", IX86_BUILTIN_VPSHRDVV2DI_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v2di_maskz, "__builtin_ia32_vpshrdv_v2di_maskz", IX86_BUILTIN_VPSHRDVV2DI_MASKZ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v2di_mask, "__builtin_ia32_vpshrdv_v2di_mask", IX86_BUILTIN_VPSHRDVV2DI_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshrdv_v2di_maskz, "__builtin_ia32_vpshrdv_v2di_maskz", IX86_BUILTIN_VPSHRDVV2DI_MASKZ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v32hi, "__builtin_ia32_vpshldv_v32hi", IX86_BUILTIN_VPSHLDVV32HI, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshldv_v32hi_mask, "__builtin_ia32_vpshldv_v32hi_mask", IX86_BUILTIN_VPSHLDVV32HI_MASK, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshldv_v32hi_maskz, "__builtin_ia32_vpshldv_v32hi_maskz", IX86_BUILTIN_VPSHLDVV32HI_MASKZ, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshldv_v32hi_mask, "__builtin_ia32_vpshldv_v32hi_mask", IX86_BUILTIN_VPSHLDVV32HI_MASK, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_USI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512BW, 0, CODE_FOR_vpshldv_v32hi_maskz, "__builtin_ia32_vpshldv_v32hi_maskz", IX86_BUILTIN_VPSHLDVV32HI_MASKZ, UNKNOWN, (int) V32HI_FTYPE_V32HI_V32HI_V32HI_USI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v16hi, "__builtin_ia32_vpshldv_v16hi", IX86_BUILTIN_VPSHLDVV16HI, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v16hi_mask, "__builtin_ia32_vpshldv_v16hi_mask", IX86_BUILTIN_VPSHLDVV16HI_MASK, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v16hi_maskz, "__builtin_ia32_vpshldv_v16hi_maskz", IX86_BUILTIN_VPSHLDVV16HI_MASKZ, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v16hi_mask, "__builtin_ia32_vpshldv_v16hi_mask", IX86_BUILTIN_VPSHLDVV16HI_MASK, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v16hi_maskz, "__builtin_ia32_vpshldv_v16hi_maskz", IX86_BUILTIN_VPSHLDVV16HI_MASKZ, UNKNOWN, (int) V16HI_FTYPE_V16HI_V16HI_V16HI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8hi, "__builtin_ia32_vpshldv_v8hi", IX86_BUILTIN_VPSHLDVV8HI, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8hi_mask, "__builtin_ia32_vpshldv_v8hi_mask", IX86_BUILTIN_VPSHLDVV8HI_MASK, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8hi_maskz, "__builtin_ia32_vpshldv_v8hi_maskz", IX86_BUILTIN_VPSHLDVV8HI_MASKZ, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8hi_mask, "__builtin_ia32_vpshldv_v8hi_mask", IX86_BUILTIN_VPSHLDVV8HI_MASK, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8hi_maskz, "__builtin_ia32_vpshldv_v8hi_maskz", IX86_BUILTIN_VPSHLDVV8HI_MASKZ, UNKNOWN, (int) V8HI_FTYPE_V8HI_V8HI_V8HI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v16si, "__builtin_ia32_vpshldv_v16si", IX86_BUILTIN_VPSHLDVV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v16si_mask, "__builtin_ia32_vpshldv_v16si_mask", IX86_BUILTIN_VPSHLDVV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v16si_maskz, "__builtin_ia32_vpshldv_v16si_maskz", IX86_BUILTIN_VPSHLDVV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v16si_mask, "__builtin_ia32_vpshldv_v16si_mask", IX86_BUILTIN_VPSHLDVV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v16si_maskz, "__builtin_ia32_vpshldv_v16si_maskz", IX86_BUILTIN_VPSHLDVV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8si, "__builtin_ia32_vpshldv_v8si", IX86_BUILTIN_VPSHLDVV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8si_mask, "__builtin_ia32_vpshldv_v8si_mask", IX86_BUILTIN_VPSHLDVV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8si_maskz, "__builtin_ia32_vpshldv_v8si_maskz", IX86_BUILTIN_VPSHLDVV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8si_mask, "__builtin_ia32_vpshldv_v8si_mask", IX86_BUILTIN_VPSHLDVV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v8si_maskz, "__builtin_ia32_vpshldv_v8si_maskz", IX86_BUILTIN_VPSHLDVV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4si, "__builtin_ia32_vpshldv_v4si", IX86_BUILTIN_VPSHLDVV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4si_mask, "__builtin_ia32_vpshldv_v4si_mask", IX86_BUILTIN_VPSHLDVV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4si_maskz, "__builtin_ia32_vpshldv_v4si_maskz", IX86_BUILTIN_VPSHLDVV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4si_mask, "__builtin_ia32_vpshldv_v4si_mask", IX86_BUILTIN_VPSHLDVV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4si_maskz, "__builtin_ia32_vpshldv_v4si_maskz", IX86_BUILTIN_VPSHLDVV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v8di, "__builtin_ia32_vpshldv_v8di", IX86_BUILTIN_VPSHLDVV8DI, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v8di_mask, "__builtin_ia32_vpshldv_v8di_mask", IX86_BUILTIN_VPSHLDVV8DI_MASK, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v8di_maskz, "__builtin_ia32_vpshldv_v8di_maskz", IX86_BUILTIN_VPSHLDVV8DI_MASKZ, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v8di_mask, "__builtin_ia32_vpshldv_v8di_mask", IX86_BUILTIN_VPSHLDVV8DI_MASK, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2, 0, CODE_FOR_vpshldv_v8di_maskz, "__builtin_ia32_vpshldv_v8di_maskz", IX86_BUILTIN_VPSHLDVV8DI_MASKZ, UNKNOWN, (int) V8DI_FTYPE_V8DI_V8DI_V8DI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4di, "__builtin_ia32_vpshldv_v4di", IX86_BUILTIN_VPSHLDVV4DI, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4di_mask, "__builtin_ia32_vpshldv_v4di_mask", IX86_BUILTIN_VPSHLDVV4DI_MASK, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4di_maskz, "__builtin_ia32_vpshldv_v4di_maskz", IX86_BUILTIN_VPSHLDVV4DI_MASKZ, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4di_mask, "__builtin_ia32_vpshldv_v4di_mask", IX86_BUILTIN_VPSHLDVV4DI_MASK, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v4di_maskz, "__builtin_ia32_vpshldv_v4di_maskz", IX86_BUILTIN_VPSHLDVV4DI_MASKZ, UNKNOWN, (int) V4DI_FTYPE_V4DI_V4DI_V4DI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v2di, "__builtin_ia32_vpshldv_v2di", IX86_BUILTIN_VPSHLDVV2DI, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v2di_mask, "__builtin_ia32_vpshldv_v2di_mask", IX86_BUILTIN_VPSHLDVV2DI_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v2di_maskz, "__builtin_ia32_vpshldv_v2di_maskz", IX86_BUILTIN_VPSHLDVV2DI_MASKZ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v2di_mask, "__builtin_ia32_vpshldv_v2di_mask", IX86_BUILTIN_VPSHLDVV2DI_MASK, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VBMI2 | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpshldv_v2di_maskz, "__builtin_ia32_vpshldv_v2di_maskz", IX86_BUILTIN_VPSHLDVV2DI_MASKZ, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_V2DI_UQI)
/* GFNI */
BDESC (OPTION_MASK_ISA_GFNI | OPTION_MASK_ISA_AVX512F, 0, CODE_FOR_vgf2p8affineinvqb_v64qi, "__builtin_ia32_vgf2p8affineinvqb_v64qi", IX86_BUILTIN_VGF2P8AFFINEINVQB512, UNKNOWN, (int) V64QI_FTYPE_V64QI_V64QI_INT)
@@ -2606,44 +2606,44 @@ BDESC (OPTION_MASK_ISA_GFNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vgf2p8mulb_v
/* VNNI */
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si, "__builtin_ia32_vpdpbusd_v16si", IX86_BUILTIN_VPDPBUSDV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si_mask, "__builtin_ia32_vpdpbusd_v16si_mask", IX86_BUILTIN_VPDPBUSDV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si_maskz, "__builtin_ia32_vpdpbusd_v16si_maskz", IX86_BUILTIN_VPDPBUSDV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si_mask, "__builtin_ia32_vpdpbusd_v16si_mask", IX86_BUILTIN_VPDPBUSDV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusd_v16si_maskz, "__builtin_ia32_vpdpbusd_v16si_maskz", IX86_BUILTIN_VPDPBUSDV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si, "__builtin_ia32_vpdpbusd_v8si", IX86_BUILTIN_VPDPBUSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si_mask, "__builtin_ia32_vpdpbusd_v8si_mask", IX86_BUILTIN_VPDPBUSDV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si_maskz, "__builtin_ia32_vpdpbusd_v8si_maskz", IX86_BUILTIN_VPDPBUSDV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si_mask, "__builtin_ia32_vpdpbusd_v8si_mask", IX86_BUILTIN_VPDPBUSDV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v8si_maskz, "__builtin_ia32_vpdpbusd_v8si_maskz", IX86_BUILTIN_VPDPBUSDV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si, "__builtin_ia32_vpdpbusd_v4si", IX86_BUILTIN_VPDPBUSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si_mask, "__builtin_ia32_vpdpbusd_v4si_mask", IX86_BUILTIN_VPDPBUSDV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si_maskz, "__builtin_ia32_vpdpbusd_v4si_maskz", IX86_BUILTIN_VPDPBUSDV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si_mask, "__builtin_ia32_vpdpbusd_v4si_mask", IX86_BUILTIN_VPDPBUSDV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusd_v4si_maskz, "__builtin_ia32_vpdpbusd_v4si_maskz", IX86_BUILTIN_VPDPBUSDV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si, "__builtin_ia32_vpdpbusds_v16si", IX86_BUILTIN_VPDPBUSDSV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si_mask, "__builtin_ia32_vpdpbusds_v16si_mask", IX86_BUILTIN_VPDPBUSDSV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si_maskz, "__builtin_ia32_vpdpbusds_v16si_maskz", IX86_BUILTIN_VPDPBUSDSV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si_mask, "__builtin_ia32_vpdpbusds_v16si_mask", IX86_BUILTIN_VPDPBUSDSV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpbusds_v16si_maskz, "__builtin_ia32_vpdpbusds_v16si_maskz", IX86_BUILTIN_VPDPBUSDSV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si, "__builtin_ia32_vpdpbusds_v8si", IX86_BUILTIN_VPDPBUSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si_mask, "__builtin_ia32_vpdpbusds_v8si_mask", IX86_BUILTIN_VPDPBUSDSV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si_maskz, "__builtin_ia32_vpdpbusds_v8si_maskz", IX86_BUILTIN_VPDPBUSDSV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si_mask, "__builtin_ia32_vpdpbusds_v8si_mask", IX86_BUILTIN_VPDPBUSDSV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v8si_maskz, "__builtin_ia32_vpdpbusds_v8si_maskz", IX86_BUILTIN_VPDPBUSDSV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si, "__builtin_ia32_vpdpbusds_v4si", IX86_BUILTIN_VPDPBUSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si_mask, "__builtin_ia32_vpdpbusds_v4si_mask", IX86_BUILTIN_VPDPBUSDSV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si_maskz, "__builtin_ia32_vpdpbusds_v4si_maskz", IX86_BUILTIN_VPDPBUSDSV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si_mask, "__builtin_ia32_vpdpbusds_v4si_mask", IX86_BUILTIN_VPDPBUSDSV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpbusds_v4si_maskz, "__builtin_ia32_vpdpbusds_v4si_maskz", IX86_BUILTIN_VPDPBUSDSV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si, "__builtin_ia32_vpdpwssd_v16si", IX86_BUILTIN_VPDPWSSDV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si_mask, "__builtin_ia32_vpdpwssd_v16si_mask", IX86_BUILTIN_VPDPWSSDV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si_maskz, "__builtin_ia32_vpdpwssd_v16si_maskz", IX86_BUILTIN_VPDPWSSDV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si_mask, "__builtin_ia32_vpdpwssd_v16si_mask", IX86_BUILTIN_VPDPWSSDV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssd_v16si_maskz, "__builtin_ia32_vpdpwssd_v16si_maskz", IX86_BUILTIN_VPDPWSSDV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si, "__builtin_ia32_vpdpwssd_v8si", IX86_BUILTIN_VPDPWSSDV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si_mask, "__builtin_ia32_vpdpwssd_v8si_mask", IX86_BUILTIN_VPDPWSSDV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si_maskz, "__builtin_ia32_vpdpwssd_v8si_maskz", IX86_BUILTIN_VPDPWSSDV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si_mask, "__builtin_ia32_vpdpwssd_v8si_mask", IX86_BUILTIN_VPDPWSSDV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v8si_maskz, "__builtin_ia32_vpdpwssd_v8si_maskz", IX86_BUILTIN_VPDPWSSDV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si, "__builtin_ia32_vpdpwssd_v4si", IX86_BUILTIN_VPDPWSSDV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si_mask, "__builtin_ia32_vpdpwssd_v4si_mask", IX86_BUILTIN_VPDPWSSDV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si_maskz, "__builtin_ia32_vpdpwssd_v4si_maskz", IX86_BUILTIN_VPDPWSSDV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si_mask, "__builtin_ia32_vpdpwssd_v4si_mask", IX86_BUILTIN_VPDPWSSDV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssd_v4si_maskz, "__builtin_ia32_vpdpwssd_v4si_maskz", IX86_BUILTIN_VPDPWSSDV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si, "__builtin_ia32_vpdpwssds_v16si", IX86_BUILTIN_VPDPWSSDSV16SI, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si_mask, "__builtin_ia32_vpdpwssds_v16si_mask", IX86_BUILTIN_VPDPWSSDSV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si_maskz, "__builtin_ia32_vpdpwssds_v16si_maskz", IX86_BUILTIN_VPDPWSSDSV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si_mask, "__builtin_ia32_vpdpwssds_v16si_mask", IX86_BUILTIN_VPDPWSSDSV16SI_MASK, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI, 0, CODE_FOR_vpdpwssds_v16si_maskz, "__builtin_ia32_vpdpwssds_v16si_maskz", IX86_BUILTIN_VPDPWSSDSV16SI_MASKZ, UNKNOWN, (int) V16SI_FTYPE_V16SI_V16SI_V16SI_UHI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si, "__builtin_ia32_vpdpwssds_v8si", IX86_BUILTIN_VPDPWSSDSV8SI, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si_mask, "__builtin_ia32_vpdpwssds_v8si_mask", IX86_BUILTIN_VPDPWSSDSV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si_maskz, "__builtin_ia32_vpdpwssds_v8si_maskz", IX86_BUILTIN_VPDPWSSDSV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si_mask, "__builtin_ia32_vpdpwssds_v8si_mask", IX86_BUILTIN_VPDPWSSDSV8SI_MASK, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v8si_maskz, "__builtin_ia32_vpdpwssds_v8si_maskz", IX86_BUILTIN_VPDPWSSDSV8SI_MASKZ, UNKNOWN, (int) V8SI_FTYPE_V8SI_V8SI_V8SI_UQI)
BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si, "__builtin_ia32_vpdpwssds_v4si", IX86_BUILTIN_VPDPWSSDSV4SI, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si_mask, "__builtin_ia32_vpdpwssds_v4si_mask", IX86_BUILTIN_VPDPWSSDSV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
-BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si_maskz, "__builtin_ia32_vpdpwssds_v4si_maskz", IX86_BUILTIN_VPDPWSSDSV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_INT)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si_mask, "__builtin_ia32_vpdpwssds_v4si_mask", IX86_BUILTIN_VPDPWSSDSV4SI_MASK, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
+BDESC (OPTION_MASK_ISA_AVX512VNNI | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpdpwssds_v4si_maskz, "__builtin_ia32_vpdpwssds_v4si_maskz", IX86_BUILTIN_VPDPWSSDSV4SI_MASKZ, UNKNOWN, (int) V4SI_FTYPE_V4SI_V4SI_V4SI_UQI)
/* VPCLMULQDQ */
BDESC (OPTION_MASK_ISA_VPCLMULQDQ | OPTION_MASK_ISA_AVX512VL, 0, CODE_FOR_vpclmulqdq_v2di, "__builtin_ia32_vpclmulqdq_v2di", IX86_BUILTIN_VPCLMULQDQ2, UNKNOWN, (int) V2DI_FTYPE_V2DI_V2DI_INT)
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 5d3b74a..d50e21e 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -1122,8 +1122,6 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
rtx_insn *insn;
rtx scratch, tmp0, tmp1, tmp2;
rtx (*gen_divmod4_1) (rtx, rtx, rtx, rtx);
- rtx (*gen_zero_extend) (rtx, rtx);
- rtx (*gen_test_ccno_1) (rtx, rtx);
switch (mode)
{
@@ -1135,21 +1133,16 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
else
gen_divmod4_1
= unsigned_p ? gen_udivmodsi4_zext_2 : gen_divmodsi4_zext_2;
- gen_zero_extend = gen_zero_extendqisi2;
}
else
- {
- gen_divmod4_1
- = unsigned_p ? gen_udivmodsi4_zext_1 : gen_divmodsi4_zext_1;
- gen_zero_extend = gen_zero_extendqidi2;
- }
- gen_test_ccno_1 = gen_testsi_ccno_1;
+ gen_divmod4_1
+ = unsigned_p ? gen_udivmodsi4_zext_1 : gen_divmodsi4_zext_1;
break;
+
case E_DImode:
gen_divmod4_1 = unsigned_p ? gen_udivmoddi4_1 : gen_divmoddi4_1;
- gen_test_ccno_1 = gen_testdi_ccno_1;
- gen_zero_extend = gen_zero_extendqidi2;
break;
+
default:
gcc_unreachable ();
}
@@ -1164,7 +1157,7 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
emit_move_insn (scratch, operands[2]);
scratch = expand_simple_binop (mode, IOR, scratch, operands[3],
scratch, 1, OPTAB_DIRECT);
- emit_insn (gen_test_ccno_1 (scratch, GEN_INT (-0x100)));
+ emit_insn (gen_test_ccno_1 (mode, scratch, GEN_INT (-0x100)));
tmp0 = gen_rtx_REG (CCNOmode, FLAGS_REG);
tmp0 = gen_rtx_EQ (VOIDmode, tmp0, const0_rtx);
tmp0 = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp0,
@@ -1227,7 +1220,9 @@ ix86_split_idivmod (machine_mode mode, rtx operands[],
/* Zero extend quotient from AL. */
tmp1 = gen_lowpart (QImode, tmp0);
- insn = emit_insn (gen_zero_extend (operands[0], tmp1));
+ insn = emit_insn (gen_extend_insn
+ (operands[0], tmp1,
+ GET_MODE (operands[0]), QImode, 1));
set_unique_reg_note (insn, REG_EQUAL, div);
emit_label (end_label);
@@ -9573,15 +9568,6 @@ ix86_expand_args_builtin (const struct builtin_description *d,
case USI_FTYPE_V32HI_V32HI_INT_USI:
case UHI_FTYPE_V16HI_V16HI_INT_UHI:
case UQI_FTYPE_V8HI_V8HI_INT_UQI:
- case V32HI_FTYPE_V32HI_V32HI_V32HI_INT:
- case V16HI_FTYPE_V16HI_V16HI_V16HI_INT:
- case V8HI_FTYPE_V8HI_V8HI_V8HI_INT:
- case V8SI_FTYPE_V8SI_V8SI_V8SI_INT:
- case V4DI_FTYPE_V4DI_V4DI_V4DI_INT:
- case V8DI_FTYPE_V8DI_V8DI_V8DI_INT:
- case V16SI_FTYPE_V16SI_V16SI_V16SI_INT:
- case V2DI_FTYPE_V2DI_V2DI_V2DI_INT:
- case V4SI_FTYPE_V4SI_V4SI_V4SI_INT:
nargs = 4;
mask_pos = 1;
nargs_constant = 1;
diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c
index 2eac8f7..6ccd42a 100644
--- a/gcc/config/i386/i386-features.c
+++ b/gcc/config/i386/i386-features.c
@@ -152,7 +152,7 @@ const xlogue_layout xlogue_layout::s_instances[XLOGUE_SET_COUNT] = {
/* Return an appropriate const instance of xlogue_layout based upon values
in cfun->machine and crtl. */
-const struct xlogue_layout &
+const class xlogue_layout &
xlogue_layout::get_instance ()
{
enum xlogue_stub_sets stub_set;
diff --git a/gcc/config/i386/i386-features.h b/gcc/config/i386/i386-features.h
index 3581222..f2c742f 100644
--- a/gcc/config/i386/i386-features.h
+++ b/gcc/config/i386/i386-features.h
@@ -84,7 +84,7 @@ public:
return STUB_INDEX_OFFSET + m_stack_align_off_in;
}
- static const struct xlogue_layout &get_instance ();
+ static const class xlogue_layout &get_instance ();
static unsigned count_stub_managed_regs ();
static bool is_stub_managed_reg (unsigned regno, unsigned count);
diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c
index 6f8851a..a1741c0 100644
--- a/gcc/config/i386/i386-options.c
+++ b/gcc/config/i386/i386-options.c
@@ -2779,7 +2779,11 @@ ix86_option_override_internal (bool main_args_p,
opts->x_flag_cf_protection
= (cf_protection_level) (opts->x_flag_cf_protection | CF_SET);
- if (ix86_tune_features [X86_TUNE_AVOID_128FMA_CHAINS])
+ if (ix86_tune_features [X86_TUNE_AVOID_256FMA_CHAINS])
+ maybe_set_param_value (PARAM_AVOID_FMA_MAX_BITS, 256,
+ opts->x_param_values,
+ opts_set->x_param_values);
+ else if (ix86_tune_features [X86_TUNE_AVOID_128FMA_CHAINS])
maybe_set_param_value (PARAM_AVOID_FMA_MAX_BITS, 128,
opts->x_param_values,
opts_set->x_param_values);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 49f49c5..e278d9c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7689,7 +7689,7 @@ ix86_emit_outlined_ms2sysv_save (const struct ix86_frame &frame)
rtx_insn *insn;
rtx sym, addr;
rtx rax = gen_rtx_REG (word_mode, AX_REG);
- const struct xlogue_layout &xlogue = xlogue_layout::get_instance ();
+ const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
/* AL should only be live with sysv_abi. */
gcc_assert (!ix86_eax_live_at_start_p ());
@@ -8492,7 +8492,7 @@ ix86_emit_outlined_ms2sysv_restore (const struct ix86_frame &frame,
rtx sym, tmp;
rtx rsi = gen_rtx_REG (word_mode, SI_REG);
rtx r10 = NULL_RTX;
- const struct xlogue_layout &xlogue = xlogue_layout::get_instance ();
+ const class xlogue_layout &xlogue = xlogue_layout::get_instance ();
HOST_WIDE_INT stub_ptr_offset = xlogue.get_stub_ptr_offset ();
HOST_WIDE_INT rsi_offset = frame.stack_realign_offset + stub_ptr_offset;
rtx rsi_frame_load = NULL_RTX;
@@ -21503,7 +21503,7 @@ ix86_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
/* Implement targetm.vectorize.init_cost. */
static void *
-ix86_init_cost (struct loop *)
+ix86_init_cost (class loop *)
{
unsigned *cost = XNEWVEC (unsigned, 3);
cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0;
@@ -21514,7 +21514,7 @@ ix86_init_cost (struct loop *)
static unsigned
ix86_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info, int misalign,
+ class _stmt_vec_info *stmt_info, int misalign,
enum vect_cost_model_location where)
{
unsigned *cost = (unsigned *) data;
@@ -21942,7 +21942,7 @@ ix86_simd_clone_usable (struct cgraph_node *node)
(value 32 is used) as a heuristic. */
static unsigned
-ix86_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
+ix86_loop_unroll_adjust (unsigned nunroll, class loop *loop)
{
basic_block *bbs;
rtx_insn *insn;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 1f70844..a2fcdd4 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2417,8 +2417,9 @@ const wide_int_bitmask PTA_KNM = PTA_KNL | PTA_AVX5124VNNIW
#include "insn-attr-common.h"
-struct pta
+class pta
{
+public:
const char *const name; /* processor name or nickname. */
const enum processor_type processor;
const enum attr_cpu schedule;
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c401deb..63f18d7 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1122,6 +1122,12 @@
(SI "x86_64_szext_general_operand")
(DI "x86_64_szext_general_operand")])
+(define_mode_attr nonmemory_szext_operand
+ [(QI "nonmemory_operand")
+ (HI "nonmemory_operand")
+ (SI "x86_64_szext_nonmemory_operand")
+ (DI "x86_64_szext_nonmemory_operand")])
+
;; Immediate operand predicate for integer modes.
(define_mode_attr immediate_operand
[(QI "immediate_operand")
@@ -5331,11 +5337,10 @@
"ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
(define_insn_and_split "*add<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
(plus:<DWI>
(match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
- (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
- "ro<di>,r<di>")))
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
"#"
@@ -5363,10 +5368,10 @@
})
(define_insn "*add<mode>_1"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
(plus:SWI48
(match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
- (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
+ (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
{
@@ -5469,7 +5474,7 @@
(define_insn "*addhi_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
- (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
+ (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, HImode, operands)"
{
@@ -5518,7 +5523,7 @@
(define_insn "*addqi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
- (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
+ (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, QImode, operands)"
{
@@ -5578,41 +5583,39 @@
(symbol_ref "!TARGET_PARTIAL_REG_STALL")]
(symbol_ref "true")))])
-(define_insn "*addqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (plus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qm")))
+(define_insn "*add<mode>_1_slp"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
+ (match_operand:SWI12 2 "general_operand" "<r>mn")))
(clobber (reg:CC FLAGS_REG))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && (rtx_equal_p (operands[0], operands[1])
+ || rtx_equal_p (operands[0], operands[2]))"
{
switch (get_attr_type (insn))
{
case TYPE_INCDEC:
- if (operands[1] == const1_rtx)
- return "inc{b}\t%0";
+ if (operands[2] == const1_rtx)
+ return "inc{<imodesuffix>}\t%0";
else
{
- gcc_assert (operands[1] == constm1_rtx);
- return "dec{b}\t%0";
+ gcc_assert (operands[2] == constm1_rtx);
+ return "dec{<imodesuffix>}\t%0";
}
default:
- if (x86_maybe_negate_const_int (&operands[1], QImode))
- return "sub{b}\t{%1, %0|%0, %1}";
+ if (x86_maybe_negate_const_int (&operands[2], QImode))
+ return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
- return "add{b}\t{%1, %0|%0, %1}";
+ return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (if_then_else (match_operand:QI 1 "incdec_operand")
+ (if_then_else (match_operand:QI 2 "incdec_operand")
(const_string "incdec")
- (const_string "alu1")))
- (set (attr "memory")
- (if_then_else (match_operand 1 "memory_operand")
- (const_string "load")
- (const_string "none")))
- (set_attr "mode" "QI")])
+ (const_string "alu")))
+ (set_attr "mode" "<MODE>")])
;; Split non destructive adds if we cannot use lea.
(define_split
@@ -5674,9 +5677,9 @@
(compare
(plus:SWI
(match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
- (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0"))
(const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
(plus:SWI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCGOCmode)
&& ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
@@ -6067,11 +6070,10 @@
(sign_extend:<DWI>
(match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
(sign_extend:<DWI>
- (match_operand:SWI 2 "<general_sext_operand>"
- "<r>mWe,<r>We")))
+ (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
(sign_extend:<DWI>
(plus:SWI (match_dup 1) (match_dup 2)))))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(plus:SWI (match_dup 1) (match_dup 2)))]
"ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
"add{<imodesuffix>}\t{%2, %0|%0, %2}"
@@ -6085,9 +6087,9 @@
(match_operand:SWI 1 "nonimmediate_operand" "0"))
(match_operand:<DWI> 3 "const_int_operand" "i"))
(sign_extend:<DWI>
- (plus:SWI (match_dup 1)
- (match_operand:SWI 2 "x86_64_immediate_operand"
- "<i>")))))
+ (plus:SWI
+ (match_dup 1)
+ (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
(plus:SWI (match_dup 1) (match_dup 2)))]
"ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
@@ -6291,11 +6293,10 @@
"ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
(define_insn_and_split "*sub<dwi>3_doubleword"
- [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
+ [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
(minus:<DWI>
(match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
- (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
- "ro<di>,r<di>")))
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
"#"
@@ -6324,7 +6325,7 @@
[(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(minus:SWI
(match_operand:SWI 1 "nonimmediate_operand" "0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
"sub{<imodesuffix>}\t{%2, %0|%0, %2}"
@@ -6342,23 +6343,24 @@
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
-(define_insn "*subqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (minus:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qm")))
+(define_insn "*sub<mode>_1_slp"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0")
+ (match_operand:SWI12 2 "general_operand" "<r>mn")))
(clobber (reg:CC FLAGS_REG))]
- "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "sub{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
+ "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && rtx_equal_p (operands[0], operands[1])"
+ "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "<MODE>")])
(define_insn "*sub<mode>_2"
[(set (reg FLAGS_REG)
(compare
(minus:SWI
(match_operand:SWI 1 "nonimmediate_operand" "0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
(const_int 0)))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(minus:SWI (match_dup 1) (match_dup 2)))]
@@ -6416,8 +6418,7 @@
(sign_extend:<DWI>
(match_operand:SWI 1 "nonimmediate_operand" "0,0"))
(sign_extend:<DWI>
- (match_operand:SWI 2 "<general_sext_operand>"
- "<r>We,<r>m")))
+ (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
(sign_extend:<DWI>
(minus:SWI (match_dup 1) (match_dup 2)))))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
@@ -6434,9 +6435,9 @@
(match_operand:SWI 1 "nonimmediate_operand" "0"))
(match_operand:<DWI> 3 "const_int_operand" "i"))
(sign_extend:<DWI>
- (minus:SWI (match_dup 1)
- (match_operand:SWI 2 "x86_64_immediate_operand"
- "<i>")))))
+ (minus:SWI
+ (match_dup 1)
+ (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
(minus:SWI (match_dup 1) (match_dup 2)))]
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
@@ -6469,7 +6470,7 @@
(define_insn "*sub<mode>_3"
[(set (reg FLAGS_REG)
(compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(minus:SWI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCmode)
@@ -6512,7 +6513,7 @@
(match_operator:SWI 4 "ix86_carry_flag_operator"
[(match_operand 3 "flags_reg_operand") (const_int 0)])
(match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
"adc{<imodesuffix>}\t{%2, %0|%0, %2}"
@@ -6612,7 +6613,7 @@
(match_operand:SWI 1 "nonimmediate_operand" "0,0")
(match_operator:SWI 4 "ix86_carry_flag_operator"
[(match_operand 3 "flags_reg_operand") (const_int 0)]))
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
"sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
@@ -6777,7 +6778,7 @@
(compare:CCC
(plus:SWI
(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
(match_dup 1)))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(plus:SWI (match_dup 1) (match_dup 2)))]
@@ -6818,7 +6819,7 @@
(compare:CCC
(plus:SWI
(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
(match_dup 2)))
(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(plus:SWI (match_dup 1) (match_dup 2)))]
@@ -8118,57 +8119,57 @@
;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
;; Note that this excludes ah.
-(define_expand "testsi_ccno_1"
+(define_expand "@test<mode>_ccno_1"
[(set (reg:CCNO FLAGS_REG)
(compare:CCNO
- (and:SI (match_operand:SI 0 "nonimmediate_operand")
- (match_operand:SI 1 "x86_64_nonmemory_operand"))
+ (and:SWI48
+ (match_operand:SWI48 0 "nonimmediate_operand")
+ (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
(const_int 0)))])
(define_expand "testqi_ccz_1"
[(set (reg:CCZ FLAGS_REG)
- (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
- (match_operand:QI 1 "nonmemory_operand"))
- (const_int 0)))])
-
-(define_expand "testdi_ccno_1"
- [(set (reg:CCNO FLAGS_REG)
- (compare:CCNO
- (and:DI (match_operand:DI 0 "nonimmediate_operand")
- (match_operand:DI 1 "x86_64_szext_general_operand"))
- (const_int 0)))]
- "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
+ (compare:CCZ
+ (and:QI
+ (match_operand:QI 0 "nonimmediate_operand")
+ (match_operand:QI 1 "nonmemory_operand"))
+ (const_int 0)))])
(define_insn "*testdi_1"
[(set (reg FLAGS_REG)
(compare
- (and:DI
- (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
- (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
+ (and:DI
+ (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
+ (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
(const_int 0)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "TARGET_64BIT
+ && ix86_match_ccmode
+ (insn,
+ /* If we are going to emit testl instead of testq, and the operands[1]
+ constant might have the SImode sign bit set, make sure the sign
+ flag isn't tested, because the instruction will set the sign flag
+ based on bit 31 rather than bit 63. If it isn't CONST_INT,
+ conservatively assume it might have bit 31 set. */
+ (satisfies_constraint_Z (operands[1])
+ && (!CONST_INT_P (operands[1])
+ || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
+ ? CCZmode : CCNOmode)"
"@
test{l}\t{%k1, %k0|%k0, %k1}
- test{l}\t{%k1, %k0|%k0, %k1}
- test{q}\t{%1, %0|%0, %1}
- test{q}\t{%1, %0|%0, %1}
test{q}\t{%1, %0|%0, %1}"
[(set_attr "type" "test")
- (set_attr "modrm" "0,1,0,1,1")
- (set_attr "mode" "SI,SI,DI,DI,DI")])
+ (set_attr "mode" "SI,DI")])
(define_insn "*testqi_1_maybe_si"
[(set (reg FLAGS_REG)
- (compare
+ (compare
(and:QI
- (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
- (match_operand:QI 1 "general_operand" "n,n,qn,n"))
+ (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
+ (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
(const_int 0)))]
- "!(MEM_P (operands[0]) && MEM_P (operands[1]))
- && ix86_match_ccmode (insn,
- CONST_INT_P (operands[1])
- && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
+ "ix86_match_ccmode (insn,
+ CONST_INT_P (operands[1])
+ && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
{
if (which_alternative == 3)
{
@@ -8179,24 +8180,21 @@
return "test{b}\t{%1, %0|%0, %1}";
}
[(set_attr "type" "test")
- (set_attr "modrm" "0,1,1,1")
(set_attr "mode" "QI,QI,QI,SI")
- (set_attr "pent_pair" "uv,np,uv,np")])
+ (set_attr "pent_pair" "uv,uv,np,np")])
(define_insn "*test<mode>_1"
[(set (reg FLAGS_REG)
(compare
- (and:SWI124
- (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
- (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
+ (and:SWI124
+ (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
+ (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
(const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ "ix86_match_ccmode (insn, CCNOmode)"
"test{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "test")
- (set_attr "modrm" "0,1,1")
(set_attr "mode" "<MODE>")
- (set_attr "pent_pair" "uv,np,uv")])
+ (set_attr "pent_pair" "uv,uv,np")])
(define_expand "testqi_ext_1_ccno"
[(set (reg:CCNO FLAGS_REG)
@@ -8428,7 +8426,7 @@
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
(and:DI
(match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
- (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
+ (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L")))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
"@
@@ -8513,7 +8511,7 @@
(define_insn "*and<mode>_1"
[(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
(and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
- (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
+ (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (AND, <MODE>mode, operands)"
"@
@@ -8534,7 +8532,7 @@
(define_insn "*andqi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
+ (match_operand:QI 2 "general_operand" "qn,m,rn")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (AND, QImode, operands)"
"@
@@ -8549,16 +8547,18 @@
(symbol_ref "!TARGET_PARTIAL_REG_STALL")]
(symbol_ref "true")))])
-(define_insn "*andqi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
- (and:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qn,qmn")))
+(define_insn "*and<mode>_1_slp"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
+ (match_operand:SWI12 2 "general_operand" "<r>mn")))
(clobber (reg:CC FLAGS_REG))]
"(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "and{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && (rtx_equal_p (operands[0], operands[1])
+ || rtx_equal_p (operands[0], operands[2]))"
+ "and{<imodesuffix>}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "<MODE>")])
(define_split
[(set (match_operand:SWI248 0 "register_operand")
@@ -8641,9 +8641,9 @@
(compare
(and:DI
(match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
+ (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
(const_int 0)))
- (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
+ (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
(and:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT
&& ix86_match_ccmode
@@ -8684,9 +8684,9 @@
[(set (reg FLAGS_REG)
(compare (and:QI
(match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qmn,qn,n"))
+ (match_operand:QI 2 "general_operand" "qn,m,n"))
(const_int 0)))
- (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
+ (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
(and:QI (match_dup 1) (match_dup 2)))]
"ix86_binary_operator_ok (AND, QImode, operands)
&& ix86_match_ccmode (insn,
@@ -8702,15 +8702,20 @@
return "and{b}\t{%2, %0|%0, %2}";
}
[(set_attr "type" "alu")
- (set_attr "mode" "QI,QI,SI")])
+ (set_attr "mode" "QI,QI,SI")
+ ;; Potential partial reg stall on alternative 2.
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "2")
+ (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+ (symbol_ref "true")))])
(define_insn "*and<mode>_2"
[(set (reg FLAGS_REG)
(compare (and:SWI124
(match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
+ (match_operand:SWI124 2 "<general_operand>" "<r><i>,m"))
(const_int 0)))
- (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
+ (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
(and:SWI124 (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCNOmode)
&& ix86_binary_operator_ok (AND, <MODE>mode, operands)"
@@ -8718,21 +8723,6 @@
[(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
-(define_insn "*andqi_2_slp"
- [(set (reg FLAGS_REG)
- (compare (and:QI
- (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
- (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
- (const_int 0)))
- (set (strict_low_part (match_dup 0))
- (and:QI (match_dup 0) (match_dup 1)))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "and{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
(define_insn "andqi_ext_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
(const_int 8)
@@ -8998,10 +8988,10 @@
})
(define_insn "*<code><mode>_1"
- [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
+ [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r")
(any_or:SWI248
(match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
+ (match_operand:SWI248 2 "<general_operand>" "r<i>,m")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
@@ -9078,9 +9068,9 @@
(set_attr "mode" "SI")])
(define_insn "*<code>qi_1"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
(any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
+ (match_operand:QI 2 "general_operand" "qn,m,rn")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (<CODE>, QImode, operands)"
"@
@@ -9095,24 +9085,26 @@
(symbol_ref "!TARGET_PARTIAL_REG_STALL")]
(symbol_ref "true")))])
-(define_insn "*<code>qi_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
- (any_or:QI (match_dup 0)
- (match_operand:QI 1 "general_operand" "qmn,qn")))
+(define_insn "*<code><mode>_1_slp"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
+ (match_operand:SWI12 2 "general_operand" "<r>mn")))
(clobber (reg:CC FLAGS_REG))]
"(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "<logic>{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && (rtx_equal_p (operands[0], operands[1])
+ || rtx_equal_p (operands[0], operands[2]))"
+ "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "mode" "<MODE>")])
(define_insn "*<code><mode>_2"
[(set (reg FLAGS_REG)
(compare (any_or:SWI
(match_operand:SWI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
+ (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
(const_int 0)))
- (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
+ (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
(any_or:SWI (match_dup 1) (match_dup 2)))]
"ix86_match_ccmode (insn, CCNOmode)
&& ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
@@ -9149,20 +9141,6 @@
[(set_attr "type" "alu")
(set_attr "mode" "SI")])
-(define_insn "*<code>qi_2_slp"
- [(set (reg FLAGS_REG)
- (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
- (match_operand:QI 1 "general_operand" "qmn,qn"))
- (const_int 0)))
- (set (strict_low_part (match_dup 0))
- (any_or:QI (match_dup 0) (match_dup 1)))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && ix86_match_ccmode (insn, CCNOmode)
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
- "<logic>{b}\t{%1, %0|%0, %1}"
- [(set_attr "type" "alu1")
- (set_attr "mode" "QI")])
-
(define_insn "*<code><mode>_3"
[(set (reg FLAGS_REG)
(compare (any_or:SWI
@@ -10315,48 +10293,45 @@
(symbol_ref "!TARGET_PARTIAL_REG_STALL")]
(symbol_ref "true")))])
-(define_insn "*ashlqi3_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
- (ashift:QI (match_dup 0)
- (match_operand:QI 1 "nonmemory_operand" "cI")))
+(define_insn "*ashl<mode>3_1_slp"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "cI")))
(clobber (reg:CC FLAGS_REG))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_FLAG_REG_STALL
- || (operands[1] == const1_rtx
- && (TARGET_SHIFT1
- || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
+ "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && rtx_equal_p (operands[0], operands[1])"
{
switch (get_attr_type (insn))
{
- case TYPE_ALU1:
- gcc_assert (operands[1] == const1_rtx);
- return "add{b}\t%0, %0";
+ case TYPE_ALU:
+ gcc_assert (operands[2] == const1_rtx);
+ return "add{<imodesuffix>}\t%0, %0";
default:
- if (operands[1] == const1_rtx
+ if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "sal{b}\t%0";
+ return "sal{<imodesuffix>}\t%0";
else
- return "sal{b}\t{%1, %0|%0, %1}";
+ return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
}
}
[(set (attr "type")
- (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
- (match_operand 0 "register_operand"))
- (match_operand 1 "const1_operand"))
- (const_string "alu1")
+ (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
+ (match_operand 2 "const1_operand"))
+ (const_string "alu")
]
- (const_string "ishift1")))
+ (const_string "ishift")))
(set (attr "length_immediate")
(if_then_else
- (ior (eq_attr "type" "alu1")
- (and (eq_attr "type" "ishift1")
- (and (match_operand 1 "const1_operand")
+ (ior (eq_attr "type" "alu")
+ (and (eq_attr "type" "ishift")
+ (and (match_operand 2 "const1_operand")
(ior (match_test "TARGET_SHIFT1")
(match_test "optimize_function_for_size_p (cfun)")))))
(const_string "0")
(const_string "*")))
- (set_attr "mode" "QI")])
+ (set_attr "mode" "<MODE>")])
;; Convert ashift to the lea pattern to avoid flags dependency.
(define_split
@@ -10934,31 +10909,30 @@
(const_string "*")))
(set_attr "mode" "<MODE>")])
-(define_insn "*<shift_insn>qi3_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
- (any_shiftrt:QI (match_dup 0)
- (match_operand:QI 1 "nonmemory_operand" "cI")))
+(define_insn "*<shift_insn><mode>3_1_slp"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "cI")))
(clobber (reg:CC FLAGS_REG))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_REG_STALL
- || (operands[1] == const1_rtx
- && TARGET_SHIFT1))"
+ "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && rtx_equal_p (operands[0], operands[1])"
{
- if (operands[1] == const1_rtx
+ if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<shift>{b}\t%0";
+ return "<shift>{<imodesuffix>}\t%0";
else
- return "<shift>{b}\t{%1, %0|%0, %1}";
+ return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
}
- [(set_attr "type" "ishift1")
+ [(set_attr "type" "ishift")
(set (attr "length_immediate")
(if_then_else
- (and (match_operand 1 "const1_operand")
+ (and (match_operand 2 "const1_operand")
(ior (match_test "TARGET_SHIFT1")
(match_test "optimize_function_for_size_p (cfun)")))
(const_string "0")
(const_string "*")))
- (set_attr "mode" "QI")])
+ (set_attr "mode" "<MODE>")])
;; This pattern can't accept a variable shift count, since shifts by
;; zero don't affect the flags. We assume that shifts by constant
@@ -11363,31 +11337,30 @@
(const_string "*")))
(set_attr "mode" "<MODE>")])
-(define_insn "*<rotate_insn>qi3_1_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
- (any_rotate:QI (match_dup 0)
- (match_operand:QI 1 "nonmemory_operand" "cI")))
+(define_insn "*<rotate_insn><mode>3_1_slp"
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "cI")))
(clobber (reg:CC FLAGS_REG))]
- "(optimize_function_for_size_p (cfun)
- || !TARGET_PARTIAL_REG_STALL
- || (operands[1] == const1_rtx
- && TARGET_SHIFT1))"
+ "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
+ /* FIXME: without this LRA can't reload this pattern, see PR82524. */
+ && rtx_equal_p (operands[0], operands[1])"
{
- if (operands[1] == const1_rtx
+ if (operands[2] == const1_rtx
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
- return "<rotate>{b}\t%0";
+ return "<rotate>{<imodesuffix>}\t%0";
else
- return "<rotate>{b}\t{%1, %0|%0, %1}";
+ return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
}
- [(set_attr "type" "rotate1")
+ [(set_attr "type" "rotate")
(set (attr "length_immediate")
(if_then_else
- (and (match_operand 1 "const1_operand")
+ (and (match_operand 2 "const1_operand")
(ior (match_test "TARGET_SHIFT1")
(match_test "optimize_function_for_size_p (cfun)")))
(const_string "0")
(const_string "*")))
- (set_attr "mode" "QI")])
+ (set_attr "mode" "<MODE>")])
(define_split
[(set (match_operand:HI 0 "QIreg_operand")
@@ -14755,7 +14728,7 @@
]
(const_string "fop")))
(set_attr "fp_int_src" "true")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<SWI24:MODE>")])
(define_insn "*fop_xf_4_i387"
[(set (match_operand:XF 0 "register_operand" "=f,f")
@@ -16457,7 +16430,7 @@
{
rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
- emit_insn (gen_sse4_1_round<mode>2
+ emit_insn (gen_sse4_1_round<MODEF:mode>2
(tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
| ROUND_NO_EXC)));
emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 4c71e66..c78b33b 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -1158,6 +1158,14 @@
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(define_expand "one_cmpl<mode>2"
+ [(set (match_operand:MMXMODEI 0 "register_operand")
+ (xor:MMXMODEI
+ (match_operand:MMXMODEI 1 "register_operand")
+ (match_dup 2)))]
+ "TARGET_MMX_WITH_SSE"
+ "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));")
+
(define_insn "mmx_andnot<mode>3"
[(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
(and:MMXMODEI
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 8f50cb1..fa8f13f 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -853,6 +853,13 @@
(V4SF "k") (V2DF "q")
(SF "k") (DF "q")])
+;; Mapping of vector modes to VPTERNLOG suffix
+(define_mode_attr ternlogsuffix
+ [(V8DI "q") (V4DI "q") (V2DI "q")
+ (V16SI "d") (V8SI "d") (V4SI "d")
+ (V32HI "d") (V16HI "d") (V8HI "d")
+ (V64QI "d") (V32QI "d") (V16QI "d")])
+
;; Number of scalar elements in each vector type
(define_mode_attr ssescalarnum
[(V64QI "64") (V16SI "16") (V8DI "8")
@@ -5927,16 +5934,16 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "OI")])
-(define_insn "sse2_cvtpd2dq<mask_name>"
+(define_insn "sse2_cvtpd2dq"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(unspec:V2SI [(match_operand:V2DF 1 "vector_operand" "vBm")]
UNSPEC_FIX_NOTRUNC)
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
- "TARGET_SSE2 && <mask_avx512vl_condition>"
+ "TARGET_SSE2"
{
if (TARGET_AVX)
- return "vcvtpd2dq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
+ return "vcvtpd2dq{x}\t{%1, %0|%0, %1}";
else
return "cvtpd2dq\t{%1, %0|%0, %1}";
}
@@ -5949,6 +5956,38 @@
(set_attr "athlon_decode" "vector")
(set_attr "bdver1_decode" "double")])
+(define_insn "sse2_cvtpd2dq_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_FIX_NOTRUNC)
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2dq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*sse2_cvtpd2dq_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_FIX_NOTRUNC)
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2dq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
;; For ufix_notrunc* insn patterns
(define_mode_attr pd2udqsuff
[(V8DF "") (V4DF "{y}")])
@@ -5964,15 +6003,49 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "ufix_notruncv2dfv2si2<mask_name>"
+(define_insn "ufix_notruncv2dfv2si2"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(unspec:V2SI
[(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
- UNSPEC_UNSIGNED_FIX_NOTRUNC)
+ UNSPEC_UNSIGNED_FIX_NOTRUNC)
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2udq{x}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "ufix_notruncv2dfv2si2_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI
+ [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_UNSIGNED_FIX_NOTRUNC)
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvtpd2udq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*ufix_notruncv2dfv2si2_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unspec:V2SI
+ [(match_operand:V2DF 1 "nonimmediate_operand" "vm")]
+ UNSPEC_UNSIGNED_FIX_NOTRUNC)
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
"TARGET_AVX512VL"
- "vcvtpd2udq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vcvtpd2udq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
@@ -5987,13 +6060,43 @@
(set_attr "prefix" "evex")
(set_attr "mode" "OI")])
-(define_insn "ufix_truncv2dfv2si2<mask_name>"
+(define_insn "ufix_truncv2dfv2si2"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(unsigned_fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
"TARGET_AVX512VL"
- "vcvttpd2udq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vcvttpd2udq{x}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "ufix_truncv2dfv2si2_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unsigned_fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2udq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*ufix_truncv2dfv2si2_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (unsigned_fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2udq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
@@ -6138,15 +6241,15 @@
"TARGET_AVX"
"operands[2] = CONST0_RTX (V4SImode);")
-(define_insn "sse2_cvttpd2dq<mask_name>"
+(define_insn "sse2_cvttpd2dq"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(vec_concat:V4SI
(fix:V2SI (match_operand:V2DF 1 "vector_operand" "vBm"))
(const_vector:V2SI [(const_int 0) (const_int 0)])))]
- "TARGET_SSE2 && <mask_avx512vl_condition>"
+ "TARGET_SSE2"
{
if (TARGET_AVX)
- return "vcvttpd2dq{x}\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}";
+ return "vcvttpd2dq{x}\t{%1, %0|%0, %1}";
else
return "cvttpd2dq\t{%1, %0|%0, %1}";
}
@@ -6157,6 +6260,36 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
+(define_insn "sse2_cvttpd2dq_mask"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2dq{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*sse2_cvttpd2dq_mask_1"
+ [(set (match_operand:V4SI 0 "register_operand" "=v")
+ (vec_concat:V4SI
+ (vec_merge:V2SI
+ (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (const_vector:V2SI [(const_int 0) (const_int 0)])))]
+ "TARGET_AVX512VL"
+ "vcvttpd2dq{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "TI")])
+
(define_insn "sse2_cvtsd2ss<round_name>"
[(set (match_operand:V4SF 0 "register_operand" "=x,x,v")
(vec_merge:V4SF
@@ -6276,26 +6409,28 @@
(define_expand "sse2_cvtpd2ps_mask"
[(set (match_operand:V4SF 0 "register_operand")
- (vec_merge:V4SF
- (vec_concat:V4SF
+ (vec_concat:V4SF
+ (vec_merge:V2SF
(float_truncate:V2SF
(match_operand:V2DF 1 "vector_operand"))
- (match_dup 4))
- (match_operand:V4SF 2 "register_operand")
- (match_operand:QI 3 "register_operand")))]
+ (vec_select:V2SF
+ (match_operand:V4SF 2 "nonimm_or_0_operand")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand"))
+ (match_dup 4)))]
"TARGET_SSE2"
"operands[4] = CONST0_RTX (V2SFmode);")
-(define_insn "*sse2_cvtpd2ps<mask_name>"
+(define_insn "*sse2_cvtpd2ps"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(vec_concat:V4SF
(float_truncate:V2SF
(match_operand:V2DF 1 "vector_operand" "vBm"))
- (match_operand:V2SF 2 "const0_operand")))]
- "TARGET_SSE2 && <mask_avx512vl_condition>"
+ (match_operand:V2SF 2 "const0_operand" "C")))]
+ "TARGET_SSE2"
{
if (TARGET_AVX)
- return "vcvtpd2ps{x}\t{%1, %0<mask_operand3>|%0<mask_operand3>, %1}";
+ return "vcvtpd2ps{x}\t{%1, %0|%0, %1}";
else
return "cvtpd2ps\t{%1, %0|%0, %1}";
}
@@ -6307,6 +6442,38 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "V4SF")])
+(define_insn "*sse2_cvtpd2ps_mask"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (vec_concat:V4SF
+ (vec_merge:V2SF
+ (float_truncate:V2SF
+ (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (vec_select:V2SF
+ (match_operand:V4SF 2 "nonimm_or_0_operand" "0C")
+ (parallel [(const_int 0) (const_int 1)]))
+ (match_operand:QI 3 "register_operand" "Yk"))
+ (match_operand:V2SF 4 "const0_operand" "C")))]
+ "TARGET_AVX512VL"
+ "vcvtpd2ps{x}\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "*sse2_cvtpd2ps_mask_1"
+ [(set (match_operand:V4SF 0 "register_operand" "=v")
+ (vec_concat:V4SF
+ (vec_merge:V2SF
+ (float_truncate:V2SF
+ (match_operand:V2DF 1 "nonimmediate_operand" "vm"))
+ (match_operand:V2SF 3 "const0_operand" "C")
+ (match_operand:QI 2 "register_operand" "Yk"))
+ (match_operand:V2SF 4 "const0_operand" "C")))]
+ "TARGET_AVX512VL"
+ "vcvtpd2ps{x}\t{%1, %0%{%2%}%{z%}|%0%{%2%}%{z%}, %1}"
+ [(set_attr "type" "ssecvt")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "V4SF")])
+
;; For <sse2_avx_avx512f>_cvtps2pd<avxsizesuffix> insn pattern
(define_mode_attr sf2dfmode
[(V8DF "V8SF") (V4DF "V4SF")])
@@ -6398,21 +6565,25 @@
(match_dup 2)
(match_dup 3)
(match_operand:<avx512fmaskmode> 1 "register_operand")))]
- "TARGET_AVX512DQ"
+ "TARGET_AVX512F"
"{
operands[2] = CONSTM1_RTX (<MODE>mode);
operands[3] = CONST0_RTX (<MODE>mode);
}")
(define_insn "*<avx512>_cvtmask2<ssemodesuffix><mode>"
- [(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v")
+ [(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v,v")
(vec_merge:VI48_AVX512VL
(match_operand:VI48_AVX512VL 2 "vector_all_ones_operand")
(match_operand:VI48_AVX512VL 3 "const0_operand")
- (match_operand:<avx512fmaskmode> 1 "register_operand" "k")))]
- "TARGET_AVX512DQ"
- "vpmovm2<ssemodesuffix>\t{%1, %0|%0, %1}"
- [(set_attr "prefix" "evex")
+ (match_operand:<avx512fmaskmode> 1 "register_operand" "k,Yk")))]
+ "TARGET_AVX512F"
+ "@
+ vpmovm2<ssemodesuffix>\t{%1, %0|%0, %1}
+ vpternlog<ssemodesuffix>\t{$0x81, %0, %0, %0%{%1%}%{z%}|%0%{%1%}%{z%}, %0, %0, 0x81}"
+ [(set_attr "isa" "avx512dq,*")
+ (set_attr "length_immediate" "0,1")
+ (set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "sse2_cvtps2pd<mask_name>"
@@ -12563,9 +12734,22 @@
(match_dup 2)))]
"TARGET_SSE"
{
- operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
+ if (!TARGET_AVX512F)
+ operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));
+ else
+ operands[2] = CONSTM1_RTX (<MODE>mode);
})
+(define_insn "<mask_codefor>one_cmpl<mode>2<mask_name>"
+ [(set (match_operand:VI 0 "register_operand" "=v")
+ (xor:VI (match_operand:VI 1 "nonimmediate_operand" "vm")
+ (match_operand:VI 2 "vector_all_ones_operand" "BC")))]
+ "TARGET_AVX512F"
+ "vpternlog<ternlogsuffix>\t{$0x55, %1, %0, %0<mask_operand3>|%0<mask_operand3>, %0, %1, 0x55}"
+ [(set_attr "type" "sselog")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_expand "<sse2_avx2>_andnot<mode>3"
[(set (match_operand:VI_AVX2 0 "register_operand")
(and:VI_AVX2
@@ -12702,8 +12886,8 @@
(const_string "<sseinsnmode>")))])
(define_insn "*andnot<mode>3_bcst"
- [(set (match_operand:VI 0 "register_operand" "=v")
- (and:VI
+ [(set (match_operand:VI48_AVX512VL 0 "register_operand" "=v")
+ (and:VI48_AVX512VL
(not:VI48_AVX512VL
(match_operand:VI48_AVX512VL 1 "register_operand" "v"))
(vec_duplicate:VI48_AVX512VL
@@ -16784,10 +16968,9 @@
(unspec:VF_128_256
[(match_operand:VF_128_256 1 "register_operand" "0,0,x")
(match_operand:VF_128_256 2 "vector_operand" "YrBm,*xBm,xm")
- (subreg:VF_128_256
- (lt:<sseintvecmode>
- (match_operand:<sseintvecmode> 3 "register_operand" "Yz,Yz,x")
- (match_operand:<sseintvecmode> 4 "const0_operand" "C,C,C")) 0)]
+ (lt:VF_128_256
+ (match_operand:<sseintvecmode> 3 "register_operand" "Yz,Yz,x")
+ (match_operand:<sseintvecmode> 4 "const0_operand" "C,C,C"))]
UNSPEC_BLENDV))]
"TARGET_SSE4_1"
"#"
@@ -18085,7 +18268,7 @@
operands[3]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512pf_gatherpf<mode>sf_mask"
+(define_insn "*avx512pf_gatherpf<VI48_512:mode>sf_mask"
[(unspec
[(match_operand:<avx512fmaskmode> 0 "register_operand" "Yk")
(match_operator:<GATHER_SCATTER_SF_MEM_MODE> 5 "vsib_mem_operator"
@@ -18132,7 +18315,7 @@
operands[3]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512pf_gatherpf<mode>df_mask"
+(define_insn "*avx512pf_gatherpf<VI4_256_8_512:mode>df_mask"
[(unspec
[(match_operand:<avx512fmaskmode> 0 "register_operand" "Yk")
(match_operator:V8DF 5 "vsib_mem_operator"
@@ -18179,7 +18362,7 @@
operands[3]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512pf_scatterpf<mode>sf_mask"
+(define_insn "*avx512pf_scatterpf<VI48_512:mode>sf_mask"
[(unspec
[(match_operand:<avx512fmaskmode> 0 "register_operand" "Yk")
(match_operator:<GATHER_SCATTER_SF_MEM_MODE> 5 "vsib_mem_operator"
@@ -18228,7 +18411,7 @@
operands[3]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512pf_scatterpf<mode>df_mask"
+(define_insn "*avx512pf_scatterpf<VI4_256_8_512:mode>df_mask"
[(unspec
[(match_operand:<avx512fmaskmode> 0 "register_operand" "Yk")
(match_operator:V8DF 5 "vsib_mem_operator"
@@ -21017,7 +21200,7 @@
operands[5]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx2_gathersi<mode>"
+(define_insn "*avx2_gathersi<VEC_GATHER_MODE:mode>"
[(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "=&x")
(unspec:VEC_GATHER_MODE
[(match_operand:VEC_GATHER_MODE 2 "register_operand" "0")
@@ -21037,7 +21220,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "*avx2_gathersi<mode>_2"
+(define_insn "*avx2_gathersi<VEC_GATHER_MODE:mode>_2"
[(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "=&x")
(unspec:VEC_GATHER_MODE
[(pc)
@@ -21078,7 +21261,7 @@
operands[5]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx2_gatherdi<mode>"
+(define_insn "*avx2_gatherdi<VEC_GATHER_MODE:mode>"
[(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "=&x")
(unspec:VEC_GATHER_MODE
[(match_operand:<VEC_GATHER_SRCDI> 2 "register_operand" "0")
@@ -21098,7 +21281,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "*avx2_gatherdi<mode>_2"
+(define_insn "*avx2_gatherdi<VEC_GATHER_MODE:mode>_2"
[(set (match_operand:VEC_GATHER_MODE 0 "register_operand" "=&x")
(unspec:VEC_GATHER_MODE
[(pc)
@@ -21114,7 +21297,7 @@
(clobber (match_scratch:VEC_GATHER_MODE 1 "=&x"))]
"TARGET_AVX2"
{
- if (<MODE>mode != <VEC_GATHER_SRCDI>mode)
+ if (<VEC_GATHER_MODE:MODE>mode != <VEC_GATHER_SRCDI>mode)
return "%M2v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %x0|%x0, %6, %4}";
return "%M2v<sseintprefix>gatherq<ssemodesuffix>\t{%4, %6, %0|%0, %6, %4}";
}
@@ -21122,7 +21305,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "*avx2_gatherdi<mode>_3"
+(define_insn "*avx2_gatherdi<VI4F_256:mode>_3"
[(set (match_operand:<VEC_GATHER_SRCDI> 0 "register_operand" "=&x")
(vec_select:<VEC_GATHER_SRCDI>
(unspec:VI4F_256
@@ -21145,7 +21328,7 @@
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "*avx2_gatherdi<mode>_4"
+(define_insn "*avx2_gatherdi<VI4F_256:mode>_4"
[(set (match_operand:<VEC_GATHER_SRCDI> 0 "register_operand" "=&x")
(vec_select:<VEC_GATHER_SRCDI>
(unspec:VI4F_256
@@ -21187,7 +21370,7 @@
operands[5]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512f_gathersi<mode>"
+(define_insn "*avx512f_gathersi<VI48F:mode>"
[(set (match_operand:VI48F 0 "register_operand" "=&v")
(unspec:VI48F
[(match_operand:VI48F 1 "register_operand" "0")
@@ -21208,7 +21391,7 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "*avx512f_gathersi<mode>_2"
+(define_insn "*avx512f_gathersi<VI48F:mode>_2"
[(set (match_operand:VI48F 0 "register_operand" "=&v")
(unspec:VI48F
[(pc)
@@ -21249,7 +21432,7 @@
operands[5]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512f_gatherdi<mode>"
+(define_insn "*avx512f_gatherdi<VI48F:mode>"
[(set (match_operand:VI48F 0 "register_operand" "=&v")
(unspec:VI48F
[(match_operand:<VEC_GATHER_SRCDI> 1 "register_operand" "0")
@@ -21270,7 +21453,7 @@
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "*avx512f_gatherdi<mode>_2"
+(define_insn "*avx512f_gatherdi<VI48F:mode>_2"
[(set (match_operand:VI48F 0 "register_operand" "=&v")
(unspec:VI48F
[(pc)
@@ -21287,9 +21470,9 @@
{
/* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
gas changed what it requires incompatibly. */
- if (<MODE>mode != <VEC_GATHER_SRCDI>mode)
+ if (<VI48F:MODE>mode != <VEC_GATHER_SRCDI>mode)
{
- if (<MODE_SIZE> != 64)
+ if (<VI48F:MODE_SIZE> != 64)
return "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %x0%{%1%}|%x0%{%1%}, %X5}";
else
return "%M3v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %t0%{%1%}|%t0%{%1%}, %X5}";
@@ -21318,7 +21501,7 @@
operands[4]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512f_scattersi<mode>"
+(define_insn "*avx512f_scattersi<VI48F:mode>"
[(set (match_operator:VI48F 5 "vsib_mem_operator"
[(unspec:P
[(match_operand:P 0 "vsib_address_operand" "Tv")
@@ -21356,7 +21539,7 @@
operands[4]), UNSPEC_VSIBADDR);
})
-(define_insn "*avx512f_scatterdi<mode>"
+(define_insn "*avx512f_scatterdi<VI48F:mode>"
[(set (match_operator:VI48F 5 "vsib_mem_operator"
[(unspec:P
[(match_operand:P 0 "vsib_address_operand" "Tv")
diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h
index ac06e37..8b963c0 100644
--- a/gcc/config/i386/x86-tune-costs.h
+++ b/gcc/config/i386/x86-tune-costs.h
@@ -1279,12 +1279,12 @@ struct processor_costs znver1_cost = {
static stringop_algs znver2_memcpy[2] = {
{libcall, {{6, loop, false}, {14, unrolled_loop, false},
{-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {libcall, {{16, loop, false}, {64, rep_prefix_4_byte, false},
{-1, libcall, false}}}};
static stringop_algs znver2_memset[2] = {
{libcall, {{8, loop, false}, {24, unrolled_loop, false},
{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
+ {libcall, {{24, rep_prefix_4_byte, false}, {128, rep_prefix_8_byte, false},
{-1, libcall, false}}}};
struct processor_costs znver2_cost = {
@@ -1335,11 +1335,11 @@ struct processor_costs znver2_cost = {
in SImode and DImode. */
{8, 8}, /* cost of storing MMX registers
in SImode and DImode. */
- 2, 3, 6, /* cost of moving XMM,YMM,ZMM
+ 2, 2, 3, /* cost of moving XMM,YMM,ZMM
register. */
- {6, 6, 6, 10, 20}, /* cost of loading SSE registers
+ {6, 6, 6, 6, 12}, /* cost of loading SSE registers
in 32,64,128,256 and 512-bit. */
- {6, 6, 6, 10, 20}, /* cost of unaligned loads. */
+ {6, 6, 6, 6, 12}, /* cost of unaligned loads. */
{8, 8, 8, 8, 16}, /* cost of storing SSE registers
in 32,64,128,256 and 512-bit. */
{8, 8, 8, 8, 16}, /* cost of unaligned stores. */
@@ -1372,7 +1372,7 @@ struct processor_costs znver2_cost = {
COSTS_N_INSNS (1), /* cost of cheap SSE instruction. */
COSTS_N_INSNS (3), /* cost of ADDSS/SD SUBSS/SD insns. */
COSTS_N_INSNS (3), /* cost of MULSS instruction. */
- COSTS_N_INSNS (4), /* cost of MULSD instruction. */
+ COSTS_N_INSNS (3), /* cost of MULSD instruction. */
COSTS_N_INSNS (5), /* cost of FMA SS instruction. */
COSTS_N_INSNS (5), /* cost of FMA SD instruction. */
COSTS_N_INSNS (10), /* cost of DIVSS instruction. */
diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def
index 01e4986..fd59a84 100644
--- a/gcc/config/i386/x86-tune.def
+++ b/gcc/config/i386/x86-tune.def
@@ -431,6 +431,10 @@ DEF_TUNE (X86_TUNE_USE_GATHER, "use_gather",
smaller FMA chain. */
DEF_TUNE (X86_TUNE_AVOID_128FMA_CHAINS, "avoid_fma_chains", m_ZNVER)
+/* X86_TUNE_AVOID_256FMA_CHAINS: Avoid creating loops with tight 256bit or
+ smaller FMA chain. */
+DEF_TUNE (X86_TUNE_AVOID_256FMA_CHAINS, "avoid_fma256_chains", m_ZNVER2)
+
/*****************************************************************************/
/* AVX instruction selection tuning (some of SSE flags affects AVX, too) */
/*****************************************************************************/
diff --git a/gcc/config/i386/znver1.md b/gcc/config/i386/znver1.md
index c7f49bf..7e3efa8 100644
--- a/gcc/config/i386/znver1.md
+++ b/gcc/config/i386/znver1.md
@@ -17,10 +17,11 @@
;; <http://www.gnu.org/licenses/>.
;;
+
(define_attr "znver1_decode" "direct,vector,double"
(const_string "direct"))
-;; AMD znver1 Scheduling
+;; AMD znver1 and znver2 Scheduling
;; Modeling automatons for zen decoders, integer execution pipes,
;; AGU pipes and floating point execution units.
(define_automaton "znver1, znver1_ieu, znver1_fp, znver1_agu")
@@ -51,13 +52,21 @@
(define_cpu_unit "znver1-ieu3" "znver1_ieu")
(define_reservation "znver1-ieu" "znver1-ieu0|znver1-ieu1|znver1-ieu2|znver1-ieu3")
-;; 2 AGU pipes.
+;; 2 AGU pipes in znver1 and 3 AGU pipes in znver2
+;; According to CPU diagram last AGU unit is used only for stores.
(define_cpu_unit "znver1-agu0" "znver1_agu")
(define_cpu_unit "znver1-agu1" "znver1_agu")
+(define_cpu_unit "znver2-agu2" "znver1_agu")
(define_reservation "znver1-agu-reserve" "znver1-agu0|znver1-agu1")
+(define_reservation "znver2-store-agu-reserve" "znver1-agu0|znver1-agu1|znver2-agu2")
+;; Load is 4 cycles. We do not model reservation of load unit.
+;;(define_reservation "znver1-load" "znver1-agu-reserve, nothing, nothing, nothing")
(define_reservation "znver1-load" "znver1-agu-reserve")
+;; Store operations differs between znver1 and znver2 because extra AGU
+;; was added.
(define_reservation "znver1-store" "znver1-agu-reserve")
+(define_reservation "znver2-store" "znver2-store-agu-reserve")
;; vectorpath (microcoded) instructions are single issue instructions.
;; So, they occupy all the integer units.
@@ -65,6 +74,9 @@
+znver1-ieu2+znver1-ieu3
+znver1-agu0+znver1-agu1")
+(define_reservation "znver2-ivector" "znver1-ieu0+znver1-ieu1
+ +znver1-ieu2+znver1-ieu3
+ +znver1-agu0+znver1-agu1+znver2-agu2")
;; Floating point unit 4 FP pipes.
(define_cpu_unit "znver1-fp0" "znver1_fp")
(define_cpu_unit "znver1-fp1" "znver1_fp")
@@ -76,6 +88,9 @@
(define_reservation "znver1-fvector" "znver1-fp0+znver1-fp1
+znver1-fp2+znver1-fp3
+znver1-agu0+znver1-agu1")
+(define_reservation "znver2-fvector" "znver1-fp0+znver1-fp1
+ +znver1-fp2+znver1-fp3
+ +znver1-agu0+znver1-agu1+znver2-agu2")
;; Call instruction
(define_insn_reservation "znver1_call" 1
@@ -83,27 +98,36 @@
(eq_attr "type" "call,callv"))
"znver1-double,znver1-store,znver1-ieu0|znver1-ieu3")
+(define_insn_reservation "znver2_call" 1
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "type" "call,callv"))
+ "znver1-double,znver2-store,znver1-ieu0|znver1-ieu3")
+
;; General instructions
(define_insn_reservation "znver1_push" 1
(and (eq_attr "cpu" "znver1")
(and (eq_attr "type" "push")
- (eq_attr "memory" "none,unknown")))
+ (eq_attr "memory" "store")))
"znver1-direct,znver1-store")
-
-(define_insn_reservation "znver1_push_store" 1
- (and (eq_attr "cpu" "znver1")
+(define_insn_reservation "znver2_push" 1
+ (and (eq_attr "cpu" "znver2")
(and (eq_attr "type" "push")
(eq_attr "memory" "store")))
"znver1-direct,znver1-store")
-(define_insn_reservation "znver1_push_both" 5
+(define_insn_reservation "znver1_push_load" 4
(and (eq_attr "cpu" "znver1")
(and (eq_attr "type" "push")
(eq_attr "memory" "both")))
"znver1-direct,znver1-load,znver1-store")
+(define_insn_reservation "znver2_push_load" 4
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "push")
+ (eq_attr "memory" "both")))
+ "znver1-direct,znver1-load,znver2-store")
(define_insn_reservation "znver1_pop" 4
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "pop")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load")
@@ -113,24 +137,33 @@
(and (eq_attr "type" "pop")
(eq_attr "memory" "both")))
"znver1-direct,znver1-load,znver1-store")
+(define_insn_reservation "znver2_pop_mem" 4
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "pop")
+ (eq_attr "memory" "both")))
+ "znver1-direct,znver1-load,znver2-store")
;; Leave
(define_insn_reservation "znver1_leave" 1
(and (eq_attr "cpu" "znver1")
(eq_attr "type" "leave"))
"znver1-double,znver1-ieu, znver1-store")
+(define_insn_reservation "znver2_leave" 1
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "type" "leave"))
+ "znver1-double,znver1-ieu, znver2-store")
;; Integer Instructions or General instructions
;; Multiplications
;; Reg operands
(define_insn_reservation "znver1_imul" 3
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "imul")
(eq_attr "memory" "none")))
"znver1-direct,znver1-ieu1")
(define_insn_reservation "znver1_imul_mem" 7
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "imul")
(eq_attr "memory" "!none")))
"znver1-direct,znver1-load, znver1-ieu1")
@@ -138,28 +171,28 @@
;; Divisions
;; Reg operands
(define_insn_reservation "znver1_idiv_DI" 41
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "DI")
(eq_attr "memory" "none"))))
"znver1-double,znver1-ieu2*41")
(define_insn_reservation "znver1_idiv_SI" 25
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "SI")
(eq_attr "memory" "none"))))
"znver1-double,znver1-ieu2*25")
(define_insn_reservation "znver1_idiv_HI" 17
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "HI")
(eq_attr "memory" "none"))))
"znver1-double,znver1-ieu2*17")
(define_insn_reservation "znver1_idiv_QI" 12
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "QI")
(eq_attr "memory" "none"))))
@@ -167,28 +200,28 @@
;; Mem operands
(define_insn_reservation "znver1_idiv_mem_DI" 45
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "DI")
(eq_attr "memory" "none"))))
"znver1-double,znver1-load,znver1-ieu2*41")
(define_insn_reservation "znver1_idiv_mem_SI" 29
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "SI")
(eq_attr "memory" "none"))))
"znver1-double,znver1-load,znver1-ieu2*25")
(define_insn_reservation "znver1_idiv_mem_HI" 21
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "HI")
(eq_attr "memory" "none"))))
"znver1-double,znver1-load,znver1-ieu2*17")
(define_insn_reservation "znver1_idiv_mem_QI" 16
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "idiv")
(and (eq_attr "mode" "QI")
(eq_attr "memory" "none"))))
@@ -201,16 +234,34 @@
(and (eq_attr "type" "str,ishift")
(eq_attr "memory" "both,store")))
"znver1-vector,znver1-ivector")
+
+(define_insn_reservation "znver2_str_ishift" 3
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "ishift")
+ (eq_attr "memory" "both,store")))
+ "znver1-vector,znver1-ivector")
+(define_insn_reservation "znver2_str_istr" 19
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "str")
+ (eq_attr "memory" "both,store")))
+ "znver1-vector,znver1-ivector")
;; MOV - integer moves
(define_insn_reservation "znver1_load_imov_double" 2
(and (eq_attr "cpu" "znver1")
(and (eq_attr "znver1_decode" "double")
(and (eq_attr "type" "imovx")
(eq_attr "memory" "none"))))
- "znver1-double,znver1-ieu")
+ "znver1-double,znver1-ieu|znver1-ieu")
+
+(define_insn_reservation "znver2_load_imov_double" 1
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "znver1_decode" "double")
+ (and (eq_attr "type" "imovx")
+ (eq_attr "memory" "none"))))
+ "znver1-double,znver1-ieu|znver1-ieu")
(define_insn_reservation "znver1_load_imov_direct" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "imov,imovx")
(eq_attr "memory" "none")))
"znver1-direct,znver1-ieu")
@@ -220,7 +271,14 @@
(and (eq_attr "znver1_decode" "double")
(and (eq_attr "type" "imovx")
(eq_attr "memory" "store"))))
- "znver1-double,znver1-ieu,znver1-store")
+ "znver1-double,znver1-ieu|znver1-ieu,znver1-store")
+
+(define_insn_reservation "znver2_load_imov_double_store" 1
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "znver1_decode" "double")
+ (and (eq_attr "type" "imovx")
+ (eq_attr "memory" "store"))))
+ "znver1-double,znver1-ieu|znver1-ieu,znver2-store")
(define_insn_reservation "znver1_load_imov_direct_store" 1
(and (eq_attr "cpu" "znver1")
@@ -228,15 +286,28 @@
(eq_attr "memory" "store")))
"znver1-direct,znver1-ieu,znver1-store")
+(define_insn_reservation "znver2_load_imov_direct_store" 1
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "imov,imovx")
+ (eq_attr "memory" "store")))
+ "znver1-direct,znver1-ieu,znver2-store")
+
(define_insn_reservation "znver1_load_imov_double_load" 5
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "znver1_decode" "double")
(and (eq_attr "type" "imovx")
(eq_attr "memory" "load"))))
- "znver1-double,znver1-load")
+ "znver1-double,znver1-load,znver1-ieu|znver1-ieu")
+
+(define_insn_reservation "znver2_load_imov_double_load" 4
+ (and (eq_attr "cpu" "znver1,znver2")
+ (and (eq_attr "znver1_decode" "double")
+ (and (eq_attr "type" "imovx")
+ (eq_attr "memory" "load"))))
+ "znver1-double,znver1-load,znver1-ieu|znver1-ieu")
(define_insn_reservation "znver1_load_imov_direct_load" 4
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "imov,imovx")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load")
@@ -244,13 +315,13 @@
;; INTEGER/GENERAL instructions
;; register/imm operands only: ALU, ICMP, NEG, NOT, ROTATE, ISHIFT, TEST
(define_insn_reservation "znver1_insn" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift,ishift1,test,setcc,incdec,icmov")
(eq_attr "memory" "none,unknown")))
"znver1-direct,znver1-ieu")
(define_insn_reservation "znver1_insn_load" 5
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift,ishift1,test,setcc,incdec,icmov")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-ieu")
@@ -261,18 +332,35 @@
(eq_attr "memory" "store")))
"znver1-direct,znver1-ieu,znver1-store")
+(define_insn_reservation "znver2_insn_store" 1
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift1,test,setcc,incdec")
+ (eq_attr "memory" "store")))
+ "znver1-direct,znver1-ieu,znver2-store")
+
(define_insn_reservation "znver1_insn_both" 5
(and (eq_attr "cpu" "znver1")
(and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift1,test,setcc,incdec")
(eq_attr "memory" "both")))
"znver1-direct,znver1-load,znver1-ieu,znver1-store")
+(define_insn_reservation "znver2_insn_both" 5
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "alu,icmp,negnot,rotate,rotate1,ishift1,test,setcc,incdec")
+ (eq_attr "memory" "both")))
+ "znver1-direct,znver1-load,znver1-ieu,znver2-store")
+
;; Fix me: Other vector type insns keeping latency 6 as of now.
(define_insn_reservation "znver1_ieu_vector" 6
(and (eq_attr "cpu" "znver1")
(eq_attr "type" "other,str,multi"))
"znver1-vector,znver1-ivector")
+(define_insn_reservation "znver2_ieu_vector" 5
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "type" "other,str,multi"))
+ "znver1-vector,znver2-ivector")
+
;; ALU1 register operands.
(define_insn_reservation "znver1_alu1_vector" 3
(and (eq_attr "cpu" "znver1")
@@ -281,15 +369,22 @@
(eq_attr "memory" "none,unknown"))))
"znver1-vector,znver1-ivector")
+(define_insn_reservation "znver2_alu1_vector" 3
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "znver1_decode" "vector")
+ (and (eq_attr "type" "alu1")
+ (eq_attr "memory" "none,unknown"))))
+ "znver1-vector,znver2-ivector")
+
(define_insn_reservation "znver1_alu1_double" 2
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "znver1_decode" "double")
(and (eq_attr "type" "alu1")
(eq_attr "memory" "none,unknown"))))
"znver1-double,znver1-ieu")
(define_insn_reservation "znver1_alu1_direct" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "znver1_decode" "direct")
(and (eq_attr "type" "alu1")
(eq_attr "memory" "none,unknown"))))
@@ -297,7 +392,7 @@
;; Branches : Fix me need to model conditional branches.
(define_insn_reservation "znver1_branch" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "ibr")
(eq_attr "memory" "none")))
"znver1-direct")
@@ -309,27 +404,33 @@
(eq_attr "memory" "load")))
"znver1-vector,znver1-ivector")
+(define_insn_reservation "znver2_indirect_branch_mem" 6
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "ibr")
+ (eq_attr "memory" "load")))
+ "znver1-vector,znver2-ivector")
+
;; LEA executes in ALU units with 1 cycle latency.
(define_insn_reservation "znver1_lea" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(eq_attr "type" "lea"))
"znver1-direct,znver1-ieu")
;; Other integer instrucions
(define_insn_reservation "znver1_idirect" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "unit" "integer,unknown")
(eq_attr "memory" "none,unknown")))
"znver1-direct,znver1-ieu")
;; Floating point
(define_insn_reservation "znver1_fp_cmov" 6
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(eq_attr "type" "fcmov"))
"znver1-vector,znver1-fvector")
(define_insn_reservation "znver1_fp_mov_direct_load" 8
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "znver1_decode" "direct")
(and (eq_attr "type" "fmov")
(eq_attr "memory" "load"))))
@@ -341,9 +442,15 @@
(and (eq_attr "type" "fmov")
(eq_attr "memory" "store"))))
"znver1-direct,znver1-fp2|znver1-fp3,znver1-store")
+(define_insn_reservation "znver2_fp_mov_direct_store" 5
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "znver1_decode" "direct")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "store"))))
+ "znver1-direct,znver1-fp2|znver1-fp3,znver2-store")
(define_insn_reservation "znver1_fp_mov_double" 4
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "znver1_decode" "double")
(and (eq_attr "type" "fmov")
(eq_attr "memory" "none"))))
@@ -356,13 +463,21 @@
(eq_attr "memory" "load"))))
"znver1-double,znver1-load,znver1-fp3")
+(define_insn_reservation "znver2_fp_mov_double_load" 12
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "znver1_decode" "double")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "load"))))
+ "znver1-double,znver1-load,znver1-fp3")
+
(define_insn_reservation "znver1_fp_mov_direct" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(eq_attr "type" "fmov"))
"znver1-direct,znver1-fp3")
+;; TODO: AGU?
(define_insn_reservation "znver1_fp_spc_direct" 5
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "fpspc")
(eq_attr "memory" "store")))
"znver1-direct,znver1-fp3,znver1-fp2")
@@ -372,22 +487,27 @@
(and (eq_attr "znver1_decode" "vector")
(eq_attr "type" "fpspc,mmxcvt,sselog1,ssemul,ssemov")))
"znver1-vector,znver1-fvector")
+(define_insn_reservation "znver2_fp_insn_vector" 6
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "znver1_decode" "vector")
+ (eq_attr "type" "fpspc,mmxcvt,sselog1,ssemul,ssemov")))
+ "znver1-vector,znver2-fvector")
;; FABS
(define_insn_reservation "znver1_fp_fsgn" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(eq_attr "type" "fsgn"))
"znver1-direct,znver1-fp3")
(define_insn_reservation "znver1_fp_fcmp" 2
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "memory" "none")
(and (eq_attr "znver1_decode" "double")
(eq_attr "type" "fcmp"))))
"znver1-double,znver1-fp0,znver1-fp2")
(define_insn_reservation "znver1_fp_fcmp_load" 9
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "memory" "none")
(and (eq_attr "znver1_decode" "double")
(eq_attr "type" "fcmp"))))
@@ -395,32 +515,32 @@
;;FADD FSUB FMUL
(define_insn_reservation "znver1_fp_op_mul" 5
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "fop,fmul")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp0*5")
(define_insn_reservation "znver1_fp_op_mul_load" 12
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "fop,fmul")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0*5")
(define_insn_reservation "znver1_fp_op_imul_load" 16
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "fop,fmul")
(and (eq_attr "fp_int_src" "true")
(eq_attr "memory" "load"))))
"znver1-double,znver1-load,znver1-fp3,znver1-fp0")
(define_insn_reservation "znver1_fp_op_div" 15
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "fdiv")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp3*15")
(define_insn_reservation "znver1_fp_op_div_load" 22
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "fdiv")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp3*15")
@@ -432,56 +552,63 @@
(eq_attr "memory" "load"))))
"znver1-double,znver1-load,znver1-fp3*19")
+(define_insn_reservation "znver2_fp_op_idiv_load" 26
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "fdiv")
+ (and (eq_attr "fp_int_src" "true")
+ (eq_attr "memory" "load"))))
+ "znver1-double,znver1-load,znver1-fp3*19")
+
;; MMX, SSE, SSEn.n, AVX, AVX2 instructions
(define_insn_reservation "znver1_fp_insn" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(eq_attr "type" "mmx"))
"znver1-direct,znver1-fpu")
(define_insn_reservation "znver1_mmx_add" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxadd")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp0|znver1-fp1|znver1-fp3")
(define_insn_reservation "znver1_mmx_add_load" 8
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxadd")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0|znver1-fp1|znver1-fp3")
(define_insn_reservation "znver1_mmx_cmp" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxcmp")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp0|znver1-fp3")
(define_insn_reservation "znver1_mmx_cmp_load" 8
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxcmp")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0|znver1-fp3")
(define_insn_reservation "znver1_mmx_cvt_pck_shuf" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxcvt,sseshuf,sseshuf1")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp1|znver1-fp2")
(define_insn_reservation "znver1_mmx_cvt_pck_shuf_load" 8
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxcvt,sseshuf,sseshuf1")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp1|znver1-fp2")
(define_insn_reservation "znver1_mmx_shift_move" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxshft,mmxmov")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp2")
(define_insn_reservation "znver1_mmx_shift_move_load" 8
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxshft,mmxmov")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp2")
@@ -491,19 +618,25 @@
(and (eq_attr "type" "mmxshft,mmxmov")
(eq_attr "memory" "store,both")))
"znver1-direct,znver1-fp2,znver1-store")
+(define_insn_reservation "znver2_mmx_move_store" 1
+ (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "type" "mmxshft,mmxmov")
+ (eq_attr "memory" "store,both")))
+ "znver1-direct,znver1-fp2,znver2-store")
(define_insn_reservation "znver1_mmx_mul" 3
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxmul")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp0*3")
(define_insn_reservation "znver1_mmx_load" 10
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "mmxmul")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0*3")
+;; TODO
(define_insn_reservation "znver1_avx256_log" 1
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V8SF,V4DF,OI")
@@ -519,13 +652,13 @@
"znver1-double,znver1-load,znver1-fpu")
(define_insn_reservation "znver1_sse_log" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "sselog")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fpu")
(define_insn_reservation "znver1_sse_log_load" 8
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "sselog")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fpu")
@@ -545,13 +678,13 @@
"znver1-double,znver1-load,znver1-fp1|znver1-fp2")
(define_insn_reservation "znver1_sse_log1" 1
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "sselog1")
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp1|znver1-fp2")
(define_insn_reservation "znver1_sse_log1_load" 8
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "type" "sselog1")
(eq_attr "memory" "!none")))
"znver1-direct,znver1-load,znver1-fp1|znver1-fp2")
@@ -566,46 +699,50 @@
"znver1-direct,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sse_comi_load" 8
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF")
- (and (eq_attr "prefix" "!vex")
- (and (eq_attr "prefix_extra" "0")
- (and (eq_attr "type" "ssecomi")
- (eq_attr "memory" "load"))))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "prefix_extra" "0")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "load"))))
"znver1-direct,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sse_comi_double" 2
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V4SF,V2DF,TI")
- (and (eq_attr "prefix" "vex")
- (and (eq_attr "prefix_extra" "0")
- (and (eq_attr "type" "ssecomi")
- (eq_attr "memory" "none"))))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "prefix" "vex")
+ (and (eq_attr "prefix_extra" "0")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "none")))))
"znver1-double,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sse_comi_double_load" 10
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V4SF,V2DF,TI")
- (and (eq_attr "prefix" "vex")
- (and (eq_attr "prefix_extra" "0")
- (and (eq_attr "type" "ssecomi")
- (eq_attr "memory" "load"))))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "prefix" "vex")
+ (and (eq_attr "prefix_extra" "0")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "load")))))
"znver1-double,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sse_test" 1
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
- (and (eq_attr "prefix_extra" "1")
- (and (eq_attr "type" "ssecomi")
- (eq_attr "memory" "none")))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "prefix_extra" "1")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "none"))))
"znver1-direct,znver1-fp1|znver1-fp2")
(define_insn_reservation "znver1_sse_test_load" 8
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
- (and (eq_attr "prefix_extra" "1")
- (and (eq_attr "type" "ssecomi")
- (eq_attr "memory" "load")))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "prefix_extra" "1")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "load"))))
"znver1-direct,znver1-load,znver1-fp1|znver1-fp2")
;; SSE moves
@@ -619,6 +756,14 @@
(eq_attr "memory" "none")))))
"znver1-direct,znver1-ieu0")
+(define_insn_reservation "znver2_sse_mov" 1
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "mode" "SI")
+ (and (eq_attr "isa" "avx")
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "memory" "none")))))
+ "znver1-direct,znver1-ieu0")
+
(define_insn_reservation "znver1_avx_mov" 2
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "TI")
@@ -628,11 +773,21 @@
(eq_attr "memory" "none"))))))
"znver1-direct,znver1-ieu2")
+(define_insn_reservation "znver2_avx_mov" 1
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "mode" "TI")
+ (and (eq_attr "isa" "avx")
+ (and (eq_attr "type" "ssemov")
+ (and (match_operand:SI 1 "register_operand")
+ (eq_attr "memory" "none"))))))
+ "znver1-direct,znver1-ieu2")
+
(define_insn_reservation "znver1_sseavx_mov" 1
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
- (and (eq_attr "type" "ssemov")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fpu")
(define_insn_reservation "znver1_sseavx_mov_store" 1
@@ -641,12 +796,18 @@
(and (eq_attr "type" "ssemov")
(eq_attr "memory" "store"))))
"znver1-direct,znver1-fpu,znver1-store")
+(define_insn_reservation "znver2_sseavx_mov_store" 1
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "memory" "store")))
+ "znver1-direct,znver1-fpu,znver2-store")
(define_insn_reservation "znver1_sseavx_mov_load" 8
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
- (and (eq_attr "type" "ssemov")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fpu")
(define_insn_reservation "znver1_avx256_mov" 1
@@ -672,17 +833,19 @@
;; SSE add
(define_insn_reservation "znver1_sseavx_add" 3
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
- (and (eq_attr "type" "sseadd")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp2|znver1-fp3")
(define_insn_reservation "znver1_sseavx_add_load" 10
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF,TI")
- (and (eq_attr "type" "sseadd")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp2|znver1-fp3")
(define_insn_reservation "znver1_avx256_add" 3
@@ -700,17 +863,19 @@
"znver1-double,znver1-load,znver1-fp2|znver1-fp3")
(define_insn_reservation "znver1_sseavx_fma" 5
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF")
- (and (eq_attr "type" "ssemuladd")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "ssemuladd")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sseavx_fma_load" 12
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF")
- (and (eq_attr "type" "ssemuladd")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "ssemuladd")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_avx256_fma" 5
@@ -728,17 +893,19 @@
"znver1-double,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sseavx_iadd" 1
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "DI,TI")
- (and (eq_attr "type" "sseiadd")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "DI,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "sseiadd")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp0|znver1-fp1|znver1-fp3")
(define_insn_reservation "znver1_sseavx_iadd_load" 8
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "DI,TI")
- (and (eq_attr "type" "sseiadd")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "DI,TI"))
+ (eq_attr "cpu" "znver2"))
+ (and (eq_attr "type" "sseiadd")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0|znver1-fp1|znver1-fp3")
(define_insn_reservation "znver1_avx256_iadd" 1
@@ -757,7 +924,7 @@
;; SSE conversions.
(define_insn_reservation "znver1_ssecvtsf_si_load" 12
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "mode" "SI")
(and (eq_attr "type" "sseicvt")
(and (match_operand:SF 1 "memory_operand")
@@ -771,6 +938,13 @@
(and (eq_attr "type" "sseicvt")
(eq_attr "memory" "none")))))
"znver1-double,znver1-fp3,znver1-ieu0")
+(define_insn_reservation "znver2_ssecvtdf_si" 4
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "mode" "SI")
+ (and (match_operand:DF 1 "register_operand")
+ (and (eq_attr "type" "sseicvt")
+ (eq_attr "memory" "none")))))
+ "znver1-double,znver1-fp3,znver1-ieu0")
(define_insn_reservation "znver1_ssecvtdf_si_load" 12
(and (eq_attr "cpu" "znver1")
@@ -780,6 +954,14 @@
(eq_attr "memory" "load")))))
"znver1-double,znver1-load,znver1-fp3,znver1-ieu0")
+(define_insn_reservation "znver2_ssecvtdf_si_load" 11
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "mode" "SI")
+ (and (eq_attr "type" "sseicvt")
+ (and (match_operand:DF 1 "memory_operand")
+ (eq_attr "memory" "load")))))
+ "znver1-double,znver1-load,znver1-fp3,znver1-ieu0")
+
;; All other used ssecvt fp3 pipes
;; Check: Need to revisit this again.
;; Some SSE converts may use different pipe combinations.
@@ -789,39 +971,59 @@
(eq_attr "memory" "none")))
"znver1-direct,znver1-fp3")
+(define_insn_reservation "znver2_ssecvt" 3
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "ssecvt")
+ (eq_attr "memory" "none")))
+ "znver1-direct,znver1-fp3")
+
(define_insn_reservation "znver1_ssecvt_load" 11
(and (eq_attr "cpu" "znver1")
(and (eq_attr "type" "ssecvt")
(eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp3")
+(define_insn_reservation "znver2_ssecvt_load" 11
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "ssecvt")
+ (eq_attr "memory" "load")))
+ "znver1-direct,znver1-load,znver1-fp3")
+
;; SSE div
(define_insn_reservation "znver1_ssediv_ss_ps" 10
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V4SF,SF")
- (and (eq_attr "type" "ssediv")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V4SF,SF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "V8SF,V4SF,SF")))
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp3*10")
(define_insn_reservation "znver1_ssediv_ss_ps_load" 17
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V4SF,SF")
- (and (eq_attr "type" "ssediv")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V4SF,SF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "V8SF,V4SF,SF")))
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp3*10")
(define_insn_reservation "znver1_ssediv_sd_pd" 13
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V2DF,DF")
- (and (eq_attr "type" "ssediv")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V2DF,DF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "V4DF,V2DF,DF")))
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp3*13")
(define_insn_reservation "znver1_ssediv_sd_pd_load" 20
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V2DF,DF")
- (and (eq_attr "type" "ssediv")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V2DF,DF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "V4DF,V2DF,DF")))
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp3*13")
(define_insn_reservation "znver1_ssediv_avx256_ps" 12
@@ -853,17 +1055,21 @@
"znver1-double,znver1-load,znver1-fp3*15")
;; SSE MUL
(define_insn_reservation "znver1_ssemul_ss_ps" 3
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V4SF,SF")
- (and (eq_attr "type" "ssemul")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V4SF,SF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "V8SF,V4SF,SF,V4DF,V2DF,DF")))
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "none")))
"znver1-direct,(znver1-fp0|znver1-fp1)*3")
(define_insn_reservation "znver1_ssemul_ss_ps_load" 10
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "V4SF,SF")
- (and (eq_attr "type" "ssemul")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "V4SF,SF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "V8SF,V4SF,SF")))
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*3")
(define_insn_reservation "znver1_ssemul_avx256_ps" 3
@@ -894,12 +1100,23 @@
(eq_attr "memory" "load"))))
"znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*4")
+(define_insn_reservation "znver2_ssemul_sd_pd" 3
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "none")))
+ "znver1-direct,(znver1-fp0|znver1-fp1)*3")
+
+(define_insn_reservation "znver2_ssemul_sd_pd_load" 10
+ (and (eq_attr "cpu" "znver2")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "load")))
+ "znver1-direct,znver1-load,(znver1-fp0|znver1-fp1)*3")
+
(define_insn_reservation "znver1_ssemul_avx256_pd" 5
(and (eq_attr "cpu" "znver1")
(and (eq_attr "mode" "V4DF")
- (and (eq_attr "mode" "V4DF")
- (and (eq_attr "type" "ssemul")
- (eq_attr "memory" "none")))))
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "none"))))
"znver1-double,(znver1-fp0|znver1-fp1)*4")
(define_insn_reservation "znver1_ssemul_avx256_pd_load" 12
@@ -911,42 +1128,46 @@
;;SSE imul
(define_insn_reservation "znver1_sseimul" 3
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "TI")
- (and (eq_attr "type" "sseimul")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "TI"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "TI,OI")))
+ (and (eq_attr "type" "sseimul")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp0*3")
(define_insn_reservation "znver1_sseimul_avx256" 4
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "mode" "OI")
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "none"))))
"znver1-double,znver1-fp0*4")
(define_insn_reservation "znver1_sseimul_load" 10
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "TI")
- (and (eq_attr "type" "sseimul")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "TI"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "TI,OI")))
+ (and (eq_attr "type" "sseimul")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0*3")
(define_insn_reservation "znver1_sseimul_avx256_load" 11
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "mode" "OI")
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "load"))))
"znver1-double,znver1-load,znver1-fp0*4")
(define_insn_reservation "znver1_sseimul_di" 3
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "mode" "DI")
(and (eq_attr "memory" "none")
(eq_attr "type" "sseimul"))))
"znver1-direct,znver1-fp0*3")
(define_insn_reservation "znver1_sseimul_load_di" 10
- (and (eq_attr "cpu" "znver1")
+ (and (eq_attr "cpu" "znver1,znver2")
(and (eq_attr "mode" "DI")
(and (eq_attr "type" "sseimul")
(eq_attr "memory" "load"))))
@@ -954,17 +1175,21 @@
;; SSE compares
(define_insn_reservation "znver1_sse_cmp" 1
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF")
- (and (eq_attr "type" "ssecmp")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF")))
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sse_cmp_load" 8
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "SF,DF,V4SF,V2DF")
- (and (eq_attr "type" "ssecmp")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "SF,DF,V4SF,V2DF,V8SF,V4DF")))
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sse_cmp_avx256" 1
@@ -982,17 +1207,21 @@
"znver1-double,znver1-load,znver1-fp0|znver1-fp1")
(define_insn_reservation "znver1_sse_icmp" 1
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "QI,HI,SI,DI,TI")
- (and (eq_attr "type" "ssecmp")
- (eq_attr "memory" "none"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "QI,HI,SI,DI,TI"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "QI,HI,SI,DI,TI,OI")))
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "none")))
"znver1-direct,znver1-fp0|znver1-fp3")
(define_insn_reservation "znver1_sse_icmp_load" 8
- (and (eq_attr "cpu" "znver1")
- (and (eq_attr "mode" "QI,HI,SI,DI,TI")
- (and (eq_attr "type" "ssecmp")
- (eq_attr "memory" "load"))))
+ (and (ior (and (eq_attr "cpu" "znver1")
+ (eq_attr "mode" "QI,HI,SI,DI,TI"))
+ (and (eq_attr "cpu" "znver2")
+ (eq_attr "mode" "QI,HI,SI,DI,TI,OI")))
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "load")))
"znver1-direct,znver1-load,znver1-fp0|znver1-fp3")
(define_insn_reservation "znver1_sse_icmp_avx256" 1
diff --git a/gcc/config/mips/micromips.md b/gcc/config/mips/micromips.md
index 9f8158e..782d9d1 100644
--- a/gcc/config/mips/micromips.md
+++ b/gcc/config/mips/micromips.md
@@ -133,5 +133,5 @@
return "movep\t%2,%0,%z3,%z1";
}
[(set_attr "type" "move")
- (set_attr "mode" "<MODE>")
+ (set_attr "mode" "<MOVEP1:MODE>")
(set_attr "can_delay" "no")])
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index cbebb45..e0535b1 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -4849,7 +4849,7 @@ mips_split_move (rtx dest, rtx src, enum mips_split_type split_type, rtx insn_)
can forward SRC for DEST. This is most useful if the next insn is a
simple store. */
rtx_insn *insn = (rtx_insn *)insn_;
- struct mips_address_info addr;
+ struct mips_address_info addr = {};
if (insn)
{
rtx_insn *next = next_nonnote_nondebug_insn_bb (insn);
@@ -4862,7 +4862,7 @@ mips_split_move (rtx dest, rtx src, enum mips_split_type split_type, rtx insn_)
{
rtx tmp = XEXP (src, 0);
mips_classify_address (&addr, tmp, GET_MODE (tmp), true);
- if (REGNO (addr.reg) != REGNO (dest))
+ if (addr.reg && REGNO (addr.reg) != REGNO (dest))
validate_change (next, &SET_SRC (set), src, false);
}
else
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index d260cf9..e17b1d5 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -1749,7 +1749,7 @@
[(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d")
(match_operand:SI 2 "register_operand" "d,d,d"))
- (match_operand:SI 3 "register_operand" "0,0,d")))
+ (match_operand:SI 3 "register_operand" "l,l,d")))
(clobber (match_scratch:SI 4 "=X,X,l"))
(clobber (match_scratch:SI 5 "=X,X,&d"))]
"GENERATE_MADD_MSUB && !TARGET_MIPS16"
@@ -1778,7 +1778,7 @@
[(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d*?,d?")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d")
(match_operand:SI 2 "register_operand" "d,d,d,d"))
- (match_operand:SI 3 "register_operand" "0,0,l,d")))
+ (match_operand:SI 3 "register_operand" "l,l,l,d")))
(clobber (match_scratch:SI 4 "=X,X,3,l"))
(clobber (match_scratch:SI 5 "=X,X,X,&d"))]
"TARGET_MIPS3900 && !TARGET_MIPS16"
@@ -1822,7 +1822,7 @@
[(set (match_operand:SI 0 "register_operand" "=l,d")
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d")
(match_operand:SI 2 "register_operand" "d,d"))
- (match_operand:SI 3 "register_operand" "0,l")))
+ (match_operand:SI 3 "register_operand" "l,l")))
(clobber (match_scratch:SI 4 "=X,3"))]
"ISA_HAS_MACC"
{
@@ -1842,7 +1842,7 @@
(define_insn "*msac"
[(set (match_operand:SI 0 "register_operand" "=l,d")
- (minus:SI (match_operand:SI 1 "register_operand" "0,l")
+ (minus:SI (match_operand:SI 1 "register_operand" "l,l")
(mult:SI (match_operand:SI 2 "register_operand" "d,d")
(match_operand:SI 3 "register_operand" "d,d"))))
(clobber (match_scratch:SI 4 "=X,1"))]
@@ -1862,7 +1862,7 @@
;; An msac-like instruction implemented using negation and a macc.
(define_insn_and_split "*msac_using_macc"
[(set (match_operand:SI 0 "register_operand" "=l,d")
- (minus:SI (match_operand:SI 1 "register_operand" "0,l")
+ (minus:SI (match_operand:SI 1 "register_operand" "l,l")
(mult:SI (match_operand:SI 2 "register_operand" "d,d")
(match_operand:SI 3 "register_operand" "d,d"))))
(clobber (match_scratch:SI 4 "=X,1"))
@@ -2005,7 +2005,7 @@
;; See the comment above *mul_add_si for details.
(define_insn "*mul_sub_si"
[(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?")
- (minus:SI (match_operand:SI 1 "register_operand" "0,0,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "l,l,d")
(mult:SI (match_operand:SI 2 "register_operand" "d,d,d")
(match_operand:SI 3 "register_operand" "d,d,d"))))
(clobber (match_scratch:SI 4 "=X,X,l"))
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 365e9eb..265c2f6 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -1755,11 +1755,19 @@ msp430_preserve_reg_p (int regno)
if (fixed_regs [regno])
return false;
- /* Interrupt handlers save all registers they use, even
- ones which are call saved. If they call other functions
- then *every* register is saved. */
- if (msp430_is_interrupt_func ())
- return ! crtl->is_leaf || df_regs_ever_live_p (regno);
+ /* For interrupt functions we must save and restore the used regs that
+ would normally be caller-saved (R11->R15). */
+ if (msp430_is_interrupt_func () && regno >= 11 && regno <= 15)
+ {
+ if (crtl->is_leaf && df_regs_ever_live_p (regno))
+ /* If the interrupt func is a leaf then we only need to restore the
+ caller-saved regs that are used. */
+ return true;
+ else if (!crtl->is_leaf)
+ /* If the interrupt function is not a leaf we must save all
+ caller-saved regs in case the callee modifies them. */
+ return true;
+ }
if (!call_used_regs [regno]
&& df_regs_ever_live_p (regno))
diff --git a/gcc/config/or1k/constraints.md b/gcc/config/or1k/constraints.md
index 93da8c0..8cac7eb 100644
--- a/gcc/config/or1k/constraints.md
+++ b/gcc/config/or1k/constraints.md
@@ -24,6 +24,7 @@
; We use:
; c - sibcall registers
+; d - double pair base registers (excludes r0, r30 and r31 which overflow)
; I - constant signed 16-bit
; K - constant unsigned 16-bit
; M - constant signed 16-bit shifted left 16-bits (l.movhi)
@@ -32,6 +33,9 @@
(define_register_constraint "c" "SIBCALL_REGS"
"Registers which can hold a sibling call address")
+(define_register_constraint "d" "DOUBLE_REGS"
+ "Registers which can be used for double reg pairs.")
+
;; Immediates
(define_constraint "I"
"A signed 16-bit immediate in the range -32768 to 32767."
diff --git a/gcc/config/or1k/elf.opt b/gcc/config/or1k/elf.opt
index 641b6dd..2d4d187 100644
--- a/gcc/config/or1k/elf.opt
+++ b/gcc/config/or1k/elf.opt
@@ -25,9 +25,9 @@
mboard=
Target RejectNegative Joined
-Configure board specific runtime.
+Configure the newlib board specific runtime. The default is or1ksim.
mnewlib
Target RejectNegative
-For compatibility, it's always newlib for elf now.
-
+This option is ignored; it is provided for compatibility purposes only. This
+used to select linker and preprocessor options for use with newlib.
diff --git a/gcc/config/or1k/or1k.c b/gcc/config/or1k/or1k.c
index 54c9e80..f8eed4a 100644
--- a/gcc/config/or1k/or1k.c
+++ b/gcc/config/or1k/or1k.c
@@ -1226,6 +1226,19 @@ or1k_print_operand (FILE *file, rtx x, int code)
output_operand_lossage ("invalid %%H value");
break;
+ case 'd':
+ if (REG_P (x))
+ {
+ if (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
+ fprintf (file, "%s,%s", reg_names[REGNO (operand)],
+ reg_names[REGNO (operand) + 1]);
+ else
+ fprintf (file, "%s", reg_names[REGNO (operand)]);
+ }
+ else
+ output_operand_lossage ("invalid %%d value");
+ break;
+
case 'h':
print_reloc (file, x, 0, RKIND_HI);
break;
@@ -1435,21 +1448,44 @@ void
or1k_expand_compare (rtx *operands)
{
rtx sr_f = gen_rtx_REG (BImode, SR_F_REGNUM);
-
- /* The RTL may receive an immediate in argument 1 of the compare, this is not
- supported unless we have l.sf*i instructions, force them into registers. */
- if (!TARGET_SFIMM)
- XEXP (operands[0], 1) = force_reg (SImode, XEXP (operands[0], 1));
+ rtx righthand_op = XEXP (operands[0], 1);
+ rtx_code cmp_code = GET_CODE (operands[0]);
+ bool flag_check_ne = true;
+
+ /* Integer RTL may receive an immediate in argument 1 of the compare, this is
+ not supported unless we have l.sf*i instructions, force them into
+ registers. */
+ if (!TARGET_SFIMM && CONST_INT_P (righthand_op))
+ XEXP (operands[0], 1) = force_reg (SImode, righthand_op);
+
+ /* Normalize comparison operators to ones OpenRISC support. */
+ switch (cmp_code)
+ {
+ case LTGT:
+ cmp_code = UNEQ;
+ flag_check_ne = false;
+ break;
+
+ case ORDERED:
+ cmp_code = UNORDERED;
+ flag_check_ne = false;
+ break;
+
+ default:
+ break;
+ }
/* Emit the given comparison into the Flag bit. */
PUT_MODE (operands[0], BImode);
+ PUT_CODE (operands[0], cmp_code);
emit_insn (gen_rtx_SET (sr_f, operands[0]));
/* Adjust the operands for use in the caller. */
- operands[0] = gen_rtx_NE (VOIDmode, sr_f, const0_rtx);
+ operands[0] = flag_check_ne ? gen_rtx_NE (VOIDmode, sr_f, const0_rtx)
+ : gen_rtx_EQ (VOIDmode, sr_f, const0_rtx);
operands[1] = sr_f;
operands[2] = const0_rtx;
-}
+ }
/* Expand the patterns "call", "sibcall", "call_value" and "sibcall_value".
Expands a function call where argument RETVAL is an optional RTX providing
diff --git a/gcc/config/or1k/or1k.h b/gcc/config/or1k/or1k.h
index 6dda230..2b29e62 100644
--- a/gcc/config/or1k/or1k.h
+++ b/gcc/config/or1k/or1k.h
@@ -189,6 +189,7 @@ enum reg_class
{
NO_REGS,
SIBCALL_REGS,
+ DOUBLE_REGS,
GENERAL_REGS,
FLAG_REGS,
ALL_REGS,
@@ -200,6 +201,7 @@ enum reg_class
#define REG_CLASS_NAMES { \
"NO_REGS", \
"SIBCALL_REGS", \
+ "DOUBLE_REGS", \
"GENERAL_REGS", \
"FLAG_REGS", \
"ALL_REGS" }
@@ -212,6 +214,7 @@ enum reg_class
#define REG_CLASS_CONTENTS \
{ { 0x00000000, 0x00000000 }, \
{ SIBCALL_REGS_MASK, 0 }, \
+ { 0x7f7ffffe, 0x00000000 }, \
{ 0xffffffff, 0x00000003 }, \
{ 0x00000000, 0x00000004 }, \
{ 0xffffffff, 0x00000007 } \
diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md
index 2dad51c..cee11d0 100644
--- a/gcc/config/or1k/or1k.md
+++ b/gcc/config/or1k/or1k.md
@@ -60,10 +60,10 @@
(define_attr "length" "" (const_int 4))
(define_attr "type"
- "alu,st,ld,control,multi"
+ "alu,st,ld,control,multi,fpu"
(const_string "alu"))
-(define_attr "insn_support" "class1,sext,sfimm,shftimm" (const_string "class1"))
+(define_attr "insn_support" "class1,sext,sfimm,shftimm,ror,rori" (const_string "class1"))
(define_attr "enabled" ""
(cond [(eq_attr "insn_support" "class1") (const_int 1)
@@ -72,7 +72,11 @@
(and (eq_attr "insn_support" "sfimm")
(ne (symbol_ref "TARGET_SFIMM") (const_int 0))) (const_int 1)
(and (eq_attr "insn_support" "shftimm")
- (ne (symbol_ref "TARGET_SHFTIMM") (const_int 0))) (const_int 1)]
+ (ne (symbol_ref "TARGET_SHFTIMM") (const_int 0))) (const_int 1)
+ (and (eq_attr "insn_support" "ror")
+ (ne (symbol_ref "TARGET_ROR") (const_int 0))) (const_int 1)
+ (and (eq_attr "insn_support" "rori")
+ (ne (symbol_ref "TARGET_RORI") (const_int 0))) (const_int 1)]
(const_int 0)))
;; Describe a user's asm statement.
@@ -93,6 +97,10 @@
(define_insn_reservation "control" 1
(eq_attr "type" "control")
"cpu")
+(define_insn_reservation "fpu" 2
+ (eq_attr "type" "fpu")
+ "cpu")
+
; Define delay slots for any branch
(define_delay (eq_attr "type" "control")
@@ -156,6 +164,47 @@
"l.sub\t%0, %r1, %2")
;; -------------------------------------------------------------------------
+;; Floating Point Arithmetic instructions
+;; -------------------------------------------------------------------------
+
+;; Mode iterator for single/double float
+(define_mode_iterator F [(SF "TARGET_HARD_FLOAT")
+ (DF "TARGET_DOUBLE_FLOAT")])
+(define_mode_attr f [(SF "s") (DF "d")])
+(define_mode_attr fr [(SF "r") (DF "d")])
+(define_mode_attr fi [(SF "si") (DF "di")])
+(define_mode_attr FI [(SF "SI") (DF "DI")])
+
+;; Basic arithmetic instructions
+(define_code_iterator FOP [plus minus mult div])
+(define_code_attr fop [(plus "add") (minus "sub") (mult "mul") (div "div")])
+
+(define_insn "<fop><F:mode>3"
+ [(set (match_operand:F 0 "register_operand" "=<fr>")
+ (FOP:F (match_operand:F 1 "register_operand" "<fr>")
+ (match_operand:F 2 "register_operand" "<fr>")))]
+ "TARGET_HARD_FLOAT"
+ "lf.<fop>.<f>\t%d0, %d1, %d2"
+ [(set_attr "type" "fpu")])
+
+;; Basic float<->int conversion
+(define_insn "float<fi><F:mode>2"
+ [(set (match_operand:F 0 "register_operand" "=<fr>")
+ (float:F
+ (match_operand:<FI> 1 "register_operand" "<fr>")))]
+ "TARGET_HARD_FLOAT"
+ "lf.itof.<f>\t%d0, %d1"
+ [(set_attr "type" "fpu")])
+
+(define_insn "fix_trunc<F:mode><fi>2"
+ [(set (match_operand:<FI> 0 "register_operand" "=<fr>")
+ (fix:<FI>
+ (match_operand:F 1 "register_operand" "<fr>")))]
+ "TARGET_HARD_FLOAT"
+ "lf.ftoi.<f>\t%d0, %d1"
+ [(set_attr "type" "fpu")])
+
+;; -------------------------------------------------------------------------
;; Logical operators
;; -------------------------------------------------------------------------
@@ -178,12 +227,12 @@
(define_insn "rotrsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
- (match_operand:SI 2 "reg_or_u6_operand" "r,n")))]
- "TARGET_ROR"
+ (match_operand:SI 2 "ror_reg_or_u6_operand" "r,n")))]
+ "TARGET_ROR || TARGET_RORI"
"@
l.ror\t%0, %1, %2
l.rori\t%0, %1, %2"
- [(set_attr "insn_support" "*,shftimm")])
+ [(set_attr "insn_support" "ror,rori")])
(define_insn "andsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -328,11 +377,11 @@
;; Sign Extending
;; -------------------------------------------------------------------------
-;; Zero extension can always be done with AND and an extending load.
+;; Zero extension can always be done with AND or an extending load.
(define_insn "zero_extend<mode>si2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:I12 1 "nonimmediate_operand" "r,m")))]
+ (zero_extend:SI (match_operand:I12 1 "reg_or_mem_operand" "r,m")))]
""
"@
l.andi\t%0, %1, <zext_andi>
@@ -344,7 +393,7 @@
(define_insn "extend<mode>si2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (sign_extend:SI (match_operand:I12 1 "nonimmediate_operand" "r,m")))]
+ (sign_extend:SI (match_operand:I12 1 "reg_or_mem_operand" "r,m")))]
"TARGET_SEXT"
"@
l.ext<ldst>s\t%0, %1
@@ -376,7 +425,7 @@
(define_code_iterator intcmpcc [ne eq lt ltu gt gtu ge le geu leu])
(define_code_attr insn [(ne "ne") (eq "eq") (lt "lts") (ltu "ltu")
(gt "gts") (gtu "gtu") (ge "ges") (le "les")
- (geu "geu") (leu "leu") ])
+ (geu "geu") (leu "leu")])
(define_insn "*sf_insn"
[(set (reg:BI SR_F_REGNUM)
@@ -388,6 +437,36 @@
l.sf<insn>i\t%r0, %1"
[(set_attr "insn_support" "*,sfimm")])
+;; Support FP comparisons too
+
+;; The OpenRISC FPU supports these comparisons:
+;;
+;; lf.sfeq.{d,s} - equality, r r, double or single precision
+;; lf.sfge.{d,s} - greater than or equal, r r, double or single precision
+;; lf.sfgt.{d,s} - greater than, r r, double or single precision
+;; lf.sfle.{d,s} - less than or equal, r r, double or single precision
+;; lf.sflt.{d,s} - less than, r r, double or single precision
+;; lf.sfne.{d,s} - not equal, r r, double or single precision
+;;
+;; Double precision is only supported on some hardware. Only register/register
+;; comparisons are supported. All comparisons are signed.
+
+(define_code_iterator fpcmpcc [ne eq lt gt ge le uneq unle unlt ungt unge
+ unordered])
+(define_code_attr fpcmpinsn [(ne "ne") (eq "eq") (lt "lt") (gt "gt") (ge "ge")
+ (le "le") (uneq "ueq") (unle "ule") (unlt "ult")
+ (ungt "ugt") (unge "uge") (unordered "un")])
+
+
+(define_insn "*sf_fp_insn"
+ [(set (reg:BI SR_F_REGNUM)
+ (fpcmpcc:BI (match_operand:F 0 "register_operand" "<fr>")
+ (match_operand:F 1 "register_operand" "<fr>")))]
+ "TARGET_HARD_FLOAT"
+ "lf.sf<fpcmpinsn>.<f>\t%d0, %d1"
+ [(set_attr "type" "fpu")])
+
+
;; -------------------------------------------------------------------------
;; Conditional Store instructions
;; -------------------------------------------------------------------------
@@ -408,6 +487,23 @@
DONE;
})
+;; Support FP cstores too
+(define_expand "cstore<F:mode>4"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (if_then_else:F
+ (match_operator 1 "fp_comparison_operator"
+ [(match_operand:F 2 "register_operand" "")
+ (match_operand:F 3 "register_operand" "")])
+ (match_dup 0)
+ (const_int 0)))]
+ "TARGET_HARD_FLOAT"
+{
+ or1k_expand_compare (operands + 1);
+ PUT_MODE (operands[1], SImode);
+ emit_insn (gen_rtx_SET (operands[0], operands[1]));
+ DONE;
+})
+
;; Being able to "copy" SR_F to a general register is helpful for
;; the atomic insns, wherein the usual usage is to test the success
;; of the compare-and-swap. Representing the operation in this way,
@@ -501,6 +597,21 @@
or1k_expand_compare (operands);
})
+;; Support FP branching
+
+(define_expand "cbranch<F:mode>4"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "fp_comparison_operator"
+ [(match_operand:F 1 "register_operand" "")
+ (match_operand:F 2 "register_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_HARD_FLOAT"
+{
+ or1k_expand_compare (operands);
+})
+
(define_insn "*cbranch"
[(set (pc)
(if_then_else
diff --git a/gcc/config/or1k/or1k.opt b/gcc/config/or1k/or1k.opt
index 7bdbd84..15085fa 100644
--- a/gcc/config/or1k/or1k.opt
+++ b/gcc/config/or1k/or1k.opt
@@ -21,47 +21,77 @@
; See the GCC internals manual (options.texi) for a description of
; this file's format.
-; Please try to keep this file in ASCII collating order.
-
mhard-div
Target RejectNegative InverseMask(SOFT_DIV)
-Use hardware divide instructions, use -msoft-div for emulation.
+Enable generation of hardware divide (l.div, l.divu) instructions. This is the
+default; use -msoft-div to override.
+
+msoft-div
+Target RejectNegative Mask(SOFT_DIV)
+Enable generation of binaries which use functions from libgcc to perform divide
+operations. The default is -mhard-div.
mhard-mul
Target RejectNegative InverseMask(SOFT_MUL).
-Use hardware multiply instructions, use -msoft-mul for emulation.
+Enable generation of hardware multiply instructions (l.mul, l.muli) instructions.
+This is the default; use -msoft-mul to override.
+
+msoft-mul
+Target RejectNegative Mask(SOFT_MUL).
+Enable generation of binaries which use functions from libgcc to perform
+multiply operations. The default is -mhard-mul.
+
+msoft-float
+Target RejectNegative InverseMask(HARD_FLOAT)
+Enable generation of binaries which use functions from libgcc to perform
+floating point operations. This is the default; use -mhard-float to override.
+
+mhard-float
+Target RejectNegative Mask(HARD_FLOAT)
+Enable generation of hardware floating point instructions. The default is
+-msoft-float.
+
+mdouble-float
+Target Mask(DOUBLE_FLOAT)
+When -mhard-float is selected, enables generation of double-precision floating
+point instructions. By default functions from libgcc are used to perform
+double-precision floating point operations.
+
+munordered-float
+Target RejectNegative Mask(FP_UNORDERED)
+When -mhard-float is selected, enables generation of unordered floating point
+compare and set flag (lf.sfun*) instructions. By default functions from libgcc
+are used to perform unordered floating point compare and set flag operations.
mcmov
Target RejectNegative Mask(CMOV)
-Allows generation of binaries which use the l.cmov instruction. If your target
-does not support this the compiler will generate the equivalent using set and
-branch.
+Enable generation of conditional move (l.cmov) instructions. By default the
+equivalent will be generated using using set and branch.
mror
Target RejectNegative Mask(ROR)
-Allows generation of binaries which use the l.rori instructions.
+Enable generation of rotate right (l.ror) instructions. By default functions
+from libgcc are used to perform rotate right operations.
+
+mrori
+Target RejectNegative Mask(RORI)
+Enable generation of rotate right with immediate (l.rori) instructions. By
+default functions from libgcc are used to perform rotate right with immediate
+operations.
msext
Target RejectNegative Mask(SEXT)
-Allows generation of binaries which use sign-extension instructions. If your
-target does not support this the compiler will use memory loads to perform sign
-extension.
+Enable generation of sign extension (l.ext*) instructions. By default memory
+loads are used to perform sign extension.
msfimm
Target RejectNegative Mask(SFIMM)
-Allows generation of binaries which use l.sf*i instructions. If your target
-does not support this the compiler will generate instructions to store the
-immediate to a register first.
+Enable generation of compare and set flag with immediate (l.sf*i) instructions.
+By default extra instructions will be generated to store the immediate to a
+register first.
mshftimm
Target RejectNegative Mask(SHFTIMM)
-Allows generation of binaries which support shifts and rotate instructions
-supporting immediate arguments, for example l.rori.
-
-msoft-div
-Target RejectNegative Mask(SOFT_DIV)
-Use divide emulation.
-
-msoft-mul
-Target RejectNegative Mask(SOFT_MUL).
-Use multiply emulation.
+Enable generation of shift with immediate (l.srai, l.srli, l.slli) instructions.
+By default extra instructions will be generated to store the immediate to a
+register first.
diff --git a/gcc/config/or1k/predicates.md b/gcc/config/or1k/predicates.md
index 879236b..3aa6ca3 100644
--- a/gcc/config/or1k/predicates.md
+++ b/gcc/config/or1k/predicates.md
@@ -53,6 +53,13 @@
(match_test "INTVAL (op) >= -32768 && INTVAL (op) <= 32767")
(match_operand 0 "register_operand")))
+(define_predicate "ror_reg_or_u6_operand"
+ (if_then_else (match_code "const_int")
+ (and (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 0x3f")
+ (match_test "TARGET_RORI"))
+ (and (match_operand 0 "register_operand")
+ (match_test "TARGET_ROR"))))
+
(define_predicate "call_insn_operand"
(ior (match_code "symbol_ref")
(match_operand 0 "register_operand")))
@@ -82,3 +89,26 @@
(define_predicate "equality_comparison_operator"
(match_code "ne,eq"))
+
+(define_predicate "fp_comparison_operator"
+ (if_then_else (match_test "TARGET_FP_UNORDERED")
+ (match_operand 0 "comparison_operator")
+ (match_operand 0 "ordered_comparison_operator")))
+
+;; Borrowed from rs6000
+;; Return true if the operand is in volatile memory. Note that during the
+;; RTL generation phase, memory_operand does not return TRUE for volatile
+;; memory references. So this function allows us to recognize volatile
+;; references where it's safe.
+(define_predicate "volatile_mem_operand"
+ (and (match_code "mem")
+ (match_test "MEM_VOLATILE_P (op)")
+ (if_then_else (match_test "reload_completed")
+ (match_operand 0 "memory_operand")
+ (match_test "memory_address_p (mode, XEXP (op, 0))"))))
+
+;; Return true if the operand is a register or memory; including volatile
+;; memory.
+(define_predicate "reg_or_mem_operand"
+ (ior (match_operand 0 "nonimmediate_operand")
+ (match_operand 0 "volatile_mem_operand")))
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index a62eeb7..6e9e7a7 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -109,6 +109,7 @@ extern void pa_hpux_asm_output_external (FILE *, tree, const char *);
extern HOST_WIDE_INT pa_initial_elimination_offset (int, int);
extern HOST_WIDE_INT pa_function_arg_size (machine_mode, const_tree);
extern void pa_output_function_label (FILE *);
+extern void hppa_profile_hook (int);
extern const int pa_magic_milli[];
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 0d00bf6..f54ca6e 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -9805,19 +9805,22 @@ pa_som_asm_init_sections (void)
= get_unnamed_section (0, output_section_asm_op,
"\t.SPACE $PRIVATE$\n\t.SUBSPA $TM_CLONE_TABLE$");
- /* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
- which reference data within the $TEXT$ space (for example constant
+ /* HPUX ld generates incorrect GOT entries for "T" fixups which
+ reference data within the $TEXT$ space (for example constant
strings in the $LIT$ subspace).
The assemblers (GAS and HP as) both have problems with handling
- the difference of two symbols which is the other correct way to
+ the difference of two symbols. This is the other correct way to
reference constant data during PIC code generation.
- So, there's no way to reference constant data which is in the
- $TEXT$ space during PIC generation. Instead place all constant
- data into the $PRIVATE$ subspace (this reduces sharing, but it
- works correctly). */
- readonly_data_section = flag_pic ? data_section : som_readonly_data_section;
+ Thus, we can't put constant data needing relocation in the $TEXT$
+ space during PIC generation.
+
+ Previously, we placed all constant data into the $DATA$ subspace
+ when generating PIC code. This reduces sharing, but it works
+ correctly. Now we rely on pa_reloc_rw_mask() for section selection.
+ This puts constant data not needing relocation into the $TEXT$ space. */
+ readonly_data_section = som_readonly_data_section;
/* We must not have a reference to an external symbol defined in a
shared library in a readonly section, else the SOM linker will
@@ -9850,7 +9853,7 @@ pa_select_section (tree exp, int reloc,
&& DECL_INITIAL (exp)
&& (DECL_INITIAL (exp) == error_mark_node
|| TREE_CONSTANT (DECL_INITIAL (exp)))
- && !reloc)
+ && !(reloc & pa_reloc_rw_mask ()))
{
if (TARGET_SOM
&& DECL_ONE_ONLY (exp)
@@ -9859,7 +9862,8 @@ pa_select_section (tree exp, int reloc,
else
return readonly_data_section;
}
- else if (CONSTANT_CLASS_P (exp) && !reloc)
+ else if (CONSTANT_CLASS_P (exp)
+ && !(reloc & pa_reloc_rw_mask ()))
return readonly_data_section;
else if (TARGET_SOM
&& TREE_CODE (exp) == VAR_DECL
@@ -9875,12 +9879,11 @@ pa_select_section (tree exp, int reloc,
static int
pa_reloc_rw_mask (void)
{
- /* We force (const (plus (symbol) (const_int))) to memory when the
- const_int doesn't fit in a 14-bit integer. The SOM linker can't
- handle this construct in read-only memory and we want to avoid
- this for ELF. So, we always force an RTX needing relocation to
- the data section. */
- return 3;
+ if (flag_pic || (TARGET_SOM && !TARGET_HPUX_11))
+ return 3;
+
+ /* HP linker does not support global relocs in readonly memory. */
+ return TARGET_SOM ? 2 : 0;
}
static void
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 561efa5..f38a6dc 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -666,7 +666,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
(*targetm.asm_out.internal_label) (FILE, FUNC_BEGIN_PROLOG_LABEL, LABEL)
#define PROFILE_HOOK(label_no) hppa_profile_hook (label_no)
-void hppa_profile_hook (int label_no);
/* The profile counter if emitted must come before the prologue. */
#define PROFILE_BEFORE_PROLOGUE 1
diff --git a/gcc/config/riscv/pic.md b/gcc/config/riscv/pic.md
index da303e4..f16f054 100644
--- a/gcc/config/riscv/pic.md
+++ b/gcc/config/riscv/pic.md
@@ -29,14 +29,14 @@
"<default_load>\t%0,%1"
[(set (attr "length") (const_int 8))])
-(define_insn "*local_pic_load_s<mode>"
+(define_insn "*local_pic_load_s<SUBX:mode>"
[(set (match_operand:SUPERQI 0 "register_operand" "=r")
(sign_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))]
"USE_LOAD_ADDRESS_MACRO (operands[1])"
"<SUBX:load>\t%0,%1"
[(set (attr "length") (const_int 8))])
-(define_insn "*local_pic_load_u<mode>"
+(define_insn "*local_pic_load_u<SUBX:mode>"
[(set (match_operand:SUPERQI 0 "register_operand" "=r")
(zero_extend:SUPERQI (mem:SUBX (match_operand 1 "absolute_symbolic_operand" ""))))]
"USE_LOAD_ADDRESS_MACRO (operands[1])"
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index f3031f2..d00fbe2 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -46,4 +46,9 @@ enum riscv_microarchitecture_type {
};
extern enum riscv_microarchitecture_type riscv_microarchitecture;
+enum riscv_align_data {
+ riscv_align_data_type_xlen,
+ riscv_align_data_type_natural
+};
+
#endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index 8ac09f2..e274f1b 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -4904,7 +4904,8 @@ riscv_can_change_mode_class (machine_mode, machine_mode, reg_class_t rclass)
static HOST_WIDE_INT
riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align)
{
- if (TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
+ if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
+ && (riscv_align_data_type == riscv_align_data_type_xlen))
return MAX (align, BITS_PER_WORD);
return align;
}
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 4509d73..5fc9be8 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -168,6 +168,13 @@ along with GCC; see the file COPYING3. If not see
mode that should actually be used. We allow pairs of registers. */
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode)
+/* DATA_ALIGNMENT and LOCAL_ALIGNMENT common definition. */
+#define RISCV_EXPAND_ALIGNMENT(COND, TYPE, ALIGN) \
+ (((COND) && ((ALIGN) < BITS_PER_WORD) \
+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
+ || TREE_CODE (TYPE) == UNION_TYPE \
+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
+
/* If defined, a C expression to compute the alignment for a static
variable. TYPE is the data type, and ALIGN is the alignment that
the object would ordinarily have. The value of this macro is used
@@ -180,18 +187,16 @@ along with GCC; see the file COPYING3. If not see
cause character arrays to be word-aligned so that `strcpy' calls
that copy constants to character arrays can be done inline. */
-#define DATA_ALIGNMENT(TYPE, ALIGN) \
- ((((ALIGN) < BITS_PER_WORD) \
- && (TREE_CODE (TYPE) == ARRAY_TYPE \
- || TREE_CODE (TYPE) == UNION_TYPE \
- || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ RISCV_EXPAND_ALIGNMENT (riscv_align_data_type == riscv_align_data_type_xlen, \
+ TYPE, ALIGN)
/* We need this for the same reason as DATA_ALIGNMENT, namely to cause
character arrays to be word-aligned so that `strcpy' calls that copy
constants to character arrays can be done inline, and 'strcmp' can be
optimised to use word loads. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
- DATA_ALIGNMENT (TYPE, ALIGN)
+ RISCV_EXPAND_ALIGNMENT (true, TYPE, ALIGN)
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 309c109..78260fc 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -1776,10 +1776,11 @@
(set (match_dup 0)
(lshiftrt:GPR (match_dup 0) (match_dup 2)))]
{
- operands[2] = GEN_INT (BITS_PER_WORD
+ /* Op2 is a VOIDmode constant, so get the mode size from op1. */
+ operands[2] = GEN_INT (GET_MODE_BITSIZE (GET_MODE (operands[1]))
- exact_log2 (INTVAL (operands[2]) + 1));
})
-
+
;; Handle AND with 0xF...F0...0 where there are 32 to 63 zeros. This can be
;; split into two shifts. Otherwise it requires 3 instructions: li, sll, and.
(define_split
@@ -2054,7 +2055,7 @@
""
"slt%i2<u>\t%0,zero,%1"
[(set_attr "type" "slt")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<X:MODE>")])
(define_insn "*slt<u>_<X:mode><GPR:mode>"
[(set (match_operand:GPR 0 "register_operand" "= r")
@@ -2063,7 +2064,7 @@
""
"slt%i2<u>\t%0,%1,%2"
[(set_attr "type" "slt")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<X:MODE>")])
(define_insn "*sle<u>_<X:mode><GPR:mode>"
[(set (match_operand:GPR 0 "register_operand" "=r")
@@ -2075,7 +2076,7 @@
return "slt%i2<u>\t%0,%1,%2";
}
[(set_attr "type" "slt")
- (set_attr "mode" "<MODE>")])
+ (set_attr "mode" "<X:MODE>")])
;;
;; ....................
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 3b25f9a..7f0c35e 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -131,3 +131,17 @@ Mask(RVE)
mriscv-attribute
Target Report Var(riscv_emit_attribute_p) Init(-1)
Emit RISC-V ELF attribute.
+
+malign-data=
+Target RejectNegative Joined Var(riscv_align_data_type) Enum(riscv_align_data) Init(riscv_align_data_type_xlen)
+Use the given data alignment.
+
+Enum
+Name(riscv_align_data) Type(enum riscv_align_data)
+Known data alignment choices (for use with the -malign-data= option):
+
+EnumValue
+Enum(riscv_align_data) String(xlen) Value(riscv_align_data_type_xlen)
+
+EnumValue
+Enum(riscv_align_data) String(natural) Value(riscv_align_data_type_natural)
diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
index 01e1e74..75e080e 100644
--- a/gcc/config/rs6000/aix.h
+++ b/gcc/config/rs6000/aix.h
@@ -32,8 +32,7 @@
#define TARGET_AIX_OS 1
/* AIX always has a TOC. */
-#define TARGET_NO_TOC 0
-#define TARGET_TOC 1
+#define TARGET_HAS_TOC 1
#define FIXED_R2 1
/* AIX allows r13 to be used in 32-bit mode. */
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index b0b5047..1bfb577 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -43,8 +43,7 @@
/* We're not ever going to do TOCs. */
-#define TARGET_TOC 0
-#define TARGET_NO_TOC 1
+#define TARGET_HAS_TOC 0
/* Override the default rs6000 definition. */
#undef PTRDIFF_TYPE
@@ -86,6 +85,24 @@ extern int darwin_emit_picsym_stub;
#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 128
+/* Machine dependent libraries.
+ Include libmx when targeting Darwin 7.0 and above, but before libSystem,
+ since the functions are actually in libSystem but for 7.x compatibility
+ we want them to be looked for in libmx first.
+ Include libSystemStubs when compiling against 10.3 - 10.5 SDKs (we assume
+ this is the case when targetting these) - but not for 64-bit long double.
+ Don't do either for m64, the library is either a dummy or non-existent.
+*/
+
+#undef LIB_SPEC
+#define LIB_SPEC \
+"%{!static: \
+ %{!m64:%{!mlong-double-64: \
+ %{pg:%:version-compare(>< 10.3 10.5 mmacosx-version-min= -lSystemStubs_profile)} \
+ %{!pg:%:version-compare(>< 10.3 10.5 mmacosx-version-min= -lSystemStubs)} \
+ %:version-compare(>< 10.3 10.4 mmacosx-version-min= -lmx)}} \
+ -lSystem \
+}"
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. The "-faltivec" option should have been
diff --git a/gcc/config/rs6000/darwin7.h b/gcc/config/rs6000/darwin7.h
index d299074..6a3adc0 100644
--- a/gcc/config/rs6000/darwin7.h
+++ b/gcc/config/rs6000/darwin7.h
@@ -17,21 +17,11 @@ 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/>. */
-/* Machine dependent libraries. Include libmx when compiling for
- Darwin 7.0 and above, but before libSystem, since the functions are
- actually in libSystem but for 7.x compatibility we want them to be
- looked for in libmx first. Include libmx by default because otherwise
- libstdc++ isn't usable. */
-
-#undef LIB_SPEC
-#define LIB_SPEC "%{!static:\
- %:version-compare(!< 10.3 mmacosx-version-min= -lmx)\
- -lSystem}"
-
/* This generation of tools (specifically the archive tool) did not
export weak symbols from the TOC. */
#undef TARGET_WEAK_NOT_IN_ARCHIVE_TOC
#define TARGET_WEAK_NOT_IN_ARCHIVE_TOC 1
+/* Default to the last version, with most support for C++. */
#undef DEF_MIN_OSX_VERSION
#define DEF_MIN_OSX_VERSION "10.3.9"
diff --git a/gcc/config/rs6000/darwin8.h b/gcc/config/rs6000/darwin8.h
index ca4ede2..ec5a8af 100644
--- a/gcc/config/rs6000/darwin8.h
+++ b/gcc/config/rs6000/darwin8.h
@@ -17,15 +17,5 @@ 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/>. */
-/* Machine dependent libraries. Include libmx when compiling on
- Darwin 7.0 and above, but before libSystem, since the functions are
- actually in libSystem but for 7.x compatibility we want them to be
- looked for in libmx first---but only do this if 7.x compatibility
- is a concern, which it's not in 64-bit mode. Include
- libSystemStubs when compiling on (not necessarily for) 8.0 and
- above and not 64-bit long double. */
-
-#undef LIB_SPEC
-#define LIB_SPEC "%{!static:\
- %{!mlong-double-64:%{pg:-lSystemStubs_profile;:-lSystemStubs}} \
- %{!m64:%:version-compare(>< 10.3 10.4 mmacosx-version-min= -lmx)} -lSystem}"
+#undef DEF_MIN_OSX_VERSION
+#define DEF_MIN_OSX_VERSION "10.4"
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 5380f6a..bd19749 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -277,8 +277,8 @@ extern int dot_symbols;
#ifndef RS6000_BI_ARCH
/* 64-bit PowerPC Linux always has a TOC. */
-#undef TARGET_TOC
-#define TARGET_TOC 1
+#undef TARGET_HAS_TOC
+#define TARGET_HAS_TOC 1
/* Some things from sysv4.h we don't do when 64 bit. */
#undef OPTION_RELOCATABLE
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 45fa40a..5a2d2d3 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -309,7 +309,7 @@
if (!TARGET_PREFIXED_ADDR)
return 0;
- return SIGNED_34BIT_OFFSET_P (INTVAL (op), 0);
+ return SIGNED_34BIT_OFFSET_P (INTVAL (op));
})
;; Return 1 if op is a register that is not special.
@@ -703,15 +703,20 @@
;; memory references. So this function allows us to recognize volatile
;; references where it's safe.
(define_predicate "volatile_mem_operand"
- (and (and (match_code "mem")
- (match_test "MEM_VOLATILE_P (op)"))
+ (and (match_code "mem")
+ (match_test "MEM_VOLATILE_P (op)")
(if_then_else (match_test "reload_completed")
(match_operand 0 "memory_operand")
(match_test "memory_address_p (mode, XEXP (op, 0))"))))
+;; Return 1 if the operand is a volatile or non-volatile memory operand.
+(define_predicate "any_memory_operand"
+ (ior (match_operand 0 "memory_operand")
+ (match_operand 0 "volatile_mem_operand")))
+
;; Return 1 if the operand is an offsettable memory operand.
(define_predicate "offsettable_mem_operand"
- (and (match_operand 0 "memory_operand")
+ (and (match_operand 0 "any_memory_operand")
(match_test "offsettable_nonstrict_memref_p (op)")))
;; Return 1 if the operand is a simple offsettable memory operand
@@ -891,11 +896,10 @@
;; Return 1 if the operand is a general non-special register or memory operand.
(define_predicate "reg_or_mem_operand"
- (ior (match_operand 0 "memory_operand")
+ (ior (match_operand 0 "gpc_reg_operand")
+ (match_operand 0 "any_memory_operand")
(and (match_code "mem")
- (match_test "macho_lo_sum_memory_operand (op, mode)"))
- (match_operand 0 "volatile_mem_operand")
- (match_operand 0 "gpc_reg_operand")))
+ (match_test "macho_lo_sum_memory_operand (op, mode)"))))
;; Return 1 if the operand is CONST_DOUBLE 0, register or memory operand.
(define_predicate "zero_reg_mem_operand"
@@ -925,7 +929,7 @@
if (gpc_reg_operand (inner, mode))
return true;
- if (!memory_operand (inner, mode))
+ if (!any_memory_operand (inner, mode))
return false;
addr = XEXP (inner, 0);
@@ -1027,7 +1031,7 @@
const_double,const_wide_int,const_vector,const_int")
{
/* Memory is always valid. */
- if (memory_operand (op, mode))
+ if (any_memory_operand (op, mode))
return 1;
/* For floating-point, easy constants are valid. */
@@ -1638,7 +1642,7 @@
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
- if (!CONST_INT_P (op1) || !SIGNED_34BIT_OFFSET_P (INTVAL (op1), 0))
+ if (!CONST_INT_P (op1) || !SIGNED_34BIT_OFFSET_P (INTVAL (op1)))
return false;
op = op0;
@@ -1673,7 +1677,7 @@
rtx op0 = XEXP (op, 0);
rtx op1 = XEXP (op, 1);
- if (!CONST_INT_P (op1) || !SIGNED_34BIT_OFFSET_P (INTVAL (op1), 0))
+ if (!CONST_INT_P (op1) || !SIGNED_34BIT_OFFSET_P (INTVAL (op1)))
return false;
op = op0;
@@ -1686,7 +1690,7 @@
(define_predicate "prefixed_mem_operand"
(match_code "mem")
{
- return rs6000_prefixed_address (XEXP (op, 0), GET_MODE (op));
+ return rs6000_prefixed_address_mode_p (XEXP (op, 0), GET_MODE (op));
})
;; Return 1 if op is a memory operand to an external variable when we
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 7854082..7f0cdc7 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -7036,8 +7036,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
name, internal_name);
}
else
- error ("builtin function %qs not supported in this compiler "
- "configuration", name);
+ error ("%qs is not supported in this compiler configuration", name);
/* If an error-representing result tree was returned from
altivec_build_resolved_builtin above, use it. */
return (result != NULL) ? result : error_mark_node;
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
new file mode 100644
index 0000000..2ef8c7f
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -0,0 +1,8134 @@
+/* Subroutines used to generate function calls and handle built-in
+ instructions on IBM RS/6000.
+ Copyright (C) 1991-2019 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "rtl.h"
+#include "tree.h"
+#include "memmodel.h"
+#include "gimple.h"
+#include "cfghooks.h"
+#include "cfgloop.h"
+#include "df.h"
+#include "tm_p.h"
+#include "stringpool.h"
+#include "expmed.h"
+#include "optabs.h"
+#include "regs.h"
+#include "ira.h"
+#include "recog.h"
+#include "cgraph.h"
+#include "diagnostic-core.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "alias.h"
+#include "fold-const.h"
+#include "attribs.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "print-tree.h"
+#include "varasm.h"
+#include "explow.h"
+#include "expr.h"
+#include "output.h"
+#include "common/common-target.h"
+#include "langhooks.h"
+#include "gimplify.h"
+#include "gimple-fold.h"
+#include "gimple-iterator.h"
+#include "gimple-ssa.h"
+#include "builtins.h"
+#include "tree-vector-builder.h"
+#if TARGET_XCOFF
+#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
+#endif
+#include "ppc-auxv.h"
+#include "tree-ssa-propagate.h"
+#include "tree-vrp.h"
+#include "tree-ssanames.h"
+#include "targhooks.h"
+
+#include "rs6000-internal.h"
+
+#if TARGET_MACHO
+#include "gstab.h" /* for N_SLINE */
+#include "dbxout.h" /* dbxout_ */
+#endif
+
+#ifndef TARGET_PROFILE_KERNEL
+#define TARGET_PROFILE_KERNEL 0
+#endif
+
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+# ifndef HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE
+# define HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE 0
+# endif
+#endif
+
+#ifndef TARGET_NO_PROTOTYPE
+#define TARGET_NO_PROTOTYPE 0
+#endif
+
+struct builtin_description
+{
+ const HOST_WIDE_INT mask;
+ const enum insn_code icode;
+ const char *const name;
+ const enum rs6000_builtins code;
+};
+
+/* Used by __builtin_cpu_is(), mapping from PLATFORM names to values. */
+static const struct
+{
+ const char *cpu;
+ unsigned int cpuid;
+} cpu_is_info[] = {
+ { "power9", PPC_PLATFORM_POWER9 },
+ { "power8", PPC_PLATFORM_POWER8 },
+ { "power7", PPC_PLATFORM_POWER7 },
+ { "power6x", PPC_PLATFORM_POWER6X },
+ { "power6", PPC_PLATFORM_POWER6 },
+ { "power5+", PPC_PLATFORM_POWER5_PLUS },
+ { "power5", PPC_PLATFORM_POWER5 },
+ { "ppc970", PPC_PLATFORM_PPC970 },
+ { "power4", PPC_PLATFORM_POWER4 },
+ { "ppca2", PPC_PLATFORM_PPCA2 },
+ { "ppc476", PPC_PLATFORM_PPC476 },
+ { "ppc464", PPC_PLATFORM_PPC464 },
+ { "ppc440", PPC_PLATFORM_PPC440 },
+ { "ppc405", PPC_PLATFORM_PPC405 },
+ { "ppc-cell-be", PPC_PLATFORM_CELL_BE }
+};
+
+/* Used by __builtin_cpu_supports(), mapping from HWCAP names to masks. */
+static const struct
+{
+ const char *hwcap;
+ int mask;
+ unsigned int id;
+} cpu_supports_info[] = {
+ /* AT_HWCAP masks. */
+ { "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0 },
+ { "altivec", PPC_FEATURE_HAS_ALTIVEC, 0 },
+ { "arch_2_05", PPC_FEATURE_ARCH_2_05, 0 },
+ { "arch_2_06", PPC_FEATURE_ARCH_2_06, 0 },
+ { "archpmu", PPC_FEATURE_PERFMON_COMPAT, 0 },
+ { "booke", PPC_FEATURE_BOOKE, 0 },
+ { "cellbe", PPC_FEATURE_CELL_BE, 0 },
+ { "dfp", PPC_FEATURE_HAS_DFP, 0 },
+ { "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE, 0 },
+ { "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE, 0 },
+ { "fpu", PPC_FEATURE_HAS_FPU, 0 },
+ { "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, 0 },
+ { "mmu", PPC_FEATURE_HAS_MMU, 0 },
+ { "notb", PPC_FEATURE_NO_TB, 0 },
+ { "pa6t", PPC_FEATURE_PA6T, 0 },
+ { "power4", PPC_FEATURE_POWER4, 0 },
+ { "power5", PPC_FEATURE_POWER5, 0 },
+ { "power5+", PPC_FEATURE_POWER5_PLUS, 0 },
+ { "power6x", PPC_FEATURE_POWER6_EXT, 0 },
+ { "ppc32", PPC_FEATURE_32, 0 },
+ { "ppc601", PPC_FEATURE_601_INSTR, 0 },
+ { "ppc64", PPC_FEATURE_64, 0 },
+ { "ppcle", PPC_FEATURE_PPC_LE, 0 },
+ { "smt", PPC_FEATURE_SMT, 0 },
+ { "spe", PPC_FEATURE_HAS_SPE, 0 },
+ { "true_le", PPC_FEATURE_TRUE_LE, 0 },
+ { "ucache", PPC_FEATURE_UNIFIED_CACHE, 0 },
+ { "vsx", PPC_FEATURE_HAS_VSX, 0 },
+
+ /* AT_HWCAP2 masks. */
+ { "arch_2_07", PPC_FEATURE2_ARCH_2_07, 1 },
+ { "dscr", PPC_FEATURE2_HAS_DSCR, 1 },
+ { "ebb", PPC_FEATURE2_HAS_EBB, 1 },
+ { "htm", PPC_FEATURE2_HAS_HTM, 1 },
+ { "htm-nosc", PPC_FEATURE2_HTM_NOSC, 1 },
+ { "htm-no-suspend", PPC_FEATURE2_HTM_NO_SUSPEND, 1 },
+ { "isel", PPC_FEATURE2_HAS_ISEL, 1 },
+ { "tar", PPC_FEATURE2_HAS_TAR, 1 },
+ { "vcrypto", PPC_FEATURE2_HAS_VEC_CRYPTO, 1 },
+ { "arch_3_00", PPC_FEATURE2_ARCH_3_00, 1 },
+ { "ieee128", PPC_FEATURE2_HAS_IEEE128, 1 },
+ { "darn", PPC_FEATURE2_DARN, 1 },
+ { "scv", PPC_FEATURE2_SCV, 1 }
+};
+
+static void altivec_init_builtins (void);
+static tree builtin_function_type (machine_mode, machine_mode,
+ machine_mode, machine_mode,
+ enum rs6000_builtins, const char *name);
+static void rs6000_common_init_builtins (void);
+static void htm_init_builtins (void);
+
+
+/* Hash table to keep track of the argument types for builtin functions. */
+
+struct GTY((for_user)) builtin_hash_struct
+{
+ tree type;
+ machine_mode mode[4]; /* return value + 3 arguments. */
+ unsigned char uns_p[4]; /* and whether the types are unsigned. */
+};
+
+struct builtin_hasher : ggc_ptr_hash<builtin_hash_struct>
+{
+ static hashval_t hash (builtin_hash_struct *);
+ static bool equal (builtin_hash_struct *, builtin_hash_struct *);
+};
+
+static GTY (()) hash_table<builtin_hasher> *builtin_hash_table;
+
+/* Hash function for builtin functions with up to 3 arguments and a return
+ type. */
+hashval_t
+builtin_hasher::hash (builtin_hash_struct *bh)
+{
+ unsigned ret = 0;
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
+ ret = (ret * 2) + bh->uns_p[i];
+ }
+
+ return ret;
+}
+
+/* Compare builtin hash entries H1 and H2 for equivalence. */
+bool
+builtin_hasher::equal (builtin_hash_struct *p1, builtin_hash_struct *p2)
+{
+ return ((p1->mode[0] == p2->mode[0])
+ && (p1->mode[1] == p2->mode[1])
+ && (p1->mode[2] == p2->mode[2])
+ && (p1->mode[3] == p2->mode[3])
+ && (p1->uns_p[0] == p2->uns_p[0])
+ && (p1->uns_p[1] == p2->uns_p[1])
+ && (p1->uns_p[2] == p2->uns_p[2])
+ && (p1->uns_p[3] == p2->uns_p[3]));
+}
+
+
+/* Table that classifies rs6000 builtin functions (pure, const, etc.). */
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
+struct rs6000_builtin_info_type {
+ const char *name;
+ const enum insn_code icode;
+ const HOST_WIDE_INT mask;
+ const unsigned attr;
+};
+
+const struct rs6000_builtin_info_type rs6000_builtin_info[] =
+{
+#include "rs6000-builtin.def"
+};
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+
+/* Nonzero if we can use a floating-point register to pass this arg. */
+#define USE_FP_FOR_ARG_P(CUM,MODE) \
+ (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE) \
+ && (CUM)->fregno <= FP_ARG_MAX_REG \
+ && TARGET_HARD_FLOAT)
+
+/* Nonzero if we can use an AltiVec register to pass this arg. */
+#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,NAMED) \
+ (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
+ && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
+ && TARGET_ALTIVEC_ABI \
+ && (NAMED))
+
+/* Walk down the type tree of TYPE counting consecutive base elements.
+ If *MODEP is VOIDmode, then set it to the first valid floating point
+ or vector type. If a non-floating point or vector type is found, or
+ if a floating point or vector type that doesn't match a non-VOIDmode
+ *MODEP is found, then return -1, otherwise return the count in the
+ sub-tree. */
+
+static int
+rs6000_aggregate_candidate (const_tree type, machine_mode *modep)
+{
+ machine_mode mode;
+ HOST_WIDE_INT size;
+
+ switch (TREE_CODE (type))
+ {
+ case REAL_TYPE:
+ mode = TYPE_MODE (type);
+ if (!SCALAR_FLOAT_MODE_P (mode))
+ return -1;
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ if (*modep == mode)
+ return 1;
+
+ break;
+
+ case COMPLEX_TYPE:
+ mode = TYPE_MODE (TREE_TYPE (type));
+ if (!SCALAR_FLOAT_MODE_P (mode))
+ return -1;
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ if (*modep == mode)
+ return 2;
+
+ break;
+
+ case VECTOR_TYPE:
+ if (!TARGET_ALTIVEC_ABI || !TARGET_ALTIVEC)
+ return -1;
+
+ /* Use V4SImode as representative of all 128-bit vector types. */
+ size = int_size_in_bytes (type);
+ switch (size)
+ {
+ case 16:
+ mode = V4SImode;
+ break;
+ default:
+ return -1;
+ }
+
+ if (*modep == VOIDmode)
+ *modep = mode;
+
+ /* Vector modes are considered to be opaque: two vectors are
+ equivalent for the purposes of being homogeneous aggregates
+ if they are the same size. */
+ if (*modep == mode)
+ return 1;
+
+ break;
+
+ case ARRAY_TYPE:
+ {
+ int count;
+ tree index = TYPE_DOMAIN (type);
+
+ /* Can't handle incomplete types nor sizes that are not
+ fixed. */
+ if (!COMPLETE_TYPE_P (type)
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ return -1;
+
+ count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
+ if (count == -1
+ || !index
+ || !TYPE_MAX_VALUE (index)
+ || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index))
+ || !TYPE_MIN_VALUE (index)
+ || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index))
+ || count < 0)
+ return -1;
+
+ count *= (1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
+ - tree_to_uhwi (TYPE_MIN_VALUE (index)));
+
+ /* There must be no padding. */
+ if (wi::to_wide (TYPE_SIZE (type))
+ != count * GET_MODE_BITSIZE (*modep))
+ return -1;
+
+ return count;
+ }
+
+ case RECORD_TYPE:
+ {
+ int count = 0;
+ int sub_count;
+ tree field;
+
+ /* Can't handle incomplete types nor sizes that are not
+ fixed. */
+ if (!COMPLETE_TYPE_P (type)
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ return -1;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+ if (sub_count < 0)
+ return -1;
+ count += sub_count;
+ }
+
+ /* There must be no padding. */
+ if (wi::to_wide (TYPE_SIZE (type))
+ != count * GET_MODE_BITSIZE (*modep))
+ return -1;
+
+ return count;
+ }
+
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ /* These aren't very interesting except in a degenerate case. */
+ int count = 0;
+ int sub_count;
+ tree field;
+
+ /* Can't handle incomplete types nor sizes that are not
+ fixed. */
+ if (!COMPLETE_TYPE_P (type)
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ return -1;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
+ if (sub_count < 0)
+ return -1;
+ count = count > sub_count ? count : sub_count;
+ }
+
+ /* There must be no padding. */
+ if (wi::to_wide (TYPE_SIZE (type))
+ != count * GET_MODE_BITSIZE (*modep))
+ return -1;
+
+ return count;
+ }
+
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+/* If an argument, whose type is described by TYPE and MODE, is a homogeneous
+ float or vector aggregate that shall be passed in FP/vector registers
+ according to the ELFv2 ABI, return the homogeneous element mode in
+ *ELT_MODE and the number of elements in *N_ELTS, and return TRUE.
+
+ Otherwise, set *ELT_MODE to MODE and *N_ELTS to 1, and return FALSE. */
+
+bool
+rs6000_discover_homogeneous_aggregate (machine_mode mode, const_tree type,
+ machine_mode *elt_mode,
+ int *n_elts)
+{
+ /* Note that we do not accept complex types at the top level as
+ homogeneous aggregates; these types are handled via the
+ targetm.calls.split_complex_arg mechanism. Complex types
+ can be elements of homogeneous aggregates, however. */
+ if (TARGET_HARD_FLOAT && DEFAULT_ABI == ABI_ELFv2 && type
+ && AGGREGATE_TYPE_P (type))
+ {
+ machine_mode field_mode = VOIDmode;
+ int field_count = rs6000_aggregate_candidate (type, &field_mode);
+
+ if (field_count > 0)
+ {
+ int reg_size = ALTIVEC_OR_VSX_VECTOR_MODE (field_mode) ? 16 : 8;
+ int field_size = ROUND_UP (GET_MODE_SIZE (field_mode), reg_size);
+
+ /* The ELFv2 ABI allows homogeneous aggregates to occupy
+ up to AGGR_ARG_NUM_REG registers. */
+ if (field_count * field_size <= AGGR_ARG_NUM_REG * reg_size)
+ {
+ if (elt_mode)
+ *elt_mode = field_mode;
+ if (n_elts)
+ *n_elts = field_count;
+ return true;
+ }
+ }
+ }
+
+ if (elt_mode)
+ *elt_mode = mode;
+ if (n_elts)
+ *n_elts = 1;
+ return false;
+}
+
+/* Return a nonzero value to say to return the function value in
+ memory, just as large structures are always returned. TYPE will be
+ the data type of the value, and FNTYPE will be the type of the
+ function doing the returning, or @code{NULL} for libcalls.
+
+ The AIX ABI for the RS/6000 specifies that all structures are
+ returned in memory. The Darwin ABI does the same.
+
+ For the Darwin 64 Bit ABI, a function result can be returned in
+ registers or in memory, depending on the size of the return data
+ type. If it is returned in registers, the value occupies the same
+ registers as it would if it were the first and only function
+ argument. Otherwise, the function places its result in memory at
+ the location pointed to by GPR3.
+
+ The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
+ but a draft put them in memory, and GCC used to implement the draft
+ instead of the final standard. Therefore, aix_struct_return
+ controls this instead of DEFAULT_ABI; V.4 targets needing backward
+ compatibility can change DRAFT_V4_STRUCT_RET to override the
+ default, and -m switches get the final word. See
+ rs6000_option_override_internal for more details.
+
+ The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
+ long double support is enabled. These values are returned in memory.
+
+ int_size_in_bytes returns -1 for variable size objects, which go in
+ memory always. The cast to unsigned makes -1 > 8. */
+
+bool
+rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
+{
+ /* For the Darwin64 ABI, test if we can fit the return value in regs. */
+ if (TARGET_MACHO
+ && rs6000_darwin64_abi
+ && TREE_CODE (type) == RECORD_TYPE
+ && int_size_in_bytes (type) > 0)
+ {
+ CUMULATIVE_ARGS valcum;
+ rtx valret;
+
+ valcum.words = 0;
+ valcum.fregno = FP_ARG_MIN_REG;
+ valcum.vregno = ALTIVEC_ARG_MIN_REG;
+ /* Do a trial code generation as if this were going to be passed
+ as an argument; if any part goes in memory, we return NULL. */
+ valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
+ if (valret)
+ return false;
+ /* Otherwise fall through to more conventional ABI rules. */
+ }
+
+ /* The ELFv2 ABI returns homogeneous VFP aggregates in registers */
+ if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (type), type,
+ NULL, NULL))
+ return false;
+
+ /* The ELFv2 ABI returns aggregates up to 16B in registers */
+ if (DEFAULT_ABI == ABI_ELFv2 && AGGREGATE_TYPE_P (type)
+ && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) <= 16)
+ return false;
+
+ if (AGGREGATE_TYPE_P (type)
+ && (aix_struct_return
+ || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
+ return true;
+
+ /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
+ modes only exist for GCC vector types if -maltivec. */
+ if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ return false;
+
+ /* Return synthetic vectors in memory. */
+ if (TREE_CODE (type) == VECTOR_TYPE
+ && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
+ {
+ static bool warned_for_return_big_vectors = false;
+ if (!warned_for_return_big_vectors)
+ {
+ warning (OPT_Wpsabi, "GCC vector returned by reference: "
+ "non-standard ABI extension with no compatibility "
+ "guarantee");
+ warned_for_return_big_vectors = true;
+ }
+ return true;
+ }
+
+ if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD
+ && FLOAT128_IEEE_P (TYPE_MODE (type)))
+ return true;
+
+ return false;
+}
+
+/* Specify whether values returned in registers should be at the most
+ significant end of a register. We want aggregates returned by
+ value to match the way aggregates are passed to functions. */
+
+bool
+rs6000_return_in_msb (const_tree valtype)
+{
+ return (DEFAULT_ABI == ABI_ELFv2
+ && BYTES_BIG_ENDIAN
+ && AGGREGATE_TYPE_P (valtype)
+ && (rs6000_function_arg_padding (TYPE_MODE (valtype), valtype)
+ == PAD_UPWARD));
+}
+
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+/* Return TRUE if a call to function FNDECL may be one that
+ potentially affects the function calling ABI of the object file. */
+
+static bool
+call_ABI_of_interest (tree fndecl)
+{
+ if (rs6000_gnu_attr && symtab->state == EXPANSION)
+ {
+ struct cgraph_node *c_node;
+
+ /* Libcalls are always interesting. */
+ if (fndecl == NULL_TREE)
+ return true;
+
+ /* Any call to an external function is interesting. */
+ if (DECL_EXTERNAL (fndecl))
+ return true;
+
+ /* Interesting functions that we are emitting in this object file. */
+ c_node = cgraph_node::get (fndecl);
+ c_node = c_node->ultimate_alias_target ();
+ return !c_node->only_called_directly_p ();
+ }
+ return false;
+}
+#endif
+
+/* Initialize a variable CUM of type CUMULATIVE_ARGS
+ for a call to a function whose data type is FNTYPE.
+ For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
+
+ For incoming args we set the number of arguments in the prototype large
+ so we never return a PARALLEL. */
+
+void
+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
+ rtx libname ATTRIBUTE_UNUSED, int incoming,
+ int libcall, int n_named_args,
+ tree fndecl,
+ machine_mode return_mode ATTRIBUTE_UNUSED)
+{
+ static CUMULATIVE_ARGS zero_cumulative;
+
+ *cum = zero_cumulative;
+ cum->words = 0;
+ cum->fregno = FP_ARG_MIN_REG;
+ cum->vregno = ALTIVEC_ARG_MIN_REG;
+ cum->prototype = (fntype && prototype_p (fntype));
+ cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
+ ? CALL_LIBCALL : CALL_NORMAL);
+ cum->sysv_gregno = GP_ARG_MIN_REG;
+ cum->stdarg = stdarg_p (fntype);
+ cum->libcall = libcall;
+
+ cum->nargs_prototype = 0;
+ if (incoming || cum->prototype)
+ cum->nargs_prototype = n_named_args;
+
+ /* Check for a longcall attribute. */
+ if ((!fntype && rs6000_default_long_calls)
+ || (fntype
+ && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
+ && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
+ cum->call_cookie |= CALL_LONG;
+ else if (DEFAULT_ABI != ABI_DARWIN)
+ {
+ bool is_local = (fndecl
+ && !DECL_EXTERNAL (fndecl)
+ && !DECL_WEAK (fndecl)
+ && (*targetm.binds_local_p) (fndecl));
+ if (is_local)
+ ;
+ else if (flag_plt)
+ {
+ if (fntype
+ && lookup_attribute ("noplt", TYPE_ATTRIBUTES (fntype)))
+ cum->call_cookie |= CALL_LONG;
+ }
+ else
+ {
+ if (!(fntype
+ && lookup_attribute ("plt", TYPE_ATTRIBUTES (fntype))))
+ cum->call_cookie |= CALL_LONG;
+ }
+ }
+
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "\ninit_cumulative_args:");
+ if (fntype)
+ {
+ tree ret_type = TREE_TYPE (fntype);
+ fprintf (stderr, " ret code = %s,",
+ get_tree_code_name (TREE_CODE (ret_type)));
+ }
+
+ if (cum->call_cookie & CALL_LONG)
+ fprintf (stderr, " longcall,");
+
+ fprintf (stderr, " proto = %d, nargs = %d\n",
+ cum->prototype, cum->nargs_prototype);
+ }
+
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+ if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4))
+ {
+ cum->escapes = call_ABI_of_interest (fndecl);
+ if (cum->escapes)
+ {
+ tree return_type;
+
+ if (fntype)
+ {
+ return_type = TREE_TYPE (fntype);
+ return_mode = TYPE_MODE (return_type);
+ }
+ else
+ return_type = lang_hooks.types.type_for_mode (return_mode, 0);
+
+ if (return_type != NULL)
+ {
+ if (TREE_CODE (return_type) == RECORD_TYPE
+ && TYPE_TRANSPARENT_AGGR (return_type))
+ {
+ return_type = TREE_TYPE (first_field (return_type));
+ return_mode = TYPE_MODE (return_type);
+ }
+ if (AGGREGATE_TYPE_P (return_type)
+ && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
+ <= 8))
+ rs6000_returns_struct = true;
+ }
+ if (SCALAR_FLOAT_MODE_P (return_mode))
+ {
+ rs6000_passes_float = true;
+ if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE || TARGET_64BIT)
+ && (FLOAT128_IBM_P (return_mode)
+ || FLOAT128_IEEE_P (return_mode)
+ || (return_type != NULL
+ && (TYPE_MAIN_VARIANT (return_type)
+ == long_double_type_node))))
+ rs6000_passes_long_double = true;
+
+ /* Note if we passed or return a IEEE 128-bit type. We changed
+ the mangling for these types, and we may need to make an alias
+ with the old mangling. */
+ if (FLOAT128_IEEE_P (return_mode))
+ rs6000_passes_ieee128 = true;
+ }
+ if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode))
+ rs6000_passes_vector = true;
+ }
+ }
+#endif
+
+ if (fntype
+ && !TARGET_ALTIVEC
+ && TARGET_ALTIVEC_ABI
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
+ {
+ error ("cannot return value in vector register because"
+ " altivec instructions are disabled, use %qs"
+ " to enable them", "-maltivec");
+ }
+}
+
+
+/* On rs6000, function arguments are promoted, as are function return
+ values. */
+
+machine_mode
+rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
+ machine_mode mode,
+ int *punsignedp ATTRIBUTE_UNUSED,
+ const_tree, int)
+{
+ PROMOTE_MODE (mode, *punsignedp, type);
+
+ return mode;
+}
+
+/* Return true if TYPE must be passed on the stack and not in registers. */
+
+bool
+rs6000_must_pass_in_stack (machine_mode mode, const_tree type)
+{
+ if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2 || TARGET_64BIT)
+ return must_pass_in_stack_var_size (mode, type);
+ else
+ return must_pass_in_stack_var_size_or_pad (mode, type);
+}
+
+static inline bool
+is_complex_IBM_long_double (machine_mode mode)
+{
+ return mode == ICmode || (mode == TCmode && FLOAT128_IBM_P (TCmode));
+}
+
+/* Whether ABI_V4 passes MODE args to a function in floating point
+ registers. */
+
+static bool
+abi_v4_pass_in_fpr (machine_mode mode, bool named)
+{
+ if (!TARGET_HARD_FLOAT)
+ return false;
+ if (mode == DFmode)
+ return true;
+ if (mode == SFmode && named)
+ return true;
+ /* ABI_V4 passes complex IBM long double in 8 gprs.
+ Stupid, but we can't change the ABI now. */
+ if (is_complex_IBM_long_double (mode))
+ return false;
+ if (FLOAT128_2REG_P (mode))
+ return true;
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ return true;
+ return false;
+}
+
+/* Implement TARGET_FUNCTION_ARG_PADDING.
+
+ For the AIX ABI structs are always stored left shifted in their
+ argument slot. */
+
+pad_direction
+rs6000_function_arg_padding (machine_mode mode, const_tree type)
+{
+#ifndef AGGREGATE_PADDING_FIXED
+#define AGGREGATE_PADDING_FIXED 0
+#endif
+#ifndef AGGREGATES_PAD_UPWARD_ALWAYS
+#define AGGREGATES_PAD_UPWARD_ALWAYS 0
+#endif
+
+ if (!AGGREGATE_PADDING_FIXED)
+ {
+ /* GCC used to pass structures of the same size as integer types as
+ if they were in fact integers, ignoring TARGET_FUNCTION_ARG_PADDING.
+ i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
+ passed padded downward, except that -mstrict-align further
+ muddied the water in that multi-component structures of 2 and 4
+ bytes in size were passed padded upward.
+
+ The following arranges for best compatibility with previous
+ versions of gcc, but removes the -mstrict-align dependency. */
+ if (BYTES_BIG_ENDIAN)
+ {
+ HOST_WIDE_INT size = 0;
+
+ if (mode == BLKmode)
+ {
+ if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+ size = int_size_in_bytes (type);
+ }
+ else
+ size = GET_MODE_SIZE (mode);
+
+ if (size == 1 || size == 2 || size == 4)
+ return PAD_DOWNWARD;
+ }
+ return PAD_UPWARD;
+ }
+
+ if (AGGREGATES_PAD_UPWARD_ALWAYS)
+ {
+ if (type != 0 && AGGREGATE_TYPE_P (type))
+ return PAD_UPWARD;
+ }
+
+ /* Fall back to the default. */
+ return default_function_arg_padding (mode, type);
+}
+
+/* If defined, a C expression that gives the alignment boundary, in bits,
+ of an argument with the specified mode and type. If it is not defined,
+ PARM_BOUNDARY is used for all arguments.
+
+ V.4 wants long longs and doubles to be double word aligned. Just
+ testing the mode size is a boneheaded way to do this as it means
+ that other types such as complex int are also double word aligned.
+ However, we're stuck with this because changing the ABI might break
+ existing library interfaces.
+
+ Quadword align Altivec/VSX vectors.
+ Quadword align large synthetic vector types. */
+
+unsigned int
+rs6000_function_arg_boundary (machine_mode mode, const_tree type)
+{
+ machine_mode elt_mode;
+ int n_elts;
+
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+
+ if (DEFAULT_ABI == ABI_V4
+ && (GET_MODE_SIZE (mode) == 8
+ || (TARGET_HARD_FLOAT
+ && !is_complex_IBM_long_double (mode)
+ && FLOAT128_2REG_P (mode))))
+ return 64;
+ else if (FLOAT128_VECTOR_P (mode))
+ return 128;
+ else if (type && TREE_CODE (type) == VECTOR_TYPE
+ && int_size_in_bytes (type) >= 8
+ && int_size_in_bytes (type) < 16)
+ return 64;
+ else if (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode)
+ || (type && TREE_CODE (type) == VECTOR_TYPE
+ && int_size_in_bytes (type) >= 16))
+ return 128;
+
+ /* Aggregate types that need > 8 byte alignment are quadword-aligned
+ in the parameter area in the ELFv2 ABI, and in the AIX ABI unless
+ -mcompat-align-parm is used. */
+ if (((DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm)
+ || DEFAULT_ABI == ABI_ELFv2)
+ && type && TYPE_ALIGN (type) > 64)
+ {
+ /* "Aggregate" means any AGGREGATE_TYPE except for single-element
+ or homogeneous float/vector aggregates here. We already handled
+ vector aggregates above, but still need to check for float here. */
+ bool aggregate_p = (AGGREGATE_TYPE_P (type)
+ && !SCALAR_FLOAT_MODE_P (elt_mode));
+
+ /* We used to check for BLKmode instead of the above aggregate type
+ check. Warn when this results in any difference to the ABI. */
+ if (aggregate_p != (mode == BLKmode))
+ {
+ static bool warned;
+ if (!warned && warn_psabi)
+ {
+ warned = true;
+ inform (input_location,
+ "the ABI of passing aggregates with %d-byte alignment"
+ " has changed in GCC 5",
+ (int) TYPE_ALIGN (type) / BITS_PER_UNIT);
+ }
+ }
+
+ if (aggregate_p)
+ return 128;
+ }
+
+ /* Similar for the Darwin64 ABI. Note that for historical reasons we
+ implement the "aggregate type" check as a BLKmode check here; this
+ means certain aggregate types are in fact not aligned. */
+ if (TARGET_MACHO && rs6000_darwin64_abi
+ && mode == BLKmode
+ && type && TYPE_ALIGN (type) > 64)
+ return 128;
+
+ return PARM_BOUNDARY;
+}
+
+/* The offset in words to the start of the parameter save area. */
+
+static unsigned int
+rs6000_parm_offset (void)
+{
+ return (DEFAULT_ABI == ABI_V4 ? 2
+ : DEFAULT_ABI == ABI_ELFv2 ? 4
+ : 6);
+}
+
+/* For a function parm of MODE and TYPE, return the starting word in
+ the parameter area. NWORDS of the parameter area are already used. */
+
+static unsigned int
+rs6000_parm_start (machine_mode mode, const_tree type,
+ unsigned int nwords)
+{
+ unsigned int align;
+
+ align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
+ return nwords + (-(rs6000_parm_offset () + nwords) & align);
+}
+
+/* Compute the size (in words) of a function argument. */
+
+static unsigned long
+rs6000_arg_size (machine_mode mode, const_tree type)
+{
+ unsigned long size;
+
+ if (mode != BLKmode)
+ size = GET_MODE_SIZE (mode);
+ else
+ size = int_size_in_bytes (type);
+
+ if (TARGET_32BIT)
+ return (size + 3) >> 2;
+ else
+ return (size + 7) >> 3;
+}
+
+/* Use this to flush pending int fields. */
+
+static void
+rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
+ HOST_WIDE_INT bitpos, int final)
+{
+ unsigned int startbit, endbit;
+ int intregs, intoffset;
+
+ /* Handle the situations where a float is taking up the first half
+ of the GPR, and the other half is empty (typically due to
+ alignment restrictions). We can detect this by a 8-byte-aligned
+ int field, or by seeing that this is the final flush for this
+ argument. Count the word and continue on. */
+ if (cum->floats_in_gpr == 1
+ && (cum->intoffset % 64 == 0
+ || (cum->intoffset == -1 && final)))
+ {
+ cum->words++;
+ cum->floats_in_gpr = 0;
+ }
+
+ if (cum->intoffset == -1)
+ return;
+
+ intoffset = cum->intoffset;
+ cum->intoffset = -1;
+ cum->floats_in_gpr = 0;
+
+ if (intoffset % BITS_PER_WORD != 0)
+ {
+ unsigned int bits = BITS_PER_WORD - intoffset % BITS_PER_WORD;
+ if (!int_mode_for_size (bits, 0).exists ())
+ {
+ /* We couldn't find an appropriate mode, which happens,
+ e.g., in packed structs when there are 3 bytes to load.
+ Back intoffset back to the beginning of the word in this
+ case. */
+ intoffset = ROUND_DOWN (intoffset, BITS_PER_WORD);
+ }
+ }
+
+ startbit = ROUND_DOWN (intoffset, BITS_PER_WORD);
+ endbit = ROUND_UP (bitpos, BITS_PER_WORD);
+ intregs = (endbit - startbit) / BITS_PER_WORD;
+ cum->words += intregs;
+ /* words should be unsigned. */
+ if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
+ {
+ int pad = (endbit/BITS_PER_WORD) - cum->words;
+ cum->words += pad;
+ }
+}
+
+/* The darwin64 ABI calls for us to recurse down through structs,
+ looking for elements passed in registers. Unfortunately, we have
+ to track int register count here also because of misalignments
+ in powerpc alignment mode. */
+
+static void
+rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
+ const_tree type,
+ HOST_WIDE_INT startbitpos)
+{
+ tree f;
+
+ for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL)
+ {
+ HOST_WIDE_INT bitpos = startbitpos;
+ tree ftype = TREE_TYPE (f);
+ machine_mode mode;
+ if (ftype == error_mark_node)
+ continue;
+ mode = TYPE_MODE (ftype);
+
+ if (DECL_SIZE (f) != 0
+ && tree_fits_uhwi_p (bit_position (f)))
+ bitpos += int_bit_position (f);
+
+ /* ??? FIXME: else assume zero offset. */
+
+ if (TREE_CODE (ftype) == RECORD_TYPE)
+ rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
+ else if (USE_FP_FOR_ARG_P (cum, mode))
+ {
+ unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
+ rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
+ cum->fregno += n_fpregs;
+ /* Single-precision floats present a special problem for
+ us, because they are smaller than an 8-byte GPR, and so
+ the structure-packing rules combined with the standard
+ varargs behavior mean that we want to pack float/float
+ and float/int combinations into a single register's
+ space. This is complicated by the arg advance flushing,
+ which works on arbitrarily large groups of int-type
+ fields. */
+ if (mode == SFmode)
+ {
+ if (cum->floats_in_gpr == 1)
+ {
+ /* Two floats in a word; count the word and reset
+ the float count. */
+ cum->words++;
+ cum->floats_in_gpr = 0;
+ }
+ else if (bitpos % 64 == 0)
+ {
+ /* A float at the beginning of an 8-byte word;
+ count it and put off adjusting cum->words until
+ we see if a arg advance flush is going to do it
+ for us. */
+ cum->floats_in_gpr++;
+ }
+ else
+ {
+ /* The float is at the end of a word, preceded
+ by integer fields, so the arg advance flush
+ just above has already set cum->words and
+ everything is taken care of. */
+ }
+ }
+ else
+ cum->words += n_fpregs;
+ }
+ else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, 1))
+ {
+ rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
+ cum->vregno++;
+ cum->words += 2;
+ }
+ else if (cum->intoffset == -1)
+ cum->intoffset = bitpos;
+ }
+}
+
+/* Check for an item that needs to be considered specially under the darwin 64
+ bit ABI. These are record types where the mode is BLK or the structure is
+ 8 bytes in size. */
+int
+rs6000_darwin64_struct_check_p (machine_mode mode, const_tree type)
+{
+ return rs6000_darwin64_abi
+ && ((mode == BLKmode
+ && TREE_CODE (type) == RECORD_TYPE
+ && int_size_in_bytes (type) > 0)
+ || (type && TREE_CODE (type) == RECORD_TYPE
+ && int_size_in_bytes (type) == 8)) ? 1 : 0;
+}
+
+/* Update the data in CUM to advance over an argument
+ of mode MODE and data type TYPE.
+ (TYPE is null for libcalls where that information may not be available.)
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
+
+static void
+rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
+ const_tree type, bool named, int depth)
+{
+ machine_mode elt_mode;
+ int n_elts;
+
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+
+ /* Only tick off an argument if we're not recursing. */
+ if (depth == 0)
+ cum->nargs_prototype--;
+
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+ if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4)
+ && cum->escapes)
+ {
+ if (SCALAR_FLOAT_MODE_P (mode))
+ {
+ rs6000_passes_float = true;
+ if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE || TARGET_64BIT)
+ && (FLOAT128_IBM_P (mode)
+ || FLOAT128_IEEE_P (mode)
+ || (type != NULL
+ && TYPE_MAIN_VARIANT (type) == long_double_type_node)))
+ rs6000_passes_long_double = true;
+
+ /* Note if we passed or return a IEEE 128-bit type. We changed the
+ mangling for these types, and we may need to make an alias with
+ the old mangling. */
+ if (FLOAT128_IEEE_P (mode))
+ rs6000_passes_ieee128 = true;
+ }
+ if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
+ rs6000_passes_vector = true;
+ }
+#endif
+
+ if (TARGET_ALTIVEC_ABI
+ && (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode)
+ || (type && TREE_CODE (type) == VECTOR_TYPE
+ && int_size_in_bytes (type) == 16)))
+ {
+ bool stack = false;
+
+ if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
+ {
+ cum->vregno += n_elts;
+
+ if (!TARGET_ALTIVEC)
+ error ("cannot pass argument in vector register because"
+ " altivec instructions are disabled, use %qs"
+ " to enable them", "-maltivec");
+
+ /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
+ even if it is going to be passed in a vector register.
+ Darwin does the same for variable-argument functions. */
+ if (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && TARGET_64BIT)
+ || (cum->stdarg && DEFAULT_ABI != ABI_V4))
+ stack = true;
+ }
+ else
+ stack = true;
+
+ if (stack)
+ {
+ int align;
+
+ /* Vector parameters must be 16-byte aligned. In 32-bit
+ mode this means we need to take into account the offset
+ to the parameter save area. In 64-bit mode, they just
+ have to start on an even word, since the parameter save
+ area is 16-byte aligned. */
+ if (TARGET_32BIT)
+ align = -(rs6000_parm_offset () + cum->words) & 3;
+ else
+ align = cum->words & 1;
+ cum->words += align + rs6000_arg_size (mode, type);
+
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "function_adv: words = %2d, align=%d, ",
+ cum->words, align);
+ fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
+ cum->nargs_prototype, cum->prototype,
+ GET_MODE_NAME (mode));
+ }
+ }
+ }
+ else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
+ {
+ int size = int_size_in_bytes (type);
+ /* Variable sized types have size == -1 and are
+ treated as if consisting entirely of ints.
+ Pad to 16 byte boundary if needed. */
+ if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
+ && (cum->words % 2) != 0)
+ cum->words++;
+ /* For varargs, we can just go up by the size of the struct. */
+ if (!named)
+ cum->words += (size + 7) / 8;
+ else
+ {
+ /* It is tempting to say int register count just goes up by
+ sizeof(type)/8, but this is wrong in a case such as
+ { int; double; int; } [powerpc alignment]. We have to
+ grovel through the fields for these too. */
+ cum->intoffset = 0;
+ cum->floats_in_gpr = 0;
+ rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
+ rs6000_darwin64_record_arg_advance_flush (cum,
+ size * BITS_PER_UNIT, 1);
+ }
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
+ cum->words, TYPE_ALIGN (type), size);
+ fprintf (stderr,
+ "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
+ cum->nargs_prototype, cum->prototype,
+ GET_MODE_NAME (mode));
+ }
+ }
+ else if (DEFAULT_ABI == ABI_V4)
+ {
+ if (abi_v4_pass_in_fpr (mode, named))
+ {
+ /* _Decimal128 must use an even/odd register pair. This assumes
+ that the register number is odd when fregno is odd. */
+ if (mode == TDmode && (cum->fregno % 2) == 1)
+ cum->fregno++;
+
+ if (cum->fregno + (FLOAT128_2REG_P (mode) ? 1 : 0)
+ <= FP_ARG_V4_MAX_REG)
+ cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
+ else
+ {
+ cum->fregno = FP_ARG_V4_MAX_REG + 1;
+ if (mode == DFmode || FLOAT128_IBM_P (mode)
+ || mode == DDmode || mode == TDmode)
+ cum->words += cum->words & 1;
+ cum->words += rs6000_arg_size (mode, type);
+ }
+ }
+ else
+ {
+ int n_words = rs6000_arg_size (mode, type);
+ int gregno = cum->sysv_gregno;
+
+ /* Long long is put in (r3,r4), (r5,r6), (r7,r8) or (r9,r10).
+ As does any other 2 word item such as complex int due to a
+ historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
+
+ /* Multi-reg args are not split between registers and stack. */
+ if (gregno + n_words - 1 > GP_ARG_MAX_REG)
+ {
+ /* Long long is aligned on the stack. So are other 2 word
+ items such as complex int due to a historical mistake. */
+ if (n_words == 2)
+ cum->words += cum->words & 1;
+ cum->words += n_words;
+ }
+
+ /* Note: continuing to accumulate gregno past when we've started
+ spilling to the stack indicates the fact that we've started
+ spilling to the stack to expand_builtin_saveregs. */
+ cum->sysv_gregno = gregno + n_words;
+ }
+
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
+ cum->words, cum->fregno);
+ fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
+ cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
+ fprintf (stderr, "mode = %4s, named = %d\n",
+ GET_MODE_NAME (mode), named);
+ }
+ }
+ else
+ {
+ int n_words = rs6000_arg_size (mode, type);
+ int start_words = cum->words;
+ int align_words = rs6000_parm_start (mode, type, start_words);
+
+ cum->words = align_words + n_words;
+
+ if (SCALAR_FLOAT_MODE_P (elt_mode) && TARGET_HARD_FLOAT)
+ {
+ /* _Decimal128 must be passed in an even/odd float register pair.
+ This assumes that the register number is odd when fregno is
+ odd. */
+ if (elt_mode == TDmode && (cum->fregno % 2) == 1)
+ cum->fregno++;
+ cum->fregno += n_elts * ((GET_MODE_SIZE (elt_mode) + 7) >> 3);
+ }
+
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
+ cum->words, cum->fregno);
+ fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
+ cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
+ fprintf (stderr, "named = %d, align = %d, depth = %d\n",
+ named, align_words - start_words, depth);
+ }
+ }
+}
+
+void
+rs6000_function_arg_advance (cumulative_args_t cum, machine_mode mode,
+ const_tree type, bool named)
+{
+ rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
+ 0);
+}
+
+/* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
+ structure between cum->intoffset and bitpos to integer registers. */
+
+static void
+rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
+ HOST_WIDE_INT bitpos, rtx rvec[], int *k)
+{
+ machine_mode mode;
+ unsigned int regno;
+ unsigned int startbit, endbit;
+ int this_regno, intregs, intoffset;
+ rtx reg;
+
+ if (cum->intoffset == -1)
+ return;
+
+ intoffset = cum->intoffset;
+ cum->intoffset = -1;
+
+ /* If this is the trailing part of a word, try to only load that
+ much into the register. Otherwise load the whole register. Note
+ that in the latter case we may pick up unwanted bits. It's not a
+ problem at the moment but may wish to revisit. */
+
+ if (intoffset % BITS_PER_WORD != 0)
+ {
+ unsigned int bits = BITS_PER_WORD - intoffset % BITS_PER_WORD;
+ if (!int_mode_for_size (bits, 0).exists (&mode))
+ {
+ /* We couldn't find an appropriate mode, which happens,
+ e.g., in packed structs when there are 3 bytes to load.
+ Back intoffset back to the beginning of the word in this
+ case. */
+ intoffset = ROUND_DOWN (intoffset, BITS_PER_WORD);
+ mode = word_mode;
+ }
+ }
+ else
+ mode = word_mode;
+
+ startbit = ROUND_DOWN (intoffset, BITS_PER_WORD);
+ endbit = ROUND_UP (bitpos, BITS_PER_WORD);
+ intregs = (endbit - startbit) / BITS_PER_WORD;
+ this_regno = cum->words + intoffset / BITS_PER_WORD;
+
+ if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
+ cum->use_stack = 1;
+
+ intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
+ if (intregs <= 0)
+ return;
+
+ intoffset /= BITS_PER_UNIT;
+ do
+ {
+ regno = GP_ARG_MIN_REG + this_regno;
+ reg = gen_rtx_REG (mode, regno);
+ rvec[(*k)++] =
+ gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
+
+ this_regno += 1;
+ intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
+ mode = word_mode;
+ intregs -= 1;
+ }
+ while (intregs > 0);
+}
+
+/* Recursive workhorse for the following. */
+
+static void
+rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
+ HOST_WIDE_INT startbitpos, rtx rvec[],
+ int *k)
+{
+ tree f;
+
+ for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
+ if (TREE_CODE (f) == FIELD_DECL)
+ {
+ HOST_WIDE_INT bitpos = startbitpos;
+ tree ftype = TREE_TYPE (f);
+ machine_mode mode;
+ if (ftype == error_mark_node)
+ continue;
+ mode = TYPE_MODE (ftype);
+
+ if (DECL_SIZE (f) != 0
+ && tree_fits_uhwi_p (bit_position (f)))
+ bitpos += int_bit_position (f);
+
+ /* ??? FIXME: else assume zero offset. */
+
+ if (TREE_CODE (ftype) == RECORD_TYPE)
+ rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
+ else if (cum->named && USE_FP_FOR_ARG_P (cum, mode))
+ {
+ unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
+#if 0
+ switch (mode)
+ {
+ case E_SCmode: mode = SFmode; break;
+ case E_DCmode: mode = DFmode; break;
+ case E_TCmode: mode = TFmode; break;
+ default: break;
+ }
+#endif
+ rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
+ if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
+ {
+ gcc_assert (cum->fregno == FP_ARG_MAX_REG
+ && (mode == TFmode || mode == TDmode));
+ /* Long double or _Decimal128 split over regs and memory. */
+ mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
+ cum->use_stack=1;
+ }
+ rvec[(*k)++]
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->fregno++),
+ GEN_INT (bitpos / BITS_PER_UNIT));
+ if (FLOAT128_2REG_P (mode))
+ cum->fregno++;
+ }
+ else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, 1))
+ {
+ rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
+ rvec[(*k)++]
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->vregno++),
+ GEN_INT (bitpos / BITS_PER_UNIT));
+ }
+ else if (cum->intoffset == -1)
+ cum->intoffset = bitpos;
+ }
+}
+
+/* For the darwin64 ABI, we want to construct a PARALLEL consisting of
+ the register(s) to be used for each field and subfield of a struct
+ being passed by value, along with the offset of where the
+ register's value may be found in the block. FP fields go in FP
+ register, vector fields go in vector registers, and everything
+ else goes in int registers, packed as in memory.
+
+ This code is also used for function return values. RETVAL indicates
+ whether this is the case.
+
+ Much of this is taken from the SPARC V9 port, which has a similar
+ calling convention. */
+
+rtx
+rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
+ bool named, bool retval)
+{
+ rtx rvec[FIRST_PSEUDO_REGISTER];
+ int k = 1, kbase = 1;
+ HOST_WIDE_INT typesize = int_size_in_bytes (type);
+ /* This is a copy; modifications are not visible to our caller. */
+ CUMULATIVE_ARGS copy_cum = *orig_cum;
+ CUMULATIVE_ARGS *cum = &copy_cum;
+
+ /* Pad to 16 byte boundary if needed. */
+ if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
+ && (cum->words % 2) != 0)
+ cum->words++;
+
+ cum->intoffset = 0;
+ cum->use_stack = 0;
+ cum->named = named;
+
+ /* Put entries into rvec[] for individual FP and vector fields, and
+ for the chunks of memory that go in int regs. Note we start at
+ element 1; 0 is reserved for an indication of using memory, and
+ may or may not be filled in below. */
+ rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
+ rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
+
+ /* If any part of the struct went on the stack put all of it there.
+ This hack is because the generic code for
+ FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
+ parts of the struct are not at the beginning. */
+ if (cum->use_stack)
+ {
+ if (retval)
+ return NULL_RTX; /* doesn't go in registers at all */
+ kbase = 0;
+ rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
+ }
+ if (k > 1 || cum->use_stack)
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
+ else
+ return NULL_RTX;
+}
+
+/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
+
+static rtx
+rs6000_mixed_function_arg (machine_mode mode, const_tree type,
+ int align_words)
+{
+ int n_units;
+ int i, k;
+ rtx rvec[GP_ARG_NUM_REG + 1];
+
+ if (align_words >= GP_ARG_NUM_REG)
+ return NULL_RTX;
+
+ n_units = rs6000_arg_size (mode, type);
+
+ /* Optimize the simple case where the arg fits in one gpr, except in
+ the case of BLKmode due to assign_parms assuming that registers are
+ BITS_PER_WORD wide. */
+ if (n_units == 0
+ || (n_units == 1 && mode != BLKmode))
+ return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+
+ k = 0;
+ if (align_words + n_units > GP_ARG_NUM_REG)
+ /* Not all of the arg fits in gprs. Say that it goes in memory too,
+ using a magic NULL_RTX component.
+ This is not strictly correct. Only some of the arg belongs in
+ memory, not all of it. However, the normal scheme using
+ function_arg_partial_nregs can result in unusual subregs, eg.
+ (subreg:SI (reg:DF) 4), which are not handled well. The code to
+ store the whole arg to memory is often more efficient than code
+ to store pieces, and we know that space is available in the right
+ place for the whole arg. */
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
+
+ i = 0;
+ do
+ {
+ rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
+ rtx off = GEN_INT (i++ * 4);
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+ while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
+
+ return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
+}
+
+/* We have an argument of MODE and TYPE that goes into FPRs or VRs,
+ but must also be copied into the parameter save area starting at
+ offset ALIGN_WORDS. Fill in RVEC with the elements corresponding
+ to the GPRs and/or memory. Return the number of elements used. */
+
+static int
+rs6000_psave_function_arg (machine_mode mode, const_tree type,
+ int align_words, rtx *rvec)
+{
+ int k = 0;
+
+ if (align_words < GP_ARG_NUM_REG)
+ {
+ int n_words = rs6000_arg_size (mode, type);
+
+ if (align_words + n_words > GP_ARG_NUM_REG
+ || mode == BLKmode
+ || (TARGET_32BIT && TARGET_POWERPC64))
+ {
+ /* If this is partially on the stack, then we only
+ include the portion actually in registers here. */
+ machine_mode rmode = TARGET_32BIT ? SImode : DImode;
+ int i = 0;
+
+ if (align_words + n_words > GP_ARG_NUM_REG)
+ {
+ /* Not all of the arg fits in gprs. Say that it goes in memory
+ too, using a magic NULL_RTX component. Also see comment in
+ rs6000_mixed_function_arg for why the normal
+ function_arg_partial_nregs scheme doesn't work in this case. */
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
+ }
+
+ do
+ {
+ rtx r = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
+ rtx off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+ while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
+ }
+ else
+ {
+ /* The whole arg fits in gprs. */
+ rtx r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
+ }
+ }
+ else
+ {
+ /* It's entirely in memory. */
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
+ }
+
+ return k;
+}
+
+/* RVEC is a vector of K components of an argument of mode MODE.
+ Construct the final function_arg return value from it. */
+
+static rtx
+rs6000_finish_function_arg (machine_mode mode, rtx *rvec, int k)
+{
+ gcc_assert (k >= 1);
+
+ /* Avoid returning a PARALLEL in the trivial cases. */
+ if (k == 1)
+ {
+ if (XEXP (rvec[0], 0) == NULL_RTX)
+ return NULL_RTX;
+
+ if (GET_MODE (XEXP (rvec[0], 0)) == mode)
+ return XEXP (rvec[0], 0);
+ }
+
+ return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
+}
+
+/* Determine where to put an argument to a function.
+ Value is zero to push the argument on the stack,
+ or a hard register in which to store the argument.
+
+ MODE is the argument's machine mode.
+ TYPE is the data type of the argument (as a tree).
+ This is null for libcalls where that information may
+ not be available.
+ CUM is a variable of type CUMULATIVE_ARGS which gives info about
+ the preceding args and about the function being called. It is
+ not modified in this routine.
+ NAMED is nonzero if this argument is a named parameter
+ (otherwise it is an extra parameter matching an ellipsis).
+
+ On RS/6000 the first eight words of non-FP are normally in registers
+ and the rest are pushed. Under AIX, the first 13 FP args are in registers.
+ Under V.4, the first 8 FP args are in registers.
+
+ If this is floating-point and no prototype is specified, we use
+ both an FP and integer register (or possibly FP reg and stack). Library
+ functions (when CALL_LIBCALL is set) always have the proper types for args,
+ so we can pass the FP value just in one register. emit_library_function
+ doesn't support PARALLEL anyway.
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
+
+rtx
+rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
+ const_tree type, bool named)
+{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+ enum rs6000_abi abi = DEFAULT_ABI;
+ machine_mode elt_mode;
+ int n_elts;
+
+ /* Return a marker to indicate whether CR1 needs to set or clear the
+ bit that V.4 uses to say fp args were passed in registers.
+ Assume that we don't need the marker for software floating point,
+ or compiler generated library calls. */
+ if (mode == VOIDmode)
+ {
+ if (abi == ABI_V4
+ && (cum->call_cookie & CALL_LIBCALL) == 0
+ && (cum->stdarg
+ || (cum->nargs_prototype < 0
+ && (cum->prototype || TARGET_NO_PROTOTYPE)))
+ && TARGET_HARD_FLOAT)
+ return GEN_INT (cum->call_cookie
+ | ((cum->fregno == FP_ARG_MIN_REG)
+ ? CALL_V4_SET_FP_ARGS
+ : CALL_V4_CLEAR_FP_ARGS));
+
+ return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
+ }
+
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+
+ if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
+ {
+ rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
+ if (rslt != NULL_RTX)
+ return rslt;
+ /* Else fall through to usual handling. */
+ }
+
+ if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
+ {
+ rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1];
+ rtx r, off;
+ int i, k = 0;
+
+ /* Do we also need to pass this argument in the parameter save area?
+ Library support functions for IEEE 128-bit are assumed to not need the
+ value passed both in GPRs and in vector registers. */
+ if (TARGET_64BIT && !cum->prototype
+ && (!cum->libcall || !FLOAT128_VECTOR_P (elt_mode)))
+ {
+ int align_words = ROUND_UP (cum->words, 2);
+ k = rs6000_psave_function_arg (mode, type, align_words, rvec);
+ }
+
+ /* Describe where this argument goes in the vector registers. */
+ for (i = 0; i < n_elts && cum->vregno + i <= ALTIVEC_ARG_MAX_REG; i++)
+ {
+ r = gen_rtx_REG (elt_mode, cum->vregno + i);
+ off = GEN_INT (i * GET_MODE_SIZE (elt_mode));
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+
+ return rs6000_finish_function_arg (mode, rvec, k);
+ }
+ else if (TARGET_ALTIVEC_ABI
+ && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
+ || (type && TREE_CODE (type) == VECTOR_TYPE
+ && int_size_in_bytes (type) == 16)))
+ {
+ if (named || abi == ABI_V4)
+ return NULL_RTX;
+ else
+ {
+ /* Vector parameters to varargs functions under AIX or Darwin
+ get passed in memory and possibly also in GPRs. */
+ int align, align_words, n_words;
+ machine_mode part_mode;
+
+ /* Vector parameters must be 16-byte aligned. In 32-bit
+ mode this means we need to take into account the offset
+ to the parameter save area. In 64-bit mode, they just
+ have to start on an even word, since the parameter save
+ area is 16-byte aligned. */
+ if (TARGET_32BIT)
+ align = -(rs6000_parm_offset () + cum->words) & 3;
+ else
+ align = cum->words & 1;
+ align_words = cum->words + align;
+
+ /* Out of registers? Memory, then. */
+ if (align_words >= GP_ARG_NUM_REG)
+ return NULL_RTX;
+
+ if (TARGET_32BIT && TARGET_POWERPC64)
+ return rs6000_mixed_function_arg (mode, type, align_words);
+
+ /* The vector value goes in GPRs. Only the part of the
+ value in GPRs is reported here. */
+ part_mode = mode;
+ n_words = rs6000_arg_size (mode, type);
+ if (align_words + n_words > GP_ARG_NUM_REG)
+ /* Fortunately, there are only two possibilities, the value
+ is either wholly in GPRs or half in GPRs and half not. */
+ part_mode = DImode;
+
+ return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
+ }
+ }
+
+ else if (abi == ABI_V4)
+ {
+ if (abi_v4_pass_in_fpr (mode, named))
+ {
+ /* _Decimal128 must use an even/odd register pair. This assumes
+ that the register number is odd when fregno is odd. */
+ if (mode == TDmode && (cum->fregno % 2) == 1)
+ cum->fregno++;
+
+ if (cum->fregno + (FLOAT128_2REG_P (mode) ? 1 : 0)
+ <= FP_ARG_V4_MAX_REG)
+ return gen_rtx_REG (mode, cum->fregno);
+ else
+ return NULL_RTX;
+ }
+ else
+ {
+ int n_words = rs6000_arg_size (mode, type);
+ int gregno = cum->sysv_gregno;
+
+ /* Long long is put in (r3,r4), (r5,r6), (r7,r8) or (r9,r10).
+ As does any other 2 word item such as complex int due to a
+ historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
+
+ /* Multi-reg args are not split between registers and stack. */
+ if (gregno + n_words - 1 > GP_ARG_MAX_REG)
+ return NULL_RTX;
+
+ if (TARGET_32BIT && TARGET_POWERPC64)
+ return rs6000_mixed_function_arg (mode, type,
+ gregno - GP_ARG_MIN_REG);
+ return gen_rtx_REG (mode, gregno);
+ }
+ }
+ else
+ {
+ int align_words = rs6000_parm_start (mode, type, cum->words);
+
+ /* _Decimal128 must be passed in an even/odd float register pair.
+ This assumes that the register number is odd when fregno is odd. */
+ if (elt_mode == TDmode && (cum->fregno % 2) == 1)
+ cum->fregno++;
+
+ if (USE_FP_FOR_ARG_P (cum, elt_mode)
+ && !(TARGET_AIX && !TARGET_ELF
+ && type != NULL && AGGREGATE_TYPE_P (type)))
+ {
+ rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1];
+ rtx r, off;
+ int i, k = 0;
+ unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
+ int fpr_words;
+
+ /* Do we also need to pass this argument in the parameter
+ save area? */
+ if (type && (cum->nargs_prototype <= 0
+ || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && TARGET_XL_COMPAT
+ && align_words >= GP_ARG_NUM_REG)))
+ k = rs6000_psave_function_arg (mode, type, align_words, rvec);
+
+ /* Describe where this argument goes in the fprs. */
+ for (i = 0; i < n_elts
+ && cum->fregno + i * n_fpreg <= FP_ARG_MAX_REG; i++)
+ {
+ /* Check if the argument is split over registers and memory.
+ This can only ever happen for long double or _Decimal128;
+ complex types are handled via split_complex_arg. */
+ machine_mode fmode = elt_mode;
+ if (cum->fregno + (i + 1) * n_fpreg > FP_ARG_MAX_REG + 1)
+ {
+ gcc_assert (FLOAT128_2REG_P (fmode));
+ fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
+ }
+
+ r = gen_rtx_REG (fmode, cum->fregno + i * n_fpreg);
+ off = GEN_INT (i * GET_MODE_SIZE (elt_mode));
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+
+ /* If there were not enough FPRs to hold the argument, the rest
+ usually goes into memory. However, if the current position
+ is still within the register parameter area, a portion may
+ actually have to go into GPRs.
+
+ Note that it may happen that the portion of the argument
+ passed in the first "half" of the first GPR was already
+ passed in the last FPR as well.
+
+ For unnamed arguments, we already set up GPRs to cover the
+ whole argument in rs6000_psave_function_arg, so there is
+ nothing further to do at this point. */
+ fpr_words = (i * GET_MODE_SIZE (elt_mode)) / (TARGET_32BIT ? 4 : 8);
+ if (i < n_elts && align_words + fpr_words < GP_ARG_NUM_REG
+ && cum->nargs_prototype > 0)
+ {
+ static bool warned;
+
+ machine_mode rmode = TARGET_32BIT ? SImode : DImode;
+ int n_words = rs6000_arg_size (mode, type);
+
+ align_words += fpr_words;
+ n_words -= fpr_words;
+
+ do
+ {
+ r = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
+ off = GEN_INT (fpr_words++ * GET_MODE_SIZE (rmode));
+ rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
+ }
+ while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
+
+ if (!warned && warn_psabi)
+ {
+ warned = true;
+ inform (input_location,
+ "the ABI of passing homogeneous %<float%> aggregates"
+ " has changed in GCC 5");
+ }
+ }
+
+ return rs6000_finish_function_arg (mode, rvec, k);
+ }
+ else if (align_words < GP_ARG_NUM_REG)
+ {
+ if (TARGET_32BIT && TARGET_POWERPC64)
+ return rs6000_mixed_function_arg (mode, type, align_words);
+
+ return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ }
+ else
+ return NULL_RTX;
+ }
+}
+
+/* For an arg passed partly in registers and partly in memory, this is
+ the number of bytes passed in registers. For args passed entirely in
+ registers or entirely in memory, zero. When an arg is described by a
+ PARALLEL, perhaps using more than one register type, this function
+ returns the number of bytes used by the first element of the PARALLEL. */
+
+int
+rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
+ tree type, bool named)
+{
+ CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
+ bool passed_in_gprs = true;
+ int ret = 0;
+ int align_words;
+ machine_mode elt_mode;
+ int n_elts;
+
+ rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
+
+ if (DEFAULT_ABI == ABI_V4)
+ return 0;
+
+ if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
+ {
+ /* If we are passing this arg in the fixed parameter save area (gprs or
+ memory) as well as VRs, we do not use the partial bytes mechanism;
+ instead, rs6000_function_arg will return a PARALLEL including a memory
+ element as necessary. Library support functions for IEEE 128-bit are
+ assumed to not need the value passed both in GPRs and in vector
+ registers. */
+ if (TARGET_64BIT && !cum->prototype
+ && (!cum->libcall || !FLOAT128_VECTOR_P (elt_mode)))
+ return 0;
+
+ /* Otherwise, we pass in VRs only. Check for partial copies. */
+ passed_in_gprs = false;
+ if (cum->vregno + n_elts > ALTIVEC_ARG_MAX_REG + 1)
+ ret = (ALTIVEC_ARG_MAX_REG + 1 - cum->vregno) * 16;
+ }
+
+ /* In this complicated case we just disable the partial_nregs code. */
+ if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
+ return 0;
+
+ align_words = rs6000_parm_start (mode, type, cum->words);
+
+ if (USE_FP_FOR_ARG_P (cum, elt_mode)
+ && !(TARGET_AIX && !TARGET_ELF
+ && type != NULL && AGGREGATE_TYPE_P (type)))
+ {
+ unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
+
+ /* If we are passing this arg in the fixed parameter save area
+ (gprs or memory) as well as FPRs, we do not use the partial
+ bytes mechanism; instead, rs6000_function_arg will return a
+ PARALLEL including a memory element as necessary. */
+ if (type
+ && (cum->nargs_prototype <= 0
+ || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ && TARGET_XL_COMPAT
+ && align_words >= GP_ARG_NUM_REG)))
+ return 0;
+
+ /* Otherwise, we pass in FPRs only. Check for partial copies. */
+ passed_in_gprs = false;
+ if (cum->fregno + n_elts * n_fpreg > FP_ARG_MAX_REG + 1)
+ {
+ /* Compute number of bytes / words passed in FPRs. If there
+ is still space available in the register parameter area
+ *after* that amount, a part of the argument will be passed
+ in GPRs. In that case, the total amount passed in any
+ registers is equal to the amount that would have been passed
+ in GPRs if everything were passed there, so we fall back to
+ the GPR code below to compute the appropriate value. */
+ int fpr = ((FP_ARG_MAX_REG + 1 - cum->fregno)
+ * MIN (8, GET_MODE_SIZE (elt_mode)));
+ int fpr_words = fpr / (TARGET_32BIT ? 4 : 8);
+
+ if (align_words + fpr_words < GP_ARG_NUM_REG)
+ passed_in_gprs = true;
+ else
+ ret = fpr;
+ }
+ }
+
+ if (passed_in_gprs
+ && align_words < GP_ARG_NUM_REG
+ && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
+ ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
+
+ if (ret != 0 && TARGET_DEBUG_ARG)
+ fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
+
+ return ret;
+}
+
+/* A C expression that indicates when an argument must be passed by
+ reference. If nonzero for an argument, a copy of that argument is
+ made in memory and a pointer to the argument is passed instead of
+ the argument itself. The pointer is passed in whatever way is
+ appropriate for passing a pointer to that type.
+
+ Under V.4, aggregates and long double are passed by reference.
+
+ As an extension to all 32-bit ABIs, AltiVec vectors are passed by
+ reference unless the AltiVec vector extension ABI is in force.
+
+ As an extension to all ABIs, variable sized types are passed by
+ reference. */
+
+bool
+rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
+ machine_mode mode, const_tree type,
+ bool named ATTRIBUTE_UNUSED)
+{
+ if (!type)
+ return 0;
+
+ if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD
+ && FLOAT128_IEEE_P (TYPE_MODE (type)))
+ {
+ if (TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_pass_by_reference: V4 IEEE 128-bit\n");
+ return 1;
+ }
+
+ if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
+ {
+ if (TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
+ return 1;
+ }
+
+ if (int_size_in_bytes (type) < 0)
+ {
+ if (TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
+ return 1;
+ }
+
+ /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
+ modes only exist for GCC vector types if -maltivec. */
+ if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ {
+ if (TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
+ return 1;
+ }
+
+ /* Pass synthetic vectors in memory. */
+ if (TREE_CODE (type) == VECTOR_TYPE
+ && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
+ {
+ static bool warned_for_pass_big_vectors = false;
+ if (TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
+ if (!warned_for_pass_big_vectors)
+ {
+ warning (OPT_Wpsabi, "GCC vector passed by reference: "
+ "non-standard ABI extension with no compatibility "
+ "guarantee");
+ warned_for_pass_big_vectors = true;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Process parameter of type TYPE after ARGS_SO_FAR parameters were
+ already processes. Return true if the parameter must be passed
+ (fully or partially) on the stack. */
+
+static bool
+rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
+{
+ machine_mode mode;
+ int unsignedp;
+ rtx entry_parm;
+
+ /* Catch errors. */
+ if (type == NULL || type == error_mark_node)
+ return true;
+
+ /* Handle types with no storage requirement. */
+ if (TYPE_MODE (type) == VOIDmode)
+ return false;
+
+ /* Handle complex types. */
+ if (TREE_CODE (type) == COMPLEX_TYPE)
+ return (rs6000_parm_needs_stack (args_so_far, TREE_TYPE (type))
+ || rs6000_parm_needs_stack (args_so_far, TREE_TYPE (type)));
+
+ /* Handle transparent aggregates. */
+ if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
+ && TYPE_TRANSPARENT_AGGR (type))
+ type = TREE_TYPE (first_field (type));
+
+ /* See if this arg was passed by invisible reference. */
+ if (pass_by_reference (get_cumulative_args (args_so_far),
+ TYPE_MODE (type), type, true))
+ type = build_pointer_type (type);
+
+ /* Find mode as it is passed by the ABI. */
+ unsignedp = TYPE_UNSIGNED (type);
+ mode = promote_mode (type, TYPE_MODE (type), &unsignedp);
+
+ /* If we must pass in stack, we need a stack. */
+ if (rs6000_must_pass_in_stack (mode, type))
+ return true;
+
+ /* If there is no incoming register, we need a stack. */
+ entry_parm = rs6000_function_arg (args_so_far, mode, type, true);
+ if (entry_parm == NULL)
+ return true;
+
+ /* Likewise if we need to pass both in registers and on the stack. */
+ if (GET_CODE (entry_parm) == PARALLEL
+ && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
+ return true;
+
+ /* Also true if we're partially in registers and partially not. */
+ if (rs6000_arg_partial_bytes (args_so_far, mode, type, true) != 0)
+ return true;
+
+ /* Update info on where next arg arrives in registers. */
+ rs6000_function_arg_advance (args_so_far, mode, type, true);
+ return false;
+}
+
+/* Return true if FUN has no prototype, has a variable argument
+ list, or passes any parameter in memory. */
+
+static bool
+rs6000_function_parms_need_stack (tree fun, bool incoming)
+{
+ tree fntype, result;
+ CUMULATIVE_ARGS args_so_far_v;
+ cumulative_args_t args_so_far;
+
+ if (!fun)
+ /* Must be a libcall, all of which only use reg parms. */
+ return false;
+
+ fntype = fun;
+ if (!TYPE_P (fun))
+ fntype = TREE_TYPE (fun);
+
+ /* Varargs functions need the parameter save area. */
+ if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
+ return true;
+
+ INIT_CUMULATIVE_INCOMING_ARGS (args_so_far_v, fntype, NULL_RTX);
+ args_so_far = pack_cumulative_args (&args_so_far_v);
+
+ /* When incoming, we will have been passed the function decl.
+ It is necessary to use the decl to handle K&R style functions,
+ where TYPE_ARG_TYPES may not be available. */
+ if (incoming)
+ {
+ gcc_assert (DECL_P (fun));
+ result = DECL_RESULT (fun);
+ }
+ else
+ result = TREE_TYPE (fntype);
+
+ if (result && aggregate_value_p (result, fntype))
+ {
+ if (!TYPE_P (result))
+ result = TREE_TYPE (result);
+ result = build_pointer_type (result);
+ rs6000_parm_needs_stack (args_so_far, result);
+ }
+
+ if (incoming)
+ {
+ tree parm;
+
+ for (parm = DECL_ARGUMENTS (fun);
+ parm && parm != void_list_node;
+ parm = TREE_CHAIN (parm))
+ if (rs6000_parm_needs_stack (args_so_far, TREE_TYPE (parm)))
+ return true;
+ }
+ else
+ {
+ function_args_iterator args_iter;
+ tree arg_type;
+
+ FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
+ if (rs6000_parm_needs_stack (args_so_far, arg_type))
+ return true;
+ }
+
+ return false;
+}
+
+/* Return the size of the REG_PARM_STACK_SPACE are for FUN. This is
+ usually a constant depending on the ABI. However, in the ELFv2 ABI
+ the register parameter area is optional when calling a function that
+ has a prototype is scope, has no variable argument list, and passes
+ all parameters in registers. */
+
+int
+rs6000_reg_parm_stack_space (tree fun, bool incoming)
+{
+ int reg_parm_stack_space;
+
+ switch (DEFAULT_ABI)
+ {
+ default:
+ reg_parm_stack_space = 0;
+ break;
+
+ case ABI_AIX:
+ case ABI_DARWIN:
+ reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
+ break;
+
+ case ABI_ELFv2:
+ /* ??? Recomputing this every time is a bit expensive. Is there
+ a place to cache this information? */
+ if (rs6000_function_parms_need_stack (fun, incoming))
+ reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
+ else
+ reg_parm_stack_space = 0;
+ break;
+ }
+
+ return reg_parm_stack_space;
+}
+
+static void
+rs6000_move_block_from_reg (int regno, rtx x, int nregs)
+{
+ int i;
+ machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
+
+ if (nregs == 0)
+ return;
+
+ for (i = 0; i < nregs; i++)
+ {
+ rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
+ if (reload_completed)
+ {
+ if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
+ tem = NULL_RTX;
+ else
+ tem = simplify_gen_subreg (reg_mode, x, BLKmode,
+ i * GET_MODE_SIZE (reg_mode));
+ }
+ else
+ tem = replace_equiv_address (tem, XEXP (tem, 0));
+
+ gcc_assert (tem);
+
+ emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
+ }
+}
+
+/* Perform any needed actions needed for a function that is receiving a
+ variable number of arguments.
+
+ CUM is as above.
+
+ MODE and TYPE are the mode and type of the current parameter.
+
+ PRETEND_SIZE is a variable that should be set to the amount of stack
+ that must be pushed by the prolog to pretend that our caller pushed
+ it.
+
+ Normally, this macro will push all remaining incoming registers on the
+ stack and set PRETEND_SIZE to the length of the registers pushed. */
+
+void
+setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
+ tree type, int *pretend_size ATTRIBUTE_UNUSED,
+ int no_rtl)
+{
+ CUMULATIVE_ARGS next_cum;
+ int reg_size = TARGET_32BIT ? 4 : 8;
+ rtx save_area = NULL_RTX, mem;
+ int first_reg_offset;
+ alias_set_type set;
+
+ /* Skip the last named argument. */
+ next_cum = *get_cumulative_args (cum);
+ rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
+
+ if (DEFAULT_ABI == ABI_V4)
+ {
+ first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
+
+ if (! no_rtl)
+ {
+ int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
+ HOST_WIDE_INT offset = 0;
+
+ /* Try to optimize the size of the varargs save area.
+ The ABI requires that ap.reg_save_area is doubleword
+ aligned, but we don't need to allocate space for all
+ the bytes, only those to which we actually will save
+ anything. */
+ if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
+ gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
+ if (TARGET_HARD_FLOAT
+ && next_cum.fregno <= FP_ARG_V4_MAX_REG
+ && cfun->va_list_fpr_size)
+ {
+ if (gpr_reg_num)
+ fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
+ * UNITS_PER_FP_WORD;
+ if (cfun->va_list_fpr_size
+ < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
+ fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
+ else
+ fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
+ * UNITS_PER_FP_WORD;
+ }
+ if (gpr_reg_num)
+ {
+ offset = -((first_reg_offset * reg_size) & ~7);
+ if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
+ {
+ gpr_reg_num = cfun->va_list_gpr_size;
+ if (reg_size == 4 && (first_reg_offset & 1))
+ gpr_reg_num++;
+ }
+ gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
+ }
+ else if (fpr_size)
+ offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
+ * UNITS_PER_FP_WORD
+ - (int) (GP_ARG_NUM_REG * reg_size);
+
+ if (gpr_size + fpr_size)
+ {
+ rtx reg_save_area
+ = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
+ gcc_assert (MEM_P (reg_save_area));
+ reg_save_area = XEXP (reg_save_area, 0);
+ if (GET_CODE (reg_save_area) == PLUS)
+ {
+ gcc_assert (XEXP (reg_save_area, 0)
+ == virtual_stack_vars_rtx);
+ gcc_assert (CONST_INT_P (XEXP (reg_save_area, 1)));
+ offset += INTVAL (XEXP (reg_save_area, 1));
+ }
+ else
+ gcc_assert (reg_save_area == virtual_stack_vars_rtx);
+ }
+
+ cfun->machine->varargs_save_offset = offset;
+ save_area = plus_constant (Pmode, virtual_stack_vars_rtx, offset);
+ }
+ }
+ else
+ {
+ first_reg_offset = next_cum.words;
+ save_area = crtl->args.internal_arg_pointer;
+
+ if (targetm.calls.must_pass_in_stack (mode, type))
+ first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
+ }
+
+ set = get_varargs_alias_set ();
+ if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
+ && cfun->va_list_gpr_size)
+ {
+ int n_gpr, nregs = GP_ARG_NUM_REG - first_reg_offset;
+
+ if (va_list_gpr_counter_field)
+ /* V4 va_list_gpr_size counts number of registers needed. */
+ n_gpr = cfun->va_list_gpr_size;
+ else
+ /* char * va_list instead counts number of bytes needed. */
+ n_gpr = (cfun->va_list_gpr_size + reg_size - 1) / reg_size;
+
+ if (nregs > n_gpr)
+ nregs = n_gpr;
+
+ mem = gen_rtx_MEM (BLKmode,
+ plus_constant (Pmode, save_area,
+ first_reg_offset * reg_size));
+ MEM_NOTRAP_P (mem) = 1;
+ set_mem_alias_set (mem, set);
+ set_mem_align (mem, BITS_PER_WORD);
+
+ rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
+ nregs);
+ }
+
+ /* Save FP registers if needed. */
+ if (DEFAULT_ABI == ABI_V4
+ && TARGET_HARD_FLOAT
+ && ! no_rtl
+ && next_cum.fregno <= FP_ARG_V4_MAX_REG
+ && cfun->va_list_fpr_size)
+ {
+ int fregno = next_cum.fregno, nregs;
+ rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
+ rtx lab = gen_label_rtx ();
+ int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
+ * UNITS_PER_FP_WORD);
+
+ emit_jump_insn
+ (gen_rtx_SET (pc_rtx,
+ gen_rtx_IF_THEN_ELSE (VOIDmode,
+ gen_rtx_NE (VOIDmode, cr1,
+ const0_rtx),
+ gen_rtx_LABEL_REF (VOIDmode, lab),
+ pc_rtx)));
+
+ for (nregs = 0;
+ fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
+ fregno++, off += UNITS_PER_FP_WORD, nregs++)
+ {
+ mem = gen_rtx_MEM (TARGET_HARD_FLOAT ? DFmode : SFmode,
+ plus_constant (Pmode, save_area, off));
+ MEM_NOTRAP_P (mem) = 1;
+ set_mem_alias_set (mem, set);
+ set_mem_align (mem, GET_MODE_ALIGNMENT (
+ TARGET_HARD_FLOAT ? DFmode : SFmode));
+ emit_move_insn (mem, gen_rtx_REG (
+ TARGET_HARD_FLOAT ? DFmode : SFmode, fregno));
+ }
+
+ emit_label (lab);
+ }
+}
+
+/* Create the va_list data type. */
+
+tree
+rs6000_build_builtin_va_list (void)
+{
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
+
+ /* For AIX, prefer 'char *' because that's what the system
+ header files like. */
+ if (DEFAULT_ABI != ABI_V4)
+ return build_pointer_type (char_type_node);
+
+ record = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
+ get_identifier ("__va_list_tag"), record);
+
+ f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
+ unsigned_char_type_node);
+ f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
+ unsigned_char_type_node);
+ /* Give the two bytes of padding a name, so that -Wpadded won't warn on
+ every user file. */
+ f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ get_identifier ("reserved"), short_unsigned_type_node);
+ f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ get_identifier ("overflow_arg_area"),
+ ptr_type_node);
+ f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
+ get_identifier ("reg_save_area"),
+ ptr_type_node);
+
+ va_list_gpr_counter_field = f_gpr;
+ va_list_fpr_counter_field = f_fpr;
+
+ DECL_FIELD_CONTEXT (f_gpr) = record;
+ DECL_FIELD_CONTEXT (f_fpr) = record;
+ DECL_FIELD_CONTEXT (f_res) = record;
+ DECL_FIELD_CONTEXT (f_ovf) = record;
+ DECL_FIELD_CONTEXT (f_sav) = record;
+
+ TYPE_STUB_DECL (record) = type_decl;
+ TYPE_NAME (record) = type_decl;
+ TYPE_FIELDS (record) = f_gpr;
+ DECL_CHAIN (f_gpr) = f_fpr;
+ DECL_CHAIN (f_fpr) = f_res;
+ DECL_CHAIN (f_res) = f_ovf;
+ DECL_CHAIN (f_ovf) = f_sav;
+
+ layout_type (record);
+
+ /* The correct type is an array type of one element. */
+ return build_array_type (record, build_index_type (size_zero_node));
+}
+
+/* Implement va_start. */
+
+void
+rs6000_va_start (tree valist, rtx nextarg)
+{
+ HOST_WIDE_INT words, n_gpr, n_fpr;
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
+ tree gpr, fpr, ovf, sav, t;
+
+ /* Only SVR4 needs something special. */
+ if (DEFAULT_ABI != ABI_V4)
+ {
+ std_expand_builtin_va_start (valist, nextarg);
+ return;
+ }
+
+ f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+ f_fpr = DECL_CHAIN (f_gpr);
+ f_res = DECL_CHAIN (f_fpr);
+ f_ovf = DECL_CHAIN (f_res);
+ f_sav = DECL_CHAIN (f_ovf);
+
+ valist = build_simple_mem_ref (valist);
+ gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
+ fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
+ f_fpr, NULL_TREE);
+ ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
+ f_ovf, NULL_TREE);
+ sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
+ f_sav, NULL_TREE);
+
+ /* Count number of gp and fp argument registers used. */
+ words = crtl->args.info.words;
+ n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
+ GP_ARG_NUM_REG);
+ n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
+ FP_ARG_NUM_REG);
+
+ if (TARGET_DEBUG_ARG)
+ fprintf (stderr, "va_start: words = " HOST_WIDE_INT_PRINT_DEC", n_gpr = "
+ HOST_WIDE_INT_PRINT_DEC", n_fpr = " HOST_WIDE_INT_PRINT_DEC"\n",
+ words, n_gpr, n_fpr);
+
+ if (cfun->va_list_gpr_size)
+ {
+ t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
+ build_int_cst (NULL_TREE, n_gpr));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+
+ if (cfun->va_list_fpr_size)
+ {
+ t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
+ build_int_cst (NULL_TREE, n_fpr));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+ if (call_ABI_of_interest (cfun->decl))
+ rs6000_passes_float = true;
+#endif
+ }
+
+ /* Find the overflow area. */
+ t = make_tree (TREE_TYPE (ovf), crtl->args.internal_arg_pointer);
+ if (words != 0)
+ t = fold_build_pointer_plus_hwi (t, words * MIN_UNITS_PER_WORD);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+ /* If there were no va_arg invocations, don't set up the register
+ save area. */
+ if (!cfun->va_list_gpr_size
+ && !cfun->va_list_fpr_size
+ && n_gpr < GP_ARG_NUM_REG
+ && n_fpr < FP_ARG_V4_MAX_REG)
+ return;
+
+ /* Find the register save area. */
+ t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
+ if (cfun->machine->varargs_save_offset)
+ t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+}
+
+/* Implement va_arg. */
+
+tree
+rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p)
+{
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
+ tree gpr, fpr, ovf, sav, reg, t, u;
+ int size, rsize, n_reg, sav_ofs, sav_scale;
+ tree lab_false, lab_over, addr;
+ int align;
+ tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
+ int regalign = 0;
+ gimple *stmt;
+
+ if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
+ {
+ t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
+ return build_va_arg_indirect_ref (t);
+ }
+
+ /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
+ earlier version of gcc, with the property that it always applied alignment
+ adjustments to the va-args (even for zero-sized types). The cheapest way
+ to deal with this is to replicate the effect of the part of
+ std_gimplify_va_arg_expr that carries out the align adjust, for the case
+ of relevance.
+ We don't need to check for pass-by-reference because of the test above.
+ We can return a simplifed answer, since we know there's no offset to add. */
+
+ if (((TARGET_MACHO
+ && rs6000_darwin64_abi)
+ || DEFAULT_ABI == ABI_ELFv2
+ || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
+ && integer_zerop (TYPE_SIZE (type)))
+ {
+ unsigned HOST_WIDE_INT align, boundary;
+ tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
+ align = PARM_BOUNDARY / BITS_PER_UNIT;
+ boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
+ if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
+ boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
+ boundary /= BITS_PER_UNIT;
+ if (boundary > align)
+ {
+ tree t ;
+ /* This updates arg ptr by the amount that would be necessary
+ to align the zero-sized (but not zero-alignment) item. */
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+ fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
+ gimplify_and_add (t, pre_p);
+
+ t = fold_convert (sizetype, valist_tmp);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+ fold_convert (TREE_TYPE (valist),
+ fold_build2 (BIT_AND_EXPR, sizetype, t,
+ size_int (-boundary))));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
+ gimplify_and_add (t, pre_p);
+ }
+ /* Since it is zero-sized there's no increment for the item itself. */
+ valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
+ return build_va_arg_indirect_ref (valist_tmp);
+ }
+
+ if (DEFAULT_ABI != ABI_V4)
+ {
+ if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ tree elem_type = TREE_TYPE (type);
+ machine_mode elem_mode = TYPE_MODE (elem_type);
+ int elem_size = GET_MODE_SIZE (elem_mode);
+
+ if (elem_size < UNITS_PER_WORD)
+ {
+ tree real_part, imag_part;
+ gimple_seq post = NULL;
+
+ real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
+ &post);
+ /* Copy the value into a temporary, lest the formal temporary
+ be reused out from under us. */
+ real_part = get_initialized_tmp_var (real_part, pre_p, &post);
+ gimple_seq_add_seq (pre_p, post);
+
+ imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
+ post_p);
+
+ return build2 (COMPLEX_EXPR, type, real_part, imag_part);
+ }
+ }
+
+ return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
+ }
+
+ f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
+ f_fpr = DECL_CHAIN (f_gpr);
+ f_res = DECL_CHAIN (f_fpr);
+ f_ovf = DECL_CHAIN (f_res);
+ f_sav = DECL_CHAIN (f_ovf);
+
+ gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
+ fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
+ f_fpr, NULL_TREE);
+ ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
+ f_ovf, NULL_TREE);
+ sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
+ f_sav, NULL_TREE);
+
+ size = int_size_in_bytes (type);
+ rsize = (size + 3) / 4;
+ int pad = 4 * rsize - size;
+ align = 1;
+
+ machine_mode mode = TYPE_MODE (type);
+ if (abi_v4_pass_in_fpr (mode, false))
+ {
+ /* FP args go in FP registers, if present. */
+ reg = fpr;
+ n_reg = (size + 7) / 8;
+ sav_ofs = (TARGET_HARD_FLOAT ? 8 : 4) * 4;
+ sav_scale = (TARGET_HARD_FLOAT ? 8 : 4);
+ if (mode != SFmode && mode != SDmode)
+ align = 8;
+ }
+ else
+ {
+ /* Otherwise into GP registers. */
+ reg = gpr;
+ n_reg = rsize;
+ sav_ofs = 0;
+ sav_scale = 4;
+ if (n_reg == 2)
+ align = 8;
+ }
+
+ /* Pull the value out of the saved registers.... */
+
+ lab_over = NULL;
+ addr = create_tmp_var (ptr_type_node, "addr");
+
+ /* AltiVec vectors never go in registers when -mabi=altivec. */
+ if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ align = 16;
+ else
+ {
+ lab_false = create_artificial_label (input_location);
+ lab_over = create_artificial_label (input_location);
+
+ /* Long long is aligned in the registers. As are any other 2 gpr
+ item such as complex int due to a historical mistake. */
+ u = reg;
+ if (n_reg == 2 && reg == gpr)
+ {
+ regalign = 1;
+ u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
+ build_int_cst (TREE_TYPE (reg), n_reg - 1));
+ u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
+ unshare_expr (reg), u);
+ }
+ /* _Decimal128 is passed in even/odd fpr pairs; the stored
+ reg number is 0 for f1, so we want to make it odd. */
+ else if (reg == fpr && mode == TDmode)
+ {
+ t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
+ build_int_cst (TREE_TYPE (reg), 1));
+ u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
+ }
+
+ t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
+ t = build2 (GE_EXPR, boolean_type_node, u, t);
+ u = build1 (GOTO_EXPR, void_type_node, lab_false);
+ t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
+ gimplify_and_add (t, pre_p);
+
+ t = sav;
+ if (sav_ofs)
+ t = fold_build_pointer_plus_hwi (sav, sav_ofs);
+
+ u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
+ build_int_cst (TREE_TYPE (reg), n_reg));
+ u = fold_convert (sizetype, u);
+ u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
+ t = fold_build_pointer_plus (t, u);
+
+ /* _Decimal32 varargs are located in the second word of the 64-bit
+ FP register for 32-bit binaries. */
+ if (TARGET_32BIT && TARGET_HARD_FLOAT && mode == SDmode)
+ t = fold_build_pointer_plus_hwi (t, size);
+
+ /* Args are passed right-aligned. */
+ if (BYTES_BIG_ENDIAN)
+ t = fold_build_pointer_plus_hwi (t, pad);
+
+ gimplify_assign (addr, t, pre_p);
+
+ gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
+
+ stmt = gimple_build_label (lab_false);
+ gimple_seq_add_stmt (pre_p, stmt);
+
+ if ((n_reg == 2 && !regalign) || n_reg > 2)
+ {
+ /* Ensure that we don't find any more args in regs.
+ Alignment has taken care of for special cases. */
+ gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
+ }
+ }
+
+ /* ... otherwise out of the overflow area. */
+
+ /* Care for on-stack alignment if needed. */
+ t = ovf;
+ if (align != 1)
+ {
+ t = fold_build_pointer_plus_hwi (t, align - 1);
+ t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
+ build_int_cst (TREE_TYPE (t), -align));
+ }
+
+ /* Args are passed right-aligned. */
+ if (BYTES_BIG_ENDIAN)
+ t = fold_build_pointer_plus_hwi (t, pad);
+
+ gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
+
+ gimplify_assign (unshare_expr (addr), t, pre_p);
+
+ t = fold_build_pointer_plus_hwi (t, size);
+ gimplify_assign (unshare_expr (ovf), t, pre_p);
+
+ if (lab_over)
+ {
+ stmt = gimple_build_label (lab_over);
+ gimple_seq_add_stmt (pre_p, stmt);
+ }
+
+ if (STRICT_ALIGNMENT
+ && (TYPE_ALIGN (type)
+ > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
+ {
+ /* The value (of type complex double, for example) may not be
+ aligned in memory in the saved registers, so copy via a
+ temporary. (This is the same code as used for SPARC.) */
+ tree tmp = create_tmp_var (type, "va_arg_tmp");
+ tree dest_addr = build_fold_addr_expr (tmp);
+
+ tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
+ 3, dest_addr, addr, size_int (rsize * 4));
+ TREE_ADDRESSABLE (tmp) = 1;
+
+ gimplify_and_add (copy, pre_p);
+ addr = dest_addr;
+ }
+
+ addr = fold_convert (ptrtype, addr);
+ return build_va_arg_indirect_ref (addr);
+}
+
+/* Builtins. */
+
+static void
+def_builtin (const char *name, tree type, enum rs6000_builtins code)
+{
+ tree t;
+ unsigned classify = rs6000_builtin_info[(int)code].attr;
+ const char *attr_string = "";
+
+ gcc_assert (name != NULL);
+ gcc_assert (IN_RANGE ((int)code, 0, (int)RS6000_BUILTIN_COUNT));
+
+ if (rs6000_builtin_decls[(int)code])
+ fatal_error (input_location,
+ "internal error: builtin function %qs already processed",
+ name);
+
+ rs6000_builtin_decls[(int)code] = t =
+ add_builtin_function (name, type, (int)code, BUILT_IN_MD, NULL, NULL_TREE);
+
+ /* Set any special attributes. */
+ if ((classify & RS6000_BTC_CONST) != 0)
+ {
+ /* const function, function only depends on the inputs. */
+ TREE_READONLY (t) = 1;
+ TREE_NOTHROW (t) = 1;
+ attr_string = ", const";
+ }
+ else if ((classify & RS6000_BTC_PURE) != 0)
+ {
+ /* pure function, function can read global memory, but does not set any
+ external state. */
+ DECL_PURE_P (t) = 1;
+ TREE_NOTHROW (t) = 1;
+ attr_string = ", pure";
+ }
+ else if ((classify & RS6000_BTC_FP) != 0)
+ {
+ /* Function is a math function. If rounding mode is on, then treat the
+ function as not reading global memory, but it can have arbitrary side
+ effects. If it is off, then assume the function is a const function.
+ This mimics the ATTR_MATHFN_FPROUNDING attribute in
+ builtin-attribute.def that is used for the math functions. */
+ TREE_NOTHROW (t) = 1;
+ if (flag_rounding_math)
+ {
+ DECL_PURE_P (t) = 1;
+ DECL_IS_NOVOPS (t) = 1;
+ attr_string = ", fp, pure";
+ }
+ else
+ {
+ TREE_READONLY (t) = 1;
+ attr_string = ", fp, const";
+ }
+ }
+ else if ((classify & RS6000_BTC_ATTR_MASK) != 0)
+ gcc_unreachable ();
+
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, code = %4d, %s%s\n",
+ (int)code, name, attr_string);
+}
+
+/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_3arg[] =
+{
+#include "rs6000-builtin.def"
+};
+
+/* DST operations: void foo (void *, const int, const char). */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_dst[] =
+{
+#include "rs6000-builtin.def"
+};
+
+/* Simple binary operations: VECc = foo (VECa, VECb). */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_2arg[] =
+{
+#include "rs6000-builtin.def"
+};
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+/* AltiVec predicates. */
+
+static const struct builtin_description bdesc_altivec_preds[] =
+{
+#include "rs6000-builtin.def"
+};
+
+/* ABS* operations. */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_abs[] =
+{
+#include "rs6000-builtin.def"
+};
+
+/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
+ foo (VECa). */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_1arg[] =
+{
+#include "rs6000-builtin.def"
+};
+
+/* Simple no-argument operations: result = __builtin_darn_32 () */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_0arg[] =
+{
+#include "rs6000-builtin.def"
+};
+
+/* HTM builtins. */
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_htm[] =
+{
+#include "rs6000-builtin.def"
+};
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+
+/* Return true if a builtin function is overloaded. */
+bool
+rs6000_overloaded_builtin_p (enum rs6000_builtins fncode)
+{
+ return (rs6000_builtin_info[(int)fncode].attr & RS6000_BTC_OVERLOADED) != 0;
+}
+
+const char *
+rs6000_overloaded_builtin_name (enum rs6000_builtins fncode)
+{
+ return rs6000_builtin_info[(int)fncode].name;
+}
+
+/* Expand an expression EXP that calls a builtin without arguments. */
+static rtx
+rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target)
+{
+ rtx pat;
+ machine_mode tmode = insn_data[icode].operand[0].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ if (icode == CODE_FOR_rs6000_mffsl
+ && rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
+ {
+ error ("%<__builtin_mffsl%> not supported with %<-msoft-float%>");
+ return const0_rtx;
+ }
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ pat = GEN_FCN (icode) (target);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+}
+
+
+static rtx
+rs6000_expand_mtfsf_builtin (enum insn_code icode, tree exp)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ tree arg1 = CALL_EXPR_ARG (exp, 1);
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+ machine_mode mode0 = insn_data[icode].operand[0].mode;
+ machine_mode mode1 = insn_data[icode].operand[1].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return const0_rtx;
+
+ if (!CONST_INT_P (op0)
+ || INTVAL (op0) > 255
+ || INTVAL (op0) < 0)
+ {
+ error ("argument 1 must be an 8-bit field value");
+ return const0_rtx;
+ }
+
+ if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ pat = GEN_FCN (icode) (op0, op1);
+ if (!pat)
+ return const0_rtx;
+ emit_insn (pat);
+
+ return NULL_RTX;
+}
+
+static rtx
+rs6000_expand_mtfsb_builtin (enum insn_code icode, tree exp)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ rtx op0 = expand_normal (arg0);
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
+ {
+ error ("%<__builtin_mtfsb0%> and %<__builtin_mtfsb1%> not supported with "
+ "%<-msoft-float%>");
+ return const0_rtx;
+ }
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return const0_rtx;
+
+ /* Only allow bit numbers 0 to 31. */
+ if (!u5bit_cint_operand (op0, VOIDmode))
+ {
+ error ("Argument must be a constant between 0 and 31.");
+ return const0_rtx;
+ }
+
+ pat = GEN_FCN (icode) (op0);
+ if (!pat)
+ return const0_rtx;
+ emit_insn (pat);
+
+ return NULL_RTX;
+}
+
+static rtx
+rs6000_expand_set_fpscr_rn_builtin (enum insn_code icode, tree exp)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ rtx op0 = expand_normal (arg0);
+ machine_mode mode0 = insn_data[icode].operand[0].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
+ {
+ error ("%<__builtin_set_fpscr_rn%> not supported with %<-msoft-float%>");
+ return const0_rtx;
+ }
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return const0_rtx;
+
+ /* If the argument is a constant, check the range. Argument can only be a
+ 2-bit value. Unfortunately, can't check the range of the value at
+ compile time if the argument is a variable. The least significant two
+ bits of the argument, regardless of type, are used to set the rounding
+ mode. All other bits are ignored. */
+ if (CONST_INT_P (op0) && !const_0_to_3_operand(op0, VOIDmode))
+ {
+ error ("Argument must be a value between 0 and 3.");
+ return const0_rtx;
+ }
+
+ if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ pat = GEN_FCN (icode) (op0);
+ if (!pat)
+ return const0_rtx;
+ emit_insn (pat);
+
+ return NULL_RTX;
+}
+static rtx
+rs6000_expand_set_fpscr_drn_builtin (enum insn_code icode, tree exp)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ rtx op0 = expand_normal (arg0);
+ machine_mode mode0 = insn_data[icode].operand[0].mode;
+
+ if (TARGET_32BIT)
+ /* Builtin not supported in 32-bit mode. */
+ fatal_error (input_location,
+ "%<__builtin_set_fpscr_drn%> is not supported "
+ "in 32-bit mode");
+
+ if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
+ {
+ error ("%<__builtin_set_fpscr_drn%> not supported with %<-msoft-float%>");
+ return const0_rtx;
+ }
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return const0_rtx;
+
+ /* If the argument is a constant, check the range. Agrument can only be a
+ 3-bit value. Unfortunately, can't check the range of the value at
+ compile time if the argument is a variable. The least significant two
+ bits of the argument, regardless of type, are used to set the rounding
+ mode. All other bits are ignored. */
+ if (CONST_INT_P (op0) && !const_0_to_7_operand(op0, VOIDmode))
+ {
+ error ("Argument must be a value between 0 and 7.");
+ return const0_rtx;
+ }
+
+ if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ pat = GEN_FCN (icode) (op0);
+ if (! pat)
+ return const0_rtx;
+ emit_insn (pat);
+
+ return NULL_RTX;
+}
+
+static rtx
+rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ rtx op0 = expand_normal (arg0);
+ machine_mode tmode = insn_data[icode].operand[0].mode;
+ machine_mode mode0 = insn_data[icode].operand[1].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return const0_rtx;
+
+ if (icode == CODE_FOR_altivec_vspltisb
+ || icode == CODE_FOR_altivec_vspltish
+ || icode == CODE_FOR_altivec_vspltisw)
+ {
+ /* Only allow 5-bit *signed* literals. */
+ if (!CONST_INT_P (op0)
+ || INTVAL (op0) > 15
+ || INTVAL (op0) < -16)
+ {
+ error ("argument 1 must be a 5-bit signed literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ pat = GEN_FCN (icode) (target, op0);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+}
+
+static rtx
+altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
+{
+ rtx pat, scratch1, scratch2;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ rtx op0 = expand_normal (arg0);
+ machine_mode tmode = insn_data[icode].operand[0].mode;
+ machine_mode mode0 = insn_data[icode].operand[1].mode;
+
+ /* If we have invalid arguments, bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return const0_rtx;
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ scratch1 = gen_reg_rtx (mode0);
+ scratch2 = gen_reg_rtx (mode0);
+
+ pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+}
+
+static rtx
+rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ tree arg1 = CALL_EXPR_ARG (exp, 1);
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+ machine_mode tmode = insn_data[icode].operand[0].mode;
+ machine_mode mode0 = insn_data[icode].operand[1].mode;
+ machine_mode mode1 = insn_data[icode].operand[2].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return const0_rtx;
+
+ if (icode == CODE_FOR_unpackv1ti
+ || icode == CODE_FOR_unpackkf
+ || icode == CODE_FOR_unpacktf
+ || icode == CODE_FOR_unpackif
+ || icode == CODE_FOR_unpacktd)
+ {
+ /* Only allow 1-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 1))
+ {
+ error ("argument 2 must be a 1-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_altivec_vspltw)
+ {
+ /* Only allow 2-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) & ~3)
+ {
+ error ("argument 2 must be a 2-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_altivec_vsplth)
+ {
+ /* Only allow 3-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) & ~7)
+ {
+ error ("argument 2 must be a 3-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_altivec_vspltb)
+ {
+ /* Only allow 4-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) & ~15)
+ {
+ error ("argument 2 must be a 4-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_altivec_vcfux
+ || icode == CODE_FOR_altivec_vcfsx
+ || icode == CODE_FOR_altivec_vctsxs
+ || icode == CODE_FOR_altivec_vctuxs)
+ {
+ /* Only allow 5-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) & ~0x1f)
+ {
+ error ("argument 2 must be a 5-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_dfptstsfi_eq_dd
+ || icode == CODE_FOR_dfptstsfi_lt_dd
+ || icode == CODE_FOR_dfptstsfi_gt_dd
+ || icode == CODE_FOR_dfptstsfi_unordered_dd
+ || icode == CODE_FOR_dfptstsfi_eq_td
+ || icode == CODE_FOR_dfptstsfi_lt_td
+ || icode == CODE_FOR_dfptstsfi_gt_td
+ || icode == CODE_FOR_dfptstsfi_unordered_td)
+ {
+ /* Only allow 6-bit unsigned literals. */
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || !IN_RANGE (TREE_INT_CST_LOW (arg0), 0, 63))
+ {
+ error ("argument 1 must be a 6-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_xststdcqp_kf
+ || icode == CODE_FOR_xststdcqp_tf
+ || icode == CODE_FOR_xststdcdp
+ || icode == CODE_FOR_xststdcsp
+ || icode == CODE_FOR_xvtstdcdp
+ || icode == CODE_FOR_xvtstdcsp)
+ {
+ /* Only allow 7-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 127))
+ {
+ error ("argument 2 must be a 7-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ pat = GEN_FCN (icode) (target, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+}
+
+static rtx
+altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
+{
+ rtx pat, scratch;
+ tree cr6_form = CALL_EXPR_ARG (exp, 0);
+ tree arg0 = CALL_EXPR_ARG (exp, 1);
+ tree arg1 = CALL_EXPR_ARG (exp, 2);
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+ machine_mode tmode = SImode;
+ machine_mode mode0 = insn_data[icode].operand[1].mode;
+ machine_mode mode1 = insn_data[icode].operand[2].mode;
+ int cr6_form_int;
+
+ if (TREE_CODE (cr6_form) != INTEGER_CST)
+ {
+ error ("argument 1 of %qs must be a constant",
+ "__builtin_altivec_predicate");
+ return const0_rtx;
+ }
+ else
+ cr6_form_int = TREE_INT_CST_LOW (cr6_form);
+
+ gcc_assert (mode0 == mode1);
+
+ /* If we have invalid arguments, bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return const0_rtx;
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ /* Note that for many of the relevant operations (e.g. cmpne or
+ cmpeq) with float or double operands, it makes more sense for the
+ mode of the allocated scratch register to select a vector of
+ integer. But the choice to copy the mode of operand 0 was made
+ long ago and there are no plans to change it. */
+ scratch = gen_reg_rtx (mode0);
+
+ pat = GEN_FCN (icode) (scratch, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ /* The vec_any* and vec_all* predicates use the same opcodes for two
+ different operations, but the bits in CR6 will be different
+ depending on what information we want. So we have to play tricks
+ with CR6 to get the right bits out.
+
+ If you think this is disgusting, look at the specs for the
+ AltiVec predicates. */
+
+ switch (cr6_form_int)
+ {
+ case 0:
+ emit_insn (gen_cr6_test_for_zero (target));
+ break;
+ case 1:
+ emit_insn (gen_cr6_test_for_zero_reverse (target));
+ break;
+ case 2:
+ emit_insn (gen_cr6_test_for_lt (target));
+ break;
+ case 3:
+ emit_insn (gen_cr6_test_for_lt_reverse (target));
+ break;
+ default:
+ error ("argument 1 of %qs is out of range",
+ "__builtin_altivec_predicate");
+ break;
+ }
+
+ return target;
+}
+
+rtx
+swap_endian_selector_for_mode (machine_mode mode)
+{
+ unsigned int swap1[16] = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
+ unsigned int swap2[16] = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
+ unsigned int swap4[16] = {3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12};
+ unsigned int swap8[16] = {1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14};
+
+ unsigned int *swaparray, i;
+ rtx perm[16];
+
+ switch (mode)
+ {
+ case E_V1TImode:
+ swaparray = swap1;
+ break;
+ case E_V2DFmode:
+ case E_V2DImode:
+ swaparray = swap2;
+ break;
+ case E_V4SFmode:
+ case E_V4SImode:
+ swaparray = swap4;
+ break;
+ case E_V8HImode:
+ swaparray = swap8;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ for (i = 0; i < 16; ++i)
+ perm[i] = GEN_INT (swaparray[i]);
+
+ return force_reg (V16QImode, gen_rtx_CONST_VECTOR (V16QImode,
+ gen_rtvec_v (16, perm)));
+}
+
+static rtx
+altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
+{
+ rtx pat, addr;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ tree arg1 = CALL_EXPR_ARG (exp, 1);
+ machine_mode tmode = insn_data[icode].operand[0].mode;
+ machine_mode mode0 = Pmode;
+ machine_mode mode1 = Pmode;
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return const0_rtx;
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ /* For LVX, express the RTL accurately by ANDing the address with -16.
+ LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_lvx_v1ti
+ || icode == CODE_FOR_altivec_lvx_v2df
+ || icode == CODE_FOR_altivec_lvx_v2di
+ || icode == CODE_FOR_altivec_lvx_v4sf
+ || icode == CODE_FOR_altivec_lvx_v4si
+ || icode == CODE_FOR_altivec_lvx_v8hi
+ || icode == CODE_FOR_altivec_lvx_v16qi)
+ {
+ rtx rawaddr;
+ if (op0 == const0_rtx)
+ rawaddr = op1;
+ else
+ {
+ op0 = copy_to_mode_reg (mode0, op0);
+ rawaddr = gen_rtx_PLUS (Pmode, op1, op0);
+ }
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
+
+ emit_insn (gen_rtx_SET (target, addr));
+ }
+ else
+ {
+ if (op0 == const0_rtx)
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
+ else
+ {
+ op0 = copy_to_mode_reg (mode0, op0);
+ addr = gen_rtx_MEM (blk ? BLKmode : tmode,
+ gen_rtx_PLUS (Pmode, op1, op0));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ }
+
+ return target;
+}
+
+static rtx
+altivec_expand_stxvl_builtin (enum insn_code icode, tree exp)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ tree arg1 = CALL_EXPR_ARG (exp, 1);
+ tree arg2 = CALL_EXPR_ARG (exp, 2);
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+ rtx op2 = expand_normal (arg2);
+ machine_mode mode0 = insn_data[icode].operand[0].mode;
+ machine_mode mode1 = insn_data[icode].operand[1].mode;
+ machine_mode mode2 = insn_data[icode].operand[2].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return NULL_RTX;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node
+ || arg1 == error_mark_node
+ || arg2 == error_mark_node)
+ return NULL_RTX;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+ if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
+ op2 = copy_to_mode_reg (mode2, op2);
+
+ pat = GEN_FCN (icode) (op0, op1, op2);
+ if (pat)
+ emit_insn (pat);
+
+ return NULL_RTX;
+}
+
+static rtx
+altivec_expand_stv_builtin (enum insn_code icode, tree exp)
+{
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ tree arg1 = CALL_EXPR_ARG (exp, 1);
+ tree arg2 = CALL_EXPR_ARG (exp, 2);
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+ rtx op2 = expand_normal (arg2);
+ rtx pat, addr, rawaddr;
+ machine_mode tmode = insn_data[icode].operand[0].mode;
+ machine_mode smode = insn_data[icode].operand[1].mode;
+ machine_mode mode1 = Pmode;
+ machine_mode mode2 = Pmode;
+
+ /* Invalid arguments. Bail before doing anything stoopid! */
+ if (arg0 == error_mark_node
+ || arg1 == error_mark_node
+ || arg2 == error_mark_node)
+ return const0_rtx;
+
+ op2 = copy_to_mode_reg (mode2, op2);
+
+ /* For STVX, express the RTL accurately by ANDing the address with -16.
+ STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
+ so the raw address is fine. */
+ if (icode == CODE_FOR_altivec_stvx_v2df
+ || icode == CODE_FOR_altivec_stvx_v2di
+ || icode == CODE_FOR_altivec_stvx_v4sf
+ || icode == CODE_FOR_altivec_stvx_v4si
+ || icode == CODE_FOR_altivec_stvx_v8hi
+ || icode == CODE_FOR_altivec_stvx_v16qi)
+ {
+ if (op1 == const0_rtx)
+ rawaddr = op2;
+ else
+ {
+ op1 = copy_to_mode_reg (mode1, op1);
+ rawaddr = gen_rtx_PLUS (Pmode, op2, op1);
+ }
+
+ addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
+ addr = gen_rtx_MEM (tmode, addr);
+
+ op0 = copy_to_mode_reg (tmode, op0);
+
+ emit_insn (gen_rtx_SET (addr, op0));
+ }
+ else
+ {
+ if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
+ op0 = copy_to_mode_reg (smode, op0);
+
+ if (op1 == const0_rtx)
+ addr = gen_rtx_MEM (tmode, op2);
+ else
+ {
+ op1 = copy_to_mode_reg (mode1, op1);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op2, op1));
+ }
+
+ pat = GEN_FCN (icode) (addr, op0);
+ if (pat)
+ emit_insn (pat);
+ }
+
+ return NULL_RTX;
+}
+
+/* Return the appropriate SPR number associated with the given builtin. */
+static inline HOST_WIDE_INT
+htm_spr_num (enum rs6000_builtins code)
+{
+ if (code == HTM_BUILTIN_GET_TFHAR
+ || code == HTM_BUILTIN_SET_TFHAR)
+ return TFHAR_SPR;
+ else if (code == HTM_BUILTIN_GET_TFIAR
+ || code == HTM_BUILTIN_SET_TFIAR)
+ return TFIAR_SPR;
+ else if (code == HTM_BUILTIN_GET_TEXASR
+ || code == HTM_BUILTIN_SET_TEXASR)
+ return TEXASR_SPR;
+ gcc_assert (code == HTM_BUILTIN_GET_TEXASRU
+ || code == HTM_BUILTIN_SET_TEXASRU);
+ return TEXASRU_SPR;
+}
+
+/* Return the correct ICODE value depending on whether we are
+ setting or reading the HTM SPRs. */
+static inline enum insn_code
+rs6000_htm_spr_icode (bool nonvoid)
+{
+ if (nonvoid)
+ return (TARGET_POWERPC64) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si;
+ else
+ return (TARGET_POWERPC64) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si;
+}
+
+/* Expand the HTM builtin in EXP and store the result in TARGET.
+ Store true in *EXPANDEDP if we found a builtin to expand. */
+static rtx
+htm_expand_builtin (tree exp, rtx target, bool * expandedp)
+{
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ const struct builtin_description *d;
+ size_t i;
+
+ *expandedp = true;
+
+ if (!TARGET_POWERPC64
+ && (fcode == HTM_BUILTIN_TABORTDC
+ || fcode == HTM_BUILTIN_TABORTDCI))
+ {
+ size_t uns_fcode = (size_t)fcode;
+ const char *name = rs6000_builtin_info[uns_fcode].name;
+ error ("builtin %qs is only valid in 64-bit mode", name);
+ return const0_rtx;
+ }
+
+ /* Expand the HTM builtins. */
+ d = bdesc_htm;
+ for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
+ if (d->code == fcode)
+ {
+ rtx op[MAX_HTM_OPERANDS], pat;
+ int nopnds = 0;
+ tree arg;
+ call_expr_arg_iterator iter;
+ unsigned attr = rs6000_builtin_info[fcode].attr;
+ enum insn_code icode = d->icode;
+ const struct insn_operand_data *insn_op;
+ bool uses_spr = (attr & RS6000_BTC_SPR);
+ rtx cr = NULL_RTX;
+
+ if (uses_spr)
+ icode = rs6000_htm_spr_icode (nonvoid);
+ insn_op = &insn_data[icode].operand[0];
+
+ if (nonvoid)
+ {
+ machine_mode tmode = (uses_spr) ? insn_op->mode : E_SImode;
+ if (!target
+ || GET_MODE (target) != tmode
+ || (uses_spr && !(*insn_op->predicate) (target, tmode)))
+ target = gen_reg_rtx (tmode);
+ if (uses_spr)
+ op[nopnds++] = target;
+ }
+
+ FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+ {
+ if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS)
+ return const0_rtx;
+
+ insn_op = &insn_data[icode].operand[nopnds];
+
+ op[nopnds] = expand_normal (arg);
+
+ if (!(*insn_op->predicate) (op[nopnds], insn_op->mode))
+ {
+ if (!strcmp (insn_op->constraint, "n"))
+ {
+ int arg_num = (nonvoid) ? nopnds : nopnds + 1;
+ if (!CONST_INT_P (op[nopnds]))
+ error ("argument %d must be an unsigned literal", arg_num);
+ else
+ error ("argument %d is an unsigned literal that is "
+ "out of range", arg_num);
+ return const0_rtx;
+ }
+ op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]);
+ }
+
+ nopnds++;
+ }
+
+ /* Handle the builtins for extended mnemonics. These accept
+ no arguments, but map to builtins that take arguments. */
+ switch (fcode)
+ {
+ case HTM_BUILTIN_TENDALL: /* Alias for: tend. 1 */
+ case HTM_BUILTIN_TRESUME: /* Alias for: tsr. 1 */
+ op[nopnds++] = GEN_INT (1);
+ if (flag_checking)
+ attr |= RS6000_BTC_UNARY;
+ break;
+ case HTM_BUILTIN_TSUSPEND: /* Alias for: tsr. 0 */
+ op[nopnds++] = GEN_INT (0);
+ if (flag_checking)
+ attr |= RS6000_BTC_UNARY;
+ break;
+ default:
+ break;
+ }
+
+ /* If this builtin accesses SPRs, then pass in the appropriate
+ SPR number and SPR regno as the last two operands. */
+ if (uses_spr)
+ {
+ machine_mode mode = (TARGET_POWERPC64) ? DImode : SImode;
+ op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode));
+ }
+ /* If this builtin accesses a CR, then pass in a scratch
+ CR as the last operand. */
+ else if (attr & RS6000_BTC_CR)
+ { cr = gen_reg_rtx (CCmode);
+ op[nopnds++] = cr;
+ }
+
+ if (flag_checking)
+ {
+ int expected_nopnds = 0;
+ if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_UNARY)
+ expected_nopnds = 1;
+ else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_BINARY)
+ expected_nopnds = 2;
+ else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_TERNARY)
+ expected_nopnds = 3;
+ if (!(attr & RS6000_BTC_VOID))
+ expected_nopnds += 1;
+ if (uses_spr)
+ expected_nopnds += 1;
+
+ gcc_assert (nopnds == expected_nopnds
+ && nopnds <= MAX_HTM_OPERANDS);
+ }
+
+ switch (nopnds)
+ {
+ case 1:
+ pat = GEN_FCN (icode) (op[0]);
+ break;
+ case 2:
+ pat = GEN_FCN (icode) (op[0], op[1]);
+ break;
+ case 3:
+ pat = GEN_FCN (icode) (op[0], op[1], op[2]);
+ break;
+ case 4:
+ pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (!pat)
+ return NULL_RTX;
+ emit_insn (pat);
+
+ if (attr & RS6000_BTC_CR)
+ {
+ if (fcode == HTM_BUILTIN_TBEGIN)
+ {
+ /* Emit code to set TARGET to true or false depending on
+ whether the tbegin. instruction successfully or failed
+ to start a transaction. We do this by placing the 1's
+ complement of CR's EQ bit into TARGET. */
+ rtx scratch = gen_reg_rtx (SImode);
+ emit_insn (gen_rtx_SET (scratch,
+ gen_rtx_EQ (SImode, cr,
+ const0_rtx)));
+ emit_insn (gen_rtx_SET (target,
+ gen_rtx_XOR (SImode, scratch,
+ GEN_INT (1))));
+ }
+ else
+ {
+ /* Emit code to copy the 4-bit condition register field
+ CR into the least significant end of register TARGET. */
+ rtx scratch1 = gen_reg_rtx (SImode);
+ rtx scratch2 = gen_reg_rtx (SImode);
+ rtx subreg = simplify_gen_subreg (CCmode, scratch1, SImode, 0);
+ emit_insn (gen_movcc (subreg, cr));
+ emit_insn (gen_lshrsi3 (scratch2, scratch1, GEN_INT (28)));
+ emit_insn (gen_andsi3 (target, scratch2, GEN_INT (0xf)));
+ }
+ }
+
+ if (nonvoid)
+ return target;
+ return const0_rtx;
+ }
+
+ *expandedp = false;
+ return NULL_RTX;
+}
+
+/* Expand the CPU builtin in FCODE and store the result in TARGET. */
+
+static rtx
+cpu_expand_builtin (enum rs6000_builtins fcode, tree exp ATTRIBUTE_UNUSED,
+ rtx target)
+{
+ /* __builtin_cpu_init () is a nop, so expand to nothing. */
+ if (fcode == RS6000_BUILTIN_CPU_INIT)
+ return const0_rtx;
+
+ if (target == 0 || GET_MODE (target) != SImode)
+ target = gen_reg_rtx (SImode);
+
+#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
+ tree arg = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
+ /* Target clones creates an ARRAY_REF instead of STRING_CST, convert it back
+ to a STRING_CST. */
+ if (TREE_CODE (arg) == ARRAY_REF
+ && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST
+ && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST
+ && compare_tree_int (TREE_OPERAND (arg, 1), 0) == 0)
+ arg = TREE_OPERAND (arg, 0);
+
+ if (TREE_CODE (arg) != STRING_CST)
+ {
+ error ("builtin %qs only accepts a string argument",
+ rs6000_builtin_info[(size_t) fcode].name);
+ return const0_rtx;
+ }
+
+ if (fcode == RS6000_BUILTIN_CPU_IS)
+ {
+ const char *cpu = TREE_STRING_POINTER (arg);
+ rtx cpuid = NULL_RTX;
+ for (size_t i = 0; i < ARRAY_SIZE (cpu_is_info); i++)
+ if (strcmp (cpu, cpu_is_info[i].cpu) == 0)
+ {
+ /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM. */
+ cpuid = GEN_INT (cpu_is_info[i].cpuid + _DL_FIRST_PLATFORM);
+ break;
+ }
+ if (cpuid == NULL_RTX)
+ {
+ /* Invalid CPU argument. */
+ error ("cpu %qs is an invalid argument to builtin %qs",
+ cpu, rs6000_builtin_info[(size_t) fcode].name);
+ return const0_rtx;
+ }
+
+ rtx platform = gen_reg_rtx (SImode);
+ rtx tcbmem = gen_const_mem (SImode,
+ gen_rtx_PLUS (Pmode,
+ gen_rtx_REG (Pmode, TLS_REGNUM),
+ GEN_INT (TCB_PLATFORM_OFFSET)));
+ emit_move_insn (platform, tcbmem);
+ emit_insn (gen_eqsi3 (target, platform, cpuid));
+ }
+ else if (fcode == RS6000_BUILTIN_CPU_SUPPORTS)
+ {
+ const char *hwcap = TREE_STRING_POINTER (arg);
+ rtx mask = NULL_RTX;
+ int hwcap_offset;
+ for (size_t i = 0; i < ARRAY_SIZE (cpu_supports_info); i++)
+ if (strcmp (hwcap, cpu_supports_info[i].hwcap) == 0)
+ {
+ mask = GEN_INT (cpu_supports_info[i].mask);
+ hwcap_offset = TCB_HWCAP_OFFSET (cpu_supports_info[i].id);
+ break;
+ }
+ if (mask == NULL_RTX)
+ {
+ /* Invalid HWCAP argument. */
+ error ("%s %qs is an invalid argument to builtin %qs",
+ "hwcap", hwcap, rs6000_builtin_info[(size_t) fcode].name);
+ return const0_rtx;
+ }
+
+ rtx tcb_hwcap = gen_reg_rtx (SImode);
+ rtx tcbmem = gen_const_mem (SImode,
+ gen_rtx_PLUS (Pmode,
+ gen_rtx_REG (Pmode, TLS_REGNUM),
+ GEN_INT (hwcap_offset)));
+ emit_move_insn (tcb_hwcap, tcbmem);
+ rtx scratch1 = gen_reg_rtx (SImode);
+ emit_insn (gen_rtx_SET (scratch1, gen_rtx_AND (SImode, tcb_hwcap, mask)));
+ rtx scratch2 = gen_reg_rtx (SImode);
+ emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx));
+ emit_insn (gen_rtx_SET (target, gen_rtx_XOR (SImode, scratch2, const1_rtx)));
+ }
+ else
+ gcc_unreachable ();
+
+ /* Record that we have expanded a CPU builtin, so that we can later
+ emit a reference to the special symbol exported by LIBC to ensure we
+ do not link against an old LIBC that doesn't support this feature. */
+ cpu_builtin_p = true;
+
+#else
+ warning (0, "builtin %qs needs GLIBC (2.23 and newer) that exports hardware "
+ "capability bits", rs6000_builtin_info[(size_t) fcode].name);
+
+ /* For old LIBCs, always return FALSE. */
+ emit_move_insn (target, GEN_INT (0));
+#endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
+
+ return target;
+}
+
+static rtx
+rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
+{
+ rtx pat;
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ tree arg1 = CALL_EXPR_ARG (exp, 1);
+ tree arg2 = CALL_EXPR_ARG (exp, 2);
+ rtx op0 = expand_normal (arg0);
+ rtx op1 = expand_normal (arg1);
+ rtx op2 = expand_normal (arg2);
+ machine_mode tmode = insn_data[icode].operand[0].mode;
+ machine_mode mode0 = insn_data[icode].operand[1].mode;
+ machine_mode mode1 = insn_data[icode].operand[2].mode;
+ machine_mode mode2 = insn_data[icode].operand[3].mode;
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node
+ || arg1 == error_mark_node
+ || arg2 == error_mark_node)
+ return const0_rtx;
+
+ /* Check and prepare argument depending on the instruction code.
+
+ Note that a switch statement instead of the sequence of tests
+ would be incorrect as many of the CODE_FOR values could be
+ CODE_FOR_nothing and that would yield multiple alternatives
+ with identical values. We'd never reach here at runtime in
+ this case. */
+ if (icode == CODE_FOR_altivec_vsldoi_v4sf
+ || icode == CODE_FOR_altivec_vsldoi_v2df
+ || icode == CODE_FOR_altivec_vsldoi_v4si
+ || icode == CODE_FOR_altivec_vsldoi_v8hi
+ || icode == CODE_FOR_altivec_vsldoi_v16qi)
+ {
+ /* Only allow 4-bit unsigned literals. */
+ STRIP_NOPS (arg2);
+ if (TREE_CODE (arg2) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg2) & ~0xf)
+ {
+ error ("argument 3 must be a 4-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_vsx_xxpermdi_v2df
+ || icode == CODE_FOR_vsx_xxpermdi_v2di
+ || icode == CODE_FOR_vsx_xxpermdi_v2df_be
+ || icode == CODE_FOR_vsx_xxpermdi_v2di_be
+ || icode == CODE_FOR_vsx_xxpermdi_v1ti
+ || icode == CODE_FOR_vsx_xxpermdi_v4sf
+ || icode == CODE_FOR_vsx_xxpermdi_v4si
+ || icode == CODE_FOR_vsx_xxpermdi_v8hi
+ || icode == CODE_FOR_vsx_xxpermdi_v16qi
+ || icode == CODE_FOR_vsx_xxsldwi_v16qi
+ || icode == CODE_FOR_vsx_xxsldwi_v8hi
+ || icode == CODE_FOR_vsx_xxsldwi_v4si
+ || icode == CODE_FOR_vsx_xxsldwi_v4sf
+ || icode == CODE_FOR_vsx_xxsldwi_v2di
+ || icode == CODE_FOR_vsx_xxsldwi_v2df)
+ {
+ /* Only allow 2-bit unsigned literals. */
+ STRIP_NOPS (arg2);
+ if (TREE_CODE (arg2) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg2) & ~0x3)
+ {
+ error ("argument 3 must be a 2-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_vsx_set_v2df
+ || icode == CODE_FOR_vsx_set_v2di
+ || icode == CODE_FOR_bcdadd
+ || icode == CODE_FOR_bcdadd_lt
+ || icode == CODE_FOR_bcdadd_eq
+ || icode == CODE_FOR_bcdadd_gt
+ || icode == CODE_FOR_bcdsub
+ || icode == CODE_FOR_bcdsub_lt
+ || icode == CODE_FOR_bcdsub_eq
+ || icode == CODE_FOR_bcdsub_gt)
+ {
+ /* Only allow 1-bit unsigned literals. */
+ STRIP_NOPS (arg2);
+ if (TREE_CODE (arg2) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg2) & ~0x1)
+ {
+ error ("argument 3 must be a 1-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_dfp_ddedpd_dd
+ || icode == CODE_FOR_dfp_ddedpd_td)
+ {
+ /* Only allow 2-bit unsigned literals where the value is 0 or 2. */
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg2) & ~0x3)
+ {
+ error ("argument 1 must be 0 or 2");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_dfp_denbcd_dd
+ || icode == CODE_FOR_dfp_denbcd_td)
+ {
+ /* Only allow 1-bit unsigned literals. */
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg0) & ~0x1)
+ {
+ error ("argument 1 must be a 1-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_dfp_dscli_dd
+ || icode == CODE_FOR_dfp_dscli_td
+ || icode == CODE_FOR_dfp_dscri_dd
+ || icode == CODE_FOR_dfp_dscri_td)
+ {
+ /* Only allow 6-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) & ~0x3f)
+ {
+ error ("argument 2 must be a 6-bit unsigned literal");
+ return CONST0_RTX (tmode);
+ }
+ }
+ else if (icode == CODE_FOR_crypto_vshasigmaw
+ || icode == CODE_FOR_crypto_vshasigmad)
+ {
+ /* Check whether the 2nd and 3rd arguments are integer constants and in
+ range and prepare arguments. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST || wi::geu_p (wi::to_wide (arg1), 2))
+ {
+ error ("argument 2 must be 0 or 1");
+ return CONST0_RTX (tmode);
+ }
+
+ STRIP_NOPS (arg2);
+ if (TREE_CODE (arg2) != INTEGER_CST
+ || wi::geu_p (wi::to_wide (arg2), 16))
+ {
+ error ("argument 3 must be in the range [0, 15]");
+ return CONST0_RTX (tmode);
+ }
+ }
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+ if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
+ op2 = copy_to_mode_reg (mode2, op2);
+
+ pat = GEN_FCN (icode) (target, op0, op1, op2);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+}
+
+
+/* Expand the dst builtins. */
+static rtx
+altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+ bool *expandedp)
+{
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ tree arg0, arg1, arg2;
+ machine_mode mode0, mode1;
+ rtx pat, op0, op1, op2;
+ const struct builtin_description *d;
+ size_t i;
+
+ *expandedp = false;
+
+ /* Handle DST variants. */
+ d = bdesc_dst;
+ for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
+ if (d->code == fcode)
+ {
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ arg1 = CALL_EXPR_ARG (exp, 1);
+ arg2 = CALL_EXPR_ARG (exp, 2);
+ op0 = expand_normal (arg0);
+ op1 = expand_normal (arg1);
+ op2 = expand_normal (arg2);
+ mode0 = insn_data[d->icode].operand[0].mode;
+ mode1 = insn_data[d->icode].operand[1].mode;
+
+ /* Invalid arguments, bail out before generating bad rtl. */
+ if (arg0 == error_mark_node
+ || arg1 == error_mark_node
+ || arg2 == error_mark_node)
+ return const0_rtx;
+
+ *expandedp = true;
+ STRIP_NOPS (arg2);
+ if (TREE_CODE (arg2) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg2) & ~0x3)
+ {
+ error ("argument to %qs must be a 2-bit unsigned literal", d->name);
+ return const0_rtx;
+ }
+
+ if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (Pmode, op0);
+ if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ pat = GEN_FCN (d->icode) (op0, op1, op2);
+ if (pat != 0)
+ emit_insn (pat);
+
+ return NULL_RTX;
+ }
+
+ return NULL_RTX;
+}
+
+/* Expand vec_init builtin. */
+static rtx
+altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
+{
+ machine_mode tmode = TYPE_MODE (type);
+ machine_mode inner_mode = GET_MODE_INNER (tmode);
+ int i, n_elt = GET_MODE_NUNITS (tmode);
+
+ gcc_assert (VECTOR_MODE_P (tmode));
+ gcc_assert (n_elt == call_expr_nargs (exp));
+
+ if (!target || !register_operand (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ /* If we have a vector compromised of a single element, such as V1TImode, do
+ the initialization directly. */
+ if (n_elt == 1 && GET_MODE_SIZE (tmode) == GET_MODE_SIZE (inner_mode))
+ {
+ rtx x = expand_normal (CALL_EXPR_ARG (exp, 0));
+ emit_move_insn (target, gen_lowpart (tmode, x));
+ }
+ else
+ {
+ rtvec v = rtvec_alloc (n_elt);
+
+ for (i = 0; i < n_elt; ++i)
+ {
+ rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
+ RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
+ }
+
+ rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
+ }
+
+ return target;
+}
+
+/* Return the integer constant in ARG. Constrain it to be in the range
+ of the subparts of VEC_TYPE; issue an error if not. */
+
+static int
+get_element_number (tree vec_type, tree arg)
+{
+ unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
+
+ if (!tree_fits_uhwi_p (arg)
+ || (elt = tree_to_uhwi (arg), elt > max))
+ {
+ error ("selector must be an integer constant in the range [0, %wi]", max);
+ return 0;
+ }
+
+ return elt;
+}
+
+/* Expand vec_set builtin. */
+static rtx
+altivec_expand_vec_set_builtin (tree exp)
+{
+ machine_mode tmode, mode1;
+ tree arg0, arg1, arg2;
+ int elt;
+ rtx op0, op1;
+
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ arg1 = CALL_EXPR_ARG (exp, 1);
+ arg2 = CALL_EXPR_ARG (exp, 2);
+
+ tmode = TYPE_MODE (TREE_TYPE (arg0));
+ mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
+ gcc_assert (VECTOR_MODE_P (tmode));
+
+ op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
+ op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
+ elt = get_element_number (TREE_TYPE (arg0), arg2);
+
+ if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
+ op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
+
+ op0 = force_reg (tmode, op0);
+ op1 = force_reg (mode1, op1);
+
+ rs6000_expand_vector_set (op0, op1, elt);
+
+ return op0;
+}
+
+/* Expand vec_ext builtin. */
+static rtx
+altivec_expand_vec_ext_builtin (tree exp, rtx target)
+{
+ machine_mode tmode, mode0;
+ tree arg0, arg1;
+ rtx op0;
+ rtx op1;
+
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ arg1 = CALL_EXPR_ARG (exp, 1);
+
+ op0 = expand_normal (arg0);
+ op1 = expand_normal (arg1);
+
+ if (TREE_CODE (arg1) == INTEGER_CST)
+ {
+ unsigned HOST_WIDE_INT elt;
+ unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+ unsigned int truncated_selector;
+ /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0)
+ returns low-order bits of INTEGER_CST for modulo indexing. */
+ elt = TREE_INT_CST_LOW (arg1);
+ truncated_selector = elt % size;
+ op1 = GEN_INT (truncated_selector);
+ }
+
+ tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
+ mode0 = TYPE_MODE (TREE_TYPE (arg0));
+ gcc_assert (VECTOR_MODE_P (mode0));
+
+ op0 = force_reg (mode0, op0);
+
+ if (optimize || !target || !register_operand (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ rs6000_expand_vector_extract (target, op0, op1);
+
+ return target;
+}
+
+/* Expand the builtin in EXP and store the result in TARGET. Store
+ true in *EXPANDEDP if we found a builtin to expand. */
+static rtx
+altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
+{
+ const struct builtin_description *d;
+ size_t i;
+ enum insn_code icode;
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ tree arg0, arg1, arg2;
+ rtx op0, pat;
+ machine_mode tmode, mode0;
+ enum rs6000_builtins fcode
+ = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+
+ if (rs6000_overloaded_builtin_p (fcode))
+ {
+ *expandedp = true;
+ error ("unresolved overload for Altivec builtin %qF", fndecl);
+
+ /* Given it is invalid, just generate a normal call. */
+ return expand_call (exp, target, false);
+ }
+
+ target = altivec_expand_dst_builtin (exp, target, expandedp);
+ if (*expandedp)
+ return target;
+
+ *expandedp = true;
+
+ switch (fcode)
+ {
+ case ALTIVEC_BUILTIN_STVX_V2DF:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2df, exp);
+ case ALTIVEC_BUILTIN_STVX_V2DI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2di, exp);
+ case ALTIVEC_BUILTIN_STVX_V4SF:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4sf, exp);
+ case ALTIVEC_BUILTIN_STVX:
+ case ALTIVEC_BUILTIN_STVX_V4SI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
+ case ALTIVEC_BUILTIN_STVX_V8HI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v8hi, exp);
+ case ALTIVEC_BUILTIN_STVX_V16QI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v16qi, exp);
+ case ALTIVEC_BUILTIN_STVEBX:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
+ case ALTIVEC_BUILTIN_STVEHX:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
+ case ALTIVEC_BUILTIN_STVEWX:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
+ case ALTIVEC_BUILTIN_STVXL_V2DF:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v2df, exp);
+ case ALTIVEC_BUILTIN_STVXL_V2DI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v2di, exp);
+ case ALTIVEC_BUILTIN_STVXL_V4SF:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v4sf, exp);
+ case ALTIVEC_BUILTIN_STVXL:
+ case ALTIVEC_BUILTIN_STVXL_V4SI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v4si, exp);
+ case ALTIVEC_BUILTIN_STVXL_V8HI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v8hi, exp);
+ case ALTIVEC_BUILTIN_STVXL_V16QI:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v16qi, exp);
+
+ case ALTIVEC_BUILTIN_STVLX:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
+ case ALTIVEC_BUILTIN_STVLXL:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
+ case ALTIVEC_BUILTIN_STVRX:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
+ case ALTIVEC_BUILTIN_STVRXL:
+ return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
+
+ case P9V_BUILTIN_STXVL:
+ return altivec_expand_stxvl_builtin (CODE_FOR_stxvl, exp);
+
+ case P9V_BUILTIN_XST_LEN_R:
+ return altivec_expand_stxvl_builtin (CODE_FOR_xst_len_r, exp);
+
+ case VSX_BUILTIN_STXVD2X_V1TI:
+ return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v1ti, exp);
+ case VSX_BUILTIN_STXVD2X_V2DF:
+ return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
+ case VSX_BUILTIN_STXVD2X_V2DI:
+ return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
+ case VSX_BUILTIN_STXVW4X_V4SF:
+ return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
+ case VSX_BUILTIN_STXVW4X_V4SI:
+ return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
+ case VSX_BUILTIN_STXVW4X_V8HI:
+ return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
+ case VSX_BUILTIN_STXVW4X_V16QI:
+ return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
+
+ /* For the following on big endian, it's ok to use any appropriate
+ unaligned-supporting store, so use a generic expander. For
+ little-endian, the exact element-reversing instruction must
+ be used. */
+ case VSX_BUILTIN_ST_ELEMREV_V1TI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
+ : CODE_FOR_vsx_st_elemrev_v1ti);
+ return altivec_expand_stv_builtin (code, exp);
+ }
+ case VSX_BUILTIN_ST_ELEMREV_V2DF:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
+ : CODE_FOR_vsx_st_elemrev_v2df);
+ return altivec_expand_stv_builtin (code, exp);
+ }
+ case VSX_BUILTIN_ST_ELEMREV_V2DI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
+ : CODE_FOR_vsx_st_elemrev_v2di);
+ return altivec_expand_stv_builtin (code, exp);
+ }
+ case VSX_BUILTIN_ST_ELEMREV_V4SF:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
+ : CODE_FOR_vsx_st_elemrev_v4sf);
+ return altivec_expand_stv_builtin (code, exp);
+ }
+ case VSX_BUILTIN_ST_ELEMREV_V4SI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
+ : CODE_FOR_vsx_st_elemrev_v4si);
+ return altivec_expand_stv_builtin (code, exp);
+ }
+ case VSX_BUILTIN_ST_ELEMREV_V8HI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
+ : CODE_FOR_vsx_st_elemrev_v8hi);
+ return altivec_expand_stv_builtin (code, exp);
+ }
+ case VSX_BUILTIN_ST_ELEMREV_V16QI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
+ : CODE_FOR_vsx_st_elemrev_v16qi);
+ return altivec_expand_stv_builtin (code, exp);
+ }
+
+ case ALTIVEC_BUILTIN_MFVSCR:
+ icode = CODE_FOR_altivec_mfvscr;
+ tmode = insn_data[icode].operand[0].mode;
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ pat = GEN_FCN (icode) (target);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+
+ case ALTIVEC_BUILTIN_MTVSCR:
+ icode = CODE_FOR_altivec_mtvscr;
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ op0 = expand_normal (arg0);
+ mode0 = insn_data[icode].operand[0].mode;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return const0_rtx;
+
+ if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ pat = GEN_FCN (icode) (op0);
+ if (pat)
+ emit_insn (pat);
+ return NULL_RTX;
+
+ case ALTIVEC_BUILTIN_DSSALL:
+ emit_insn (gen_altivec_dssall ());
+ return NULL_RTX;
+
+ case ALTIVEC_BUILTIN_DSS:
+ icode = CODE_FOR_altivec_dss;
+ arg0 = CALL_EXPR_ARG (exp, 0);
+ STRIP_NOPS (arg0);
+ op0 = expand_normal (arg0);
+ mode0 = insn_data[icode].operand[0].mode;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node)
+ return const0_rtx;
+
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg0) & ~0x3)
+ {
+ error ("argument to %qs must be a 2-bit unsigned literal", "dss");
+ return const0_rtx;
+ }
+
+ if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+
+ emit_insn (gen_altivec_dss (op0));
+ return NULL_RTX;
+
+ case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
+ case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
+ case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
+ case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
+ case VSX_BUILTIN_VEC_INIT_V2DF:
+ case VSX_BUILTIN_VEC_INIT_V2DI:
+ case VSX_BUILTIN_VEC_INIT_V1TI:
+ return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
+
+ case ALTIVEC_BUILTIN_VEC_SET_V4SI:
+ case ALTIVEC_BUILTIN_VEC_SET_V8HI:
+ case ALTIVEC_BUILTIN_VEC_SET_V16QI:
+ case ALTIVEC_BUILTIN_VEC_SET_V4SF:
+ case VSX_BUILTIN_VEC_SET_V2DF:
+ case VSX_BUILTIN_VEC_SET_V2DI:
+ case VSX_BUILTIN_VEC_SET_V1TI:
+ return altivec_expand_vec_set_builtin (exp);
+
+ case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
+ case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
+ case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
+ case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
+ case VSX_BUILTIN_VEC_EXT_V2DF:
+ case VSX_BUILTIN_VEC_EXT_V2DI:
+ case VSX_BUILTIN_VEC_EXT_V1TI:
+ return altivec_expand_vec_ext_builtin (exp, target);
+
+ case P9V_BUILTIN_VEC_EXTRACT4B:
+ arg1 = CALL_EXPR_ARG (exp, 1);
+ STRIP_NOPS (arg1);
+
+ /* Generate a normal call if it is invalid. */
+ if (arg1 == error_mark_node)
+ return expand_call (exp, target, false);
+
+ if (TREE_CODE (arg1) != INTEGER_CST || TREE_INT_CST_LOW (arg1) > 12)
+ {
+ error ("second argument to %qs must be [0, 12]", "vec_vextract4b");
+ return expand_call (exp, target, false);
+ }
+ break;
+
+ case P9V_BUILTIN_VEC_INSERT4B:
+ arg2 = CALL_EXPR_ARG (exp, 2);
+ STRIP_NOPS (arg2);
+
+ /* Generate a normal call if it is invalid. */
+ if (arg2 == error_mark_node)
+ return expand_call (exp, target, false);
+
+ if (TREE_CODE (arg2) != INTEGER_CST || TREE_INT_CST_LOW (arg2) > 12)
+ {
+ error ("third argument to %qs must be [0, 12]", "vec_vinsert4b");
+ return expand_call (exp, target, false);
+ }
+ break;
+
+ default:
+ break;
+ /* Fall through. */
+ }
+
+ /* Expand abs* operations. */
+ d = bdesc_abs;
+ for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
+ if (d->code == fcode)
+ return altivec_expand_abs_builtin (d->icode, exp, target);
+
+ /* Expand the AltiVec predicates. */
+ d = bdesc_altivec_preds;
+ for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, d++)
+ if (d->code == fcode)
+ return altivec_expand_predicate_builtin (d->icode, exp, target);
+
+ /* LV* are funky. We initialized them differently. */
+ switch (fcode)
+ {
+ case ALTIVEC_BUILTIN_LVSL:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVSR:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVEBX:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVEHX:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVEWX:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVXL_V2DF:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v2df,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVXL_V2DI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v2di,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVXL_V4SF:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4sf,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVXL:
+ case ALTIVEC_BUILTIN_LVXL_V4SI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4si,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVXL_V8HI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v8hi,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVXL_V16QI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v16qi,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVX_V1TI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v1ti,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVX_V2DF:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2df,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVX_V2DI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2di,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVX_V4SF:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4sf,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVX:
+ case ALTIVEC_BUILTIN_LVX_V4SI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVX_V8HI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v8hi,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVX_V16QI:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v16qi,
+ exp, target, false);
+ case ALTIVEC_BUILTIN_LVLX:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
+ exp, target, true);
+ case ALTIVEC_BUILTIN_LVLXL:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
+ exp, target, true);
+ case ALTIVEC_BUILTIN_LVRX:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
+ exp, target, true);
+ case ALTIVEC_BUILTIN_LVRXL:
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
+ exp, target, true);
+ case VSX_BUILTIN_LXVD2X_V1TI:
+ return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v1ti,
+ exp, target, false);
+ case VSX_BUILTIN_LXVD2X_V2DF:
+ return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
+ exp, target, false);
+ case VSX_BUILTIN_LXVD2X_V2DI:
+ return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
+ exp, target, false);
+ case VSX_BUILTIN_LXVW4X_V4SF:
+ return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
+ exp, target, false);
+ case VSX_BUILTIN_LXVW4X_V4SI:
+ return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
+ exp, target, false);
+ case VSX_BUILTIN_LXVW4X_V8HI:
+ return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
+ exp, target, false);
+ case VSX_BUILTIN_LXVW4X_V16QI:
+ return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
+ exp, target, false);
+ /* For the following on big endian, it's ok to use any appropriate
+ unaligned-supporting load, so use a generic expander. For
+ little-endian, the exact element-reversing instruction must
+ be used. */
+ case VSX_BUILTIN_LD_ELEMREV_V2DF:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
+ : CODE_FOR_vsx_ld_elemrev_v2df);
+ return altivec_expand_lv_builtin (code, exp, target, false);
+ }
+ case VSX_BUILTIN_LD_ELEMREV_V1TI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
+ : CODE_FOR_vsx_ld_elemrev_v1ti);
+ return altivec_expand_lv_builtin (code, exp, target, false);
+ }
+ case VSX_BUILTIN_LD_ELEMREV_V2DI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
+ : CODE_FOR_vsx_ld_elemrev_v2di);
+ return altivec_expand_lv_builtin (code, exp, target, false);
+ }
+ case VSX_BUILTIN_LD_ELEMREV_V4SF:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
+ : CODE_FOR_vsx_ld_elemrev_v4sf);
+ return altivec_expand_lv_builtin (code, exp, target, false);
+ }
+ case VSX_BUILTIN_LD_ELEMREV_V4SI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
+ : CODE_FOR_vsx_ld_elemrev_v4si);
+ return altivec_expand_lv_builtin (code, exp, target, false);
+ }
+ case VSX_BUILTIN_LD_ELEMREV_V8HI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
+ : CODE_FOR_vsx_ld_elemrev_v8hi);
+ return altivec_expand_lv_builtin (code, exp, target, false);
+ }
+ case VSX_BUILTIN_LD_ELEMREV_V16QI:
+ {
+ enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
+ : CODE_FOR_vsx_ld_elemrev_v16qi);
+ return altivec_expand_lv_builtin (code, exp, target, false);
+ }
+ break;
+ default:
+ break;
+ /* Fall through. */
+ }
+
+ *expandedp = false;
+ return NULL_RTX;
+}
+
+/* Check whether a builtin function is supported in this target
+ configuration. */
+bool
+rs6000_builtin_is_supported_p (enum rs6000_builtins fncode)
+{
+ HOST_WIDE_INT fnmask = rs6000_builtin_info[fncode].mask;
+ if ((fnmask & rs6000_builtin_mask) != fnmask)
+ return false;
+ else
+ return true;
+}
+
+/* Raise an error message for a builtin function that is called without the
+ appropriate target options being set. */
+
+void
+rs6000_invalid_builtin (enum rs6000_builtins fncode)
+{
+ size_t uns_fncode = (size_t) fncode;
+ const char *name = rs6000_builtin_info[uns_fncode].name;
+ HOST_WIDE_INT fnmask = rs6000_builtin_info[uns_fncode].mask;
+
+ gcc_assert (name != NULL);
+ if ((fnmask & RS6000_BTM_CELL) != 0)
+ error ("%qs is only valid for the cell processor", name);
+ else if ((fnmask & RS6000_BTM_VSX) != 0)
+ error ("%qs requires the %qs option", name, "-mvsx");
+ else if ((fnmask & RS6000_BTM_HTM) != 0)
+ error ("%qs requires the %qs option", name, "-mhtm");
+ else if ((fnmask & RS6000_BTM_ALTIVEC) != 0)
+ error ("%qs requires the %qs option", name, "-maltivec");
+ else if ((fnmask & (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+ == (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+ error ("%qs requires the %qs and %qs options", name, "-mhard-dfp",
+ "-mpower8-vector");
+ else if ((fnmask & RS6000_BTM_DFP) != 0)
+ error ("%qs requires the %qs option", name, "-mhard-dfp");
+ else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
+ error ("%qs requires the %qs option", name, "-mpower8-vector");
+ else if ((fnmask & (RS6000_BTM_P9_VECTOR | RS6000_BTM_64BIT))
+ == (RS6000_BTM_P9_VECTOR | RS6000_BTM_64BIT))
+ error ("%qs requires the %qs and %qs options", name, "-mcpu=power9",
+ "-m64");
+ else if ((fnmask & RS6000_BTM_P9_VECTOR) != 0)
+ error ("%qs requires the %qs option", name, "-mcpu=power9");
+ else if ((fnmask & (RS6000_BTM_P9_MISC | RS6000_BTM_64BIT))
+ == (RS6000_BTM_P9_MISC | RS6000_BTM_64BIT))
+ error ("%qs requires the %qs and %qs options", name, "-mcpu=power9",
+ "-m64");
+ else if ((fnmask & RS6000_BTM_P9_MISC) == RS6000_BTM_P9_MISC)
+ error ("%qs requires the %qs option", name, "-mcpu=power9");
+ else if ((fnmask & RS6000_BTM_LDBL128) == RS6000_BTM_LDBL128)
+ {
+ if (!TARGET_HARD_FLOAT)
+ error ("%qs requires the %qs option", name, "-mhard-float");
+ else
+ error ("%qs requires the %qs option", name,
+ TARGET_IEEEQUAD ? "-mabi=ibmlongdouble" : "-mlong-double-128");
+ }
+ else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
+ error ("%qs requires the %qs option", name, "-mhard-float");
+ else if ((fnmask & RS6000_BTM_FLOAT128_HW) != 0)
+ error ("%qs requires ISA 3.0 IEEE 128-bit floating point", name);
+ else if ((fnmask & RS6000_BTM_FLOAT128) != 0)
+ error ("%qs requires the %qs option", name, "%<-mfloat128%>");
+ else if ((fnmask & (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64))
+ == (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64))
+ error ("%qs requires the %qs (or newer), and %qs or %qs options",
+ name, "-mcpu=power7", "-m64", "-mpowerpc64");
+ else
+ error ("%qs is not supported with the current options", name);
+}
+
+/* Target hook for early folding of built-ins, shamelessly stolen
+ from ia64.c. */
+
+tree
+rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
+ int n_args ATTRIBUTE_UNUSED,
+ tree *args ATTRIBUTE_UNUSED,
+ bool ignore ATTRIBUTE_UNUSED)
+{
+#ifdef SUBTARGET_FOLD_BUILTIN
+ return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
+#else
+ return NULL_TREE;
+#endif
+}
+
+/* Helper function to sort out which built-ins may be valid without having
+ a LHS. */
+static bool
+rs6000_builtin_valid_without_lhs (enum rs6000_builtins fn_code)
+{
+ switch (fn_code)
+ {
+ case ALTIVEC_BUILTIN_STVX_V16QI:
+ case ALTIVEC_BUILTIN_STVX_V8HI:
+ case ALTIVEC_BUILTIN_STVX_V4SI:
+ case ALTIVEC_BUILTIN_STVX_V4SF:
+ case ALTIVEC_BUILTIN_STVX_V2DI:
+ case ALTIVEC_BUILTIN_STVX_V2DF:
+ case VSX_BUILTIN_STXVW4X_V16QI:
+ case VSX_BUILTIN_STXVW4X_V8HI:
+ case VSX_BUILTIN_STXVW4X_V4SF:
+ case VSX_BUILTIN_STXVW4X_V4SI:
+ case VSX_BUILTIN_STXVD2X_V2DF:
+ case VSX_BUILTIN_STXVD2X_V2DI:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/* Helper function to handle the gimple folding of a vector compare
+ operation. This sets up true/false vectors, and uses the
+ VEC_COND_EXPR operation.
+ CODE indicates which comparison is to be made. (EQ, GT, ...).
+ TYPE indicates the type of the result. */
+static tree
+fold_build_vec_cmp (tree_code code, tree type,
+ tree arg0, tree arg1)
+{
+ tree cmp_type = build_same_sized_truth_vector_type (type);
+ tree zero_vec = build_zero_cst (type);
+ tree minus_one_vec = build_minus_one_cst (type);
+ tree cmp = fold_build2 (code, cmp_type, arg0, arg1);
+ return fold_build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
+}
+
+/* Helper function to handle the in-between steps for the
+ vector compare built-ins. */
+static void
+fold_compare_helper (gimple_stmt_iterator *gsi, tree_code code, gimple *stmt)
+{
+ tree arg0 = gimple_call_arg (stmt, 0);
+ tree arg1 = gimple_call_arg (stmt, 1);
+ tree lhs = gimple_call_lhs (stmt);
+ tree cmp = fold_build_vec_cmp (code, TREE_TYPE (lhs), arg0, arg1);
+ gimple *g = gimple_build_assign (lhs, cmp);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+}
+
+/* Helper function to map V2DF and V4SF types to their
+ integral equivalents (V2DI and V4SI). */
+tree map_to_integral_tree_type (tree input_tree_type)
+{
+ if (INTEGRAL_TYPE_P (TREE_TYPE (input_tree_type)))
+ return input_tree_type;
+ else
+ {
+ if (types_compatible_p (TREE_TYPE (input_tree_type),
+ TREE_TYPE (V2DF_type_node)))
+ return V2DI_type_node;
+ else if (types_compatible_p (TREE_TYPE (input_tree_type),
+ TREE_TYPE (V4SF_type_node)))
+ return V4SI_type_node;
+ else
+ gcc_unreachable ();
+ }
+}
+
+/* Helper function to handle the vector merge[hl] built-ins. The
+ implementation difference between h and l versions for this code are in
+ the values used when building of the permute vector for high word versus
+ low word merge. The variance is keyed off the use_high parameter. */
+static void
+fold_mergehl_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_high)
+{
+ tree arg0 = gimple_call_arg (stmt, 0);
+ tree arg1 = gimple_call_arg (stmt, 1);
+ tree lhs = gimple_call_lhs (stmt);
+ tree lhs_type = TREE_TYPE (lhs);
+ int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
+ int midpoint = n_elts / 2;
+ int offset = 0;
+
+ if (use_high == 1)
+ offset = midpoint;
+
+ /* The permute_type will match the lhs for integral types. For double and
+ float types, the permute type needs to map to the V2 or V4 type that
+ matches size. */
+ tree permute_type;
+ permute_type = map_to_integral_tree_type (lhs_type);
+ tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
+
+ for (int i = 0; i < midpoint; i++)
+ {
+ elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+ offset + i));
+ elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+ offset + n_elts + i));
+ }
+
+ tree permute = elts.build ();
+
+ gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+}
+
+/* Helper function to handle the vector merge[eo] built-ins. */
+static void
+fold_mergeeo_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_odd)
+{
+ tree arg0 = gimple_call_arg (stmt, 0);
+ tree arg1 = gimple_call_arg (stmt, 1);
+ tree lhs = gimple_call_lhs (stmt);
+ tree lhs_type = TREE_TYPE (lhs);
+ int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
+
+ /* The permute_type will match the lhs for integral types. For double and
+ float types, the permute type needs to map to the V2 or V4 type that
+ matches size. */
+ tree permute_type;
+ permute_type = map_to_integral_tree_type (lhs_type);
+
+ tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
+
+ /* Build the permute vector. */
+ for (int i = 0; i < n_elts / 2; i++)
+ {
+ elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+ 2*i + use_odd));
+ elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+ 2*i + use_odd + n_elts));
+ }
+
+ tree permute = elts.build ();
+
+ gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+}
+
+/* Fold a machine-dependent built-in in GIMPLE. (For folding into
+ a constant, use rs6000_fold_builtin.) */
+
+bool
+rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
+{
+ gimple *stmt = gsi_stmt (*gsi);
+ tree fndecl = gimple_call_fndecl (stmt);
+ gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
+ enum rs6000_builtins fn_code
+ = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ tree arg0, arg1, lhs, temp;
+ enum tree_code bcode;
+ gimple *g;
+
+ size_t uns_fncode = (size_t) fn_code;
+ enum insn_code icode = rs6000_builtin_info[uns_fncode].icode;
+ const char *fn_name1 = rs6000_builtin_info[uns_fncode].name;
+ const char *fn_name2 = (icode != CODE_FOR_nothing)
+ ? get_insn_name ((int) icode)
+ : "nothing";
+
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_gimple_fold_builtin %d %s %s\n",
+ fn_code, fn_name1, fn_name2);
+
+ if (!rs6000_fold_gimple)
+ return false;
+
+ /* Prevent gimple folding for code that does not have a LHS, unless it is
+ allowed per the rs6000_builtin_valid_without_lhs helper function. */
+ if (!gimple_call_lhs (stmt) && !rs6000_builtin_valid_without_lhs (fn_code))
+ return false;
+
+ /* Don't fold invalid builtins, let rs6000_expand_builtin diagnose it. */
+ HOST_WIDE_INT mask = rs6000_builtin_info[uns_fncode].mask;
+ bool func_valid_p = (rs6000_builtin_mask & mask) == mask;
+ if (!func_valid_p)
+ return false;
+
+ switch (fn_code)
+ {
+ /* Flavors of vec_add. We deliberately don't expand
+ P8V_BUILTIN_VADDUQM as it gets lowered from V1TImode to
+ TImode, resulting in much poorer code generation. */
+ case ALTIVEC_BUILTIN_VADDUBM:
+ case ALTIVEC_BUILTIN_VADDUHM:
+ case ALTIVEC_BUILTIN_VADDUWM:
+ case P8V_BUILTIN_VADDUDM:
+ case ALTIVEC_BUILTIN_VADDFP:
+ case VSX_BUILTIN_XVADDDP:
+ bcode = PLUS_EXPR;
+ do_binary:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
+ && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs))))
+ {
+ /* Ensure the binary operation is performed in a type
+ that wraps if it is integral type. */
+ gimple_seq stmts = NULL;
+ tree type = unsigned_type_for (TREE_TYPE (lhs));
+ tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ type, arg0);
+ tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ type, arg1);
+ tree res = gimple_build (&stmts, gimple_location (stmt), bcode,
+ type, uarg0, uarg1);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR,
+ build1 (VIEW_CONVERT_EXPR,
+ TREE_TYPE (lhs), res));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+ g = gimple_build_assign (lhs, bcode, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_sub. We deliberately don't expand
+ P8V_BUILTIN_VSUBUQM. */
+ case ALTIVEC_BUILTIN_VSUBUBM:
+ case ALTIVEC_BUILTIN_VSUBUHM:
+ case ALTIVEC_BUILTIN_VSUBUWM:
+ case P8V_BUILTIN_VSUBUDM:
+ case ALTIVEC_BUILTIN_VSUBFP:
+ case VSX_BUILTIN_XVSUBDP:
+ bcode = MINUS_EXPR;
+ goto do_binary;
+ case VSX_BUILTIN_XVMULSP:
+ case VSX_BUILTIN_XVMULDP:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, MULT_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Even element flavors of vec_mul (signed). */
+ case ALTIVEC_BUILTIN_VMULESB:
+ case ALTIVEC_BUILTIN_VMULESH:
+ case P8V_BUILTIN_VMULESW:
+ /* Even element flavors of vec_mul (unsigned). */
+ case ALTIVEC_BUILTIN_VMULEUB:
+ case ALTIVEC_BUILTIN_VMULEUH:
+ case P8V_BUILTIN_VMULEUW:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, VEC_WIDEN_MULT_EVEN_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Odd element flavors of vec_mul (signed). */
+ case ALTIVEC_BUILTIN_VMULOSB:
+ case ALTIVEC_BUILTIN_VMULOSH:
+ case P8V_BUILTIN_VMULOSW:
+ /* Odd element flavors of vec_mul (unsigned). */
+ case ALTIVEC_BUILTIN_VMULOUB:
+ case ALTIVEC_BUILTIN_VMULOUH:
+ case P8V_BUILTIN_VMULOUW:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, VEC_WIDEN_MULT_ODD_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_div (Integer). */
+ case VSX_BUILTIN_DIV_V2DI:
+ case VSX_BUILTIN_UDIV_V2DI:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, TRUNC_DIV_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_div (Float). */
+ case VSX_BUILTIN_XVDIVSP:
+ case VSX_BUILTIN_XVDIVDP:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, RDIV_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_and. */
+ case ALTIVEC_BUILTIN_VAND:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_andc. */
+ case ALTIVEC_BUILTIN_VANDC:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+ g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, temp);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_nand. */
+ case P8V_BUILTIN_VEC_NAND:
+ case P8V_BUILTIN_NAND_V16QI:
+ case P8V_BUILTIN_NAND_V8HI:
+ case P8V_BUILTIN_NAND_V4SI:
+ case P8V_BUILTIN_NAND_V4SF:
+ case P8V_BUILTIN_NAND_V2DF:
+ case P8V_BUILTIN_NAND_V2DI:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+ g = gimple_build_assign (temp, BIT_AND_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_or. */
+ case ALTIVEC_BUILTIN_VOR:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* flavors of vec_orc. */
+ case P8V_BUILTIN_ORC_V16QI:
+ case P8V_BUILTIN_ORC_V8HI:
+ case P8V_BUILTIN_ORC_V4SI:
+ case P8V_BUILTIN_ORC_V4SF:
+ case P8V_BUILTIN_ORC_V2DF:
+ case P8V_BUILTIN_ORC_V2DI:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+ g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, temp);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_xor. */
+ case ALTIVEC_BUILTIN_VXOR:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, BIT_XOR_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_nor. */
+ case ALTIVEC_BUILTIN_VNOR:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+ g = gimple_build_assign (temp, BIT_IOR_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* flavors of vec_abs. */
+ case ALTIVEC_BUILTIN_ABS_V16QI:
+ case ALTIVEC_BUILTIN_ABS_V8HI:
+ case ALTIVEC_BUILTIN_ABS_V4SI:
+ case ALTIVEC_BUILTIN_ABS_V4SF:
+ case P8V_BUILTIN_ABS_V2DI:
+ case VSX_BUILTIN_XVABSDP:
+ arg0 = gimple_call_arg (stmt, 0);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (arg0)))
+ && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (arg0))))
+ return false;
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, ABS_EXPR, arg0);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* flavors of vec_min. */
+ case VSX_BUILTIN_XVMINDP:
+ case P8V_BUILTIN_VMINSD:
+ case P8V_BUILTIN_VMINUD:
+ case ALTIVEC_BUILTIN_VMINSB:
+ case ALTIVEC_BUILTIN_VMINSH:
+ case ALTIVEC_BUILTIN_VMINSW:
+ case ALTIVEC_BUILTIN_VMINUB:
+ case ALTIVEC_BUILTIN_VMINUH:
+ case ALTIVEC_BUILTIN_VMINUW:
+ case ALTIVEC_BUILTIN_VMINFP:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, MIN_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* flavors of vec_max. */
+ case VSX_BUILTIN_XVMAXDP:
+ case P8V_BUILTIN_VMAXSD:
+ case P8V_BUILTIN_VMAXUD:
+ case ALTIVEC_BUILTIN_VMAXSB:
+ case ALTIVEC_BUILTIN_VMAXSH:
+ case ALTIVEC_BUILTIN_VMAXSW:
+ case ALTIVEC_BUILTIN_VMAXUB:
+ case ALTIVEC_BUILTIN_VMAXUH:
+ case ALTIVEC_BUILTIN_VMAXUW:
+ case ALTIVEC_BUILTIN_VMAXFP:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, MAX_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_eqv. */
+ case P8V_BUILTIN_EQV_V16QI:
+ case P8V_BUILTIN_EQV_V8HI:
+ case P8V_BUILTIN_EQV_V4SI:
+ case P8V_BUILTIN_EQV_V4SF:
+ case P8V_BUILTIN_EQV_V2DF:
+ case P8V_BUILTIN_EQV_V2DI:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
+ g = gimple_build_assign (temp, BIT_XOR_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vec_rotate_left. */
+ case ALTIVEC_BUILTIN_VRLB:
+ case ALTIVEC_BUILTIN_VRLH:
+ case ALTIVEC_BUILTIN_VRLW:
+ case P8V_BUILTIN_VRLD:
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ g = gimple_build_assign (lhs, LROTATE_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ /* Flavors of vector shift right algebraic.
+ vec_sra{b,h,w} -> vsra{b,h,w}. */
+ case ALTIVEC_BUILTIN_VSRAB:
+ case ALTIVEC_BUILTIN_VSRAH:
+ case ALTIVEC_BUILTIN_VSRAW:
+ case P8V_BUILTIN_VSRAD:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ tree arg1_type = TREE_TYPE (arg1);
+ tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+ tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+ location_t loc = gimple_location (stmt);
+ /* Force arg1 into the range valid matching the arg0 type. */
+ /* Build a vector consisting of the max valid bit-size values. */
+ int n_elts = VECTOR_CST_NELTS (arg1);
+ tree element_size = build_int_cst (unsigned_element_type,
+ 128 / n_elts);
+ tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
+ for (int i = 0; i < n_elts; i++)
+ elts.safe_push (element_size);
+ tree modulo_tree = elts.build ();
+ /* Modulo the provided shift value against that vector. */
+ gimple_seq stmts = NULL;
+ tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ unsigned_arg1_type, arg1);
+ tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+ unsigned_arg1_type, unsigned_arg1,
+ modulo_tree);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ /* And finally, do the shift. */
+ g = gimple_build_assign (lhs, RSHIFT_EXPR, arg0, new_arg1);
+ gimple_set_location (g, loc);
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+ /* Flavors of vector shift left.
+ builtin_altivec_vsl{b,h,w} -> vsl{b,h,w}. */
+ case ALTIVEC_BUILTIN_VSLB:
+ case ALTIVEC_BUILTIN_VSLH:
+ case ALTIVEC_BUILTIN_VSLW:
+ case P8V_BUILTIN_VSLD:
+ {
+ location_t loc;
+ gimple_seq stmts = NULL;
+ arg0 = gimple_call_arg (stmt, 0);
+ tree arg0_type = TREE_TYPE (arg0);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (arg0_type))
+ && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0_type)))
+ return false;
+ arg1 = gimple_call_arg (stmt, 1);
+ tree arg1_type = TREE_TYPE (arg1);
+ tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+ tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+ loc = gimple_location (stmt);
+ lhs = gimple_call_lhs (stmt);
+ /* Force arg1 into the range valid matching the arg0 type. */
+ /* Build a vector consisting of the max valid bit-size values. */
+ int n_elts = VECTOR_CST_NELTS (arg1);
+ int tree_size_in_bits = TREE_INT_CST_LOW (size_in_bytes (arg1_type))
+ * BITS_PER_UNIT;
+ tree element_size = build_int_cst (unsigned_element_type,
+ tree_size_in_bits / n_elts);
+ tree_vector_builder elts (unsigned_type_for (arg1_type), n_elts, 1);
+ for (int i = 0; i < n_elts; i++)
+ elts.safe_push (element_size);
+ tree modulo_tree = elts.build ();
+ /* Modulo the provided shift value against that vector. */
+ tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ unsigned_arg1_type, arg1);
+ tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+ unsigned_arg1_type, unsigned_arg1,
+ modulo_tree);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ /* And finally, do the shift. */
+ g = gimple_build_assign (lhs, LSHIFT_EXPR, arg0, new_arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+ /* Flavors of vector shift right. */
+ case ALTIVEC_BUILTIN_VSRB:
+ case ALTIVEC_BUILTIN_VSRH:
+ case ALTIVEC_BUILTIN_VSRW:
+ case P8V_BUILTIN_VSRD:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ tree arg1_type = TREE_TYPE (arg1);
+ tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
+ tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
+ location_t loc = gimple_location (stmt);
+ gimple_seq stmts = NULL;
+ /* Convert arg0 to unsigned. */
+ tree arg0_unsigned
+ = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ unsigned_type_for (TREE_TYPE (arg0)), arg0);
+ /* Force arg1 into the range valid matching the arg0 type. */
+ /* Build a vector consisting of the max valid bit-size values. */
+ int n_elts = VECTOR_CST_NELTS (arg1);
+ tree element_size = build_int_cst (unsigned_element_type,
+ 128 / n_elts);
+ tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
+ for (int i = 0; i < n_elts; i++)
+ elts.safe_push (element_size);
+ tree modulo_tree = elts.build ();
+ /* Modulo the provided shift value against that vector. */
+ tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ unsigned_arg1_type, arg1);
+ tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
+ unsigned_arg1_type, unsigned_arg1,
+ modulo_tree);
+ /* Do the shift. */
+ tree res
+ = gimple_build (&stmts, RSHIFT_EXPR,
+ TREE_TYPE (arg0_unsigned), arg0_unsigned, new_arg1);
+ /* Convert result back to the lhs type. */
+ res = gimple_build (&stmts, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), res);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ update_call_from_tree (gsi, res);
+ return true;
+ }
+ /* Vector loads. */
+ case ALTIVEC_BUILTIN_LVX_V16QI:
+ case ALTIVEC_BUILTIN_LVX_V8HI:
+ case ALTIVEC_BUILTIN_LVX_V4SI:
+ case ALTIVEC_BUILTIN_LVX_V4SF:
+ case ALTIVEC_BUILTIN_LVX_V2DI:
+ case ALTIVEC_BUILTIN_LVX_V2DF:
+ case ALTIVEC_BUILTIN_LVX_V1TI:
+ {
+ arg0 = gimple_call_arg (stmt, 0); // offset
+ arg1 = gimple_call_arg (stmt, 1); // address
+ lhs = gimple_call_lhs (stmt);
+ location_t loc = gimple_location (stmt);
+ /* Since arg1 may be cast to a different type, just use ptr_type_node
+ here instead of trying to enforce TBAA on pointer types. */
+ tree arg1_type = ptr_type_node;
+ tree lhs_type = TREE_TYPE (lhs);
+ /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
+ the tree using the value from arg0. The resulting type will match
+ the type of arg1. */
+ gimple_seq stmts = NULL;
+ tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
+ tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+ arg1_type, arg1, temp_offset);
+ /* Mask off any lower bits from the address. */
+ tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
+ arg1_type, temp_addr,
+ build_int_cst (arg1_type, -16));
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ if (!is_gimple_mem_ref_addr (aligned_addr))
+ {
+ tree t = make_ssa_name (TREE_TYPE (aligned_addr));
+ gimple *g = gimple_build_assign (t, aligned_addr);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ aligned_addr = t;
+ }
+ /* Use the build2 helper to set up the mem_ref. The MEM_REF could also
+ take an offset, but since we've already incorporated the offset
+ above, here we just pass in a zero. */
+ gimple *g
+ = gimple_build_assign (lhs, build2 (MEM_REF, lhs_type, aligned_addr,
+ build_int_cst (arg1_type, 0)));
+ gimple_set_location (g, loc);
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+ /* Vector stores. */
+ case ALTIVEC_BUILTIN_STVX_V16QI:
+ case ALTIVEC_BUILTIN_STVX_V8HI:
+ case ALTIVEC_BUILTIN_STVX_V4SI:
+ case ALTIVEC_BUILTIN_STVX_V4SF:
+ case ALTIVEC_BUILTIN_STVX_V2DI:
+ case ALTIVEC_BUILTIN_STVX_V2DF:
+ {
+ arg0 = gimple_call_arg (stmt, 0); /* Value to be stored. */
+ arg1 = gimple_call_arg (stmt, 1); /* Offset. */
+ tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address. */
+ location_t loc = gimple_location (stmt);
+ tree arg0_type = TREE_TYPE (arg0);
+ /* Use ptr_type_node (no TBAA) for the arg2_type.
+ FIXME: (Richard) "A proper fix would be to transition this type as
+ seen from the frontend to GIMPLE, for example in a similar way we
+ do for MEM_REFs by piggy-backing that on an extra argument, a
+ constant zero pointer of the alias pointer type to use (which would
+ also serve as a type indicator of the store itself). I'd use a
+ target specific internal function for this (not sure if we can have
+ those target specific, but I guess if it's folded away then that's
+ fine) and get away with the overload set." */
+ tree arg2_type = ptr_type_node;
+ /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
+ the tree using the value from arg0. The resulting type will match
+ the type of arg2. */
+ gimple_seq stmts = NULL;
+ tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
+ tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+ arg2_type, arg2, temp_offset);
+ /* Mask off any lower bits from the address. */
+ tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
+ arg2_type, temp_addr,
+ build_int_cst (arg2_type, -16));
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ if (!is_gimple_mem_ref_addr (aligned_addr))
+ {
+ tree t = make_ssa_name (TREE_TYPE (aligned_addr));
+ gimple *g = gimple_build_assign (t, aligned_addr);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ aligned_addr = t;
+ }
+ /* The desired gimple result should be similar to:
+ MEM[(__vector floatD.1407 *)_1] = vf1D.2697; */
+ gimple *g
+ = gimple_build_assign (build2 (MEM_REF, arg0_type, aligned_addr,
+ build_int_cst (arg2_type, 0)), arg0);
+ gimple_set_location (g, loc);
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ /* unaligned Vector loads. */
+ case VSX_BUILTIN_LXVW4X_V16QI:
+ case VSX_BUILTIN_LXVW4X_V8HI:
+ case VSX_BUILTIN_LXVW4X_V4SF:
+ case VSX_BUILTIN_LXVW4X_V4SI:
+ case VSX_BUILTIN_LXVD2X_V2DF:
+ case VSX_BUILTIN_LXVD2X_V2DI:
+ {
+ arg0 = gimple_call_arg (stmt, 0); // offset
+ arg1 = gimple_call_arg (stmt, 1); // address
+ lhs = gimple_call_lhs (stmt);
+ location_t loc = gimple_location (stmt);
+ /* Since arg1 may be cast to a different type, just use ptr_type_node
+ here instead of trying to enforce TBAA on pointer types. */
+ tree arg1_type = ptr_type_node;
+ tree lhs_type = TREE_TYPE (lhs);
+ /* In GIMPLE the type of the MEM_REF specifies the alignment. The
+ required alignment (power) is 4 bytes regardless of data type. */
+ tree align_ltype = build_aligned_type (lhs_type, 4);
+ /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
+ the tree using the value from arg0. The resulting type will match
+ the type of arg1. */
+ gimple_seq stmts = NULL;
+ tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
+ tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+ arg1_type, arg1, temp_offset);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ if (!is_gimple_mem_ref_addr (temp_addr))
+ {
+ tree t = make_ssa_name (TREE_TYPE (temp_addr));
+ gimple *g = gimple_build_assign (t, temp_addr);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ temp_addr = t;
+ }
+ /* Use the build2 helper to set up the mem_ref. The MEM_REF could also
+ take an offset, but since we've already incorporated the offset
+ above, here we just pass in a zero. */
+ gimple *g;
+ g = gimple_build_assign (lhs, build2 (MEM_REF, align_ltype, temp_addr,
+ build_int_cst (arg1_type, 0)));
+ gimple_set_location (g, loc);
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ /* unaligned Vector stores. */
+ case VSX_BUILTIN_STXVW4X_V16QI:
+ case VSX_BUILTIN_STXVW4X_V8HI:
+ case VSX_BUILTIN_STXVW4X_V4SF:
+ case VSX_BUILTIN_STXVW4X_V4SI:
+ case VSX_BUILTIN_STXVD2X_V2DF:
+ case VSX_BUILTIN_STXVD2X_V2DI:
+ {
+ arg0 = gimple_call_arg (stmt, 0); /* Value to be stored. */
+ arg1 = gimple_call_arg (stmt, 1); /* Offset. */
+ tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address. */
+ location_t loc = gimple_location (stmt);
+ tree arg0_type = TREE_TYPE (arg0);
+ /* Use ptr_type_node (no TBAA) for the arg2_type. */
+ tree arg2_type = ptr_type_node;
+ /* In GIMPLE the type of the MEM_REF specifies the alignment. The
+ required alignment (power) is 4 bytes regardless of data type. */
+ tree align_stype = build_aligned_type (arg0_type, 4);
+ /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
+ the tree using the value from arg1. */
+ gimple_seq stmts = NULL;
+ tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
+ tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
+ arg2_type, arg2, temp_offset);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ if (!is_gimple_mem_ref_addr (temp_addr))
+ {
+ tree t = make_ssa_name (TREE_TYPE (temp_addr));
+ gimple *g = gimple_build_assign (t, temp_addr);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ temp_addr = t;
+ }
+ gimple *g;
+ g = gimple_build_assign (build2 (MEM_REF, align_stype, temp_addr,
+ build_int_cst (arg2_type, 0)), arg0);
+ gimple_set_location (g, loc);
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ /* Vector Fused multiply-add (fma). */
+ case ALTIVEC_BUILTIN_VMADDFP:
+ case VSX_BUILTIN_XVMADDDP:
+ case ALTIVEC_BUILTIN_VMLADDUHM:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ tree arg2 = gimple_call_arg (stmt, 2);
+ lhs = gimple_call_lhs (stmt);
+ gcall *g = gimple_build_call_internal (IFN_FMA, 3, arg0, arg1, arg2);
+ gimple_call_set_lhs (g, lhs);
+ gimple_call_set_nothrow (g, true);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ /* Vector compares; EQ, NE, GE, GT, LE. */
+ case ALTIVEC_BUILTIN_VCMPEQUB:
+ case ALTIVEC_BUILTIN_VCMPEQUH:
+ case ALTIVEC_BUILTIN_VCMPEQUW:
+ case P8V_BUILTIN_VCMPEQUD:
+ fold_compare_helper (gsi, EQ_EXPR, stmt);
+ return true;
+
+ case P9V_BUILTIN_CMPNEB:
+ case P9V_BUILTIN_CMPNEH:
+ case P9V_BUILTIN_CMPNEW:
+ fold_compare_helper (gsi, NE_EXPR, stmt);
+ return true;
+
+ case VSX_BUILTIN_CMPGE_16QI:
+ case VSX_BUILTIN_CMPGE_U16QI:
+ case VSX_BUILTIN_CMPGE_8HI:
+ case VSX_BUILTIN_CMPGE_U8HI:
+ case VSX_BUILTIN_CMPGE_4SI:
+ case VSX_BUILTIN_CMPGE_U4SI:
+ case VSX_BUILTIN_CMPGE_2DI:
+ case VSX_BUILTIN_CMPGE_U2DI:
+ fold_compare_helper (gsi, GE_EXPR, stmt);
+ return true;
+
+ case ALTIVEC_BUILTIN_VCMPGTSB:
+ case ALTIVEC_BUILTIN_VCMPGTUB:
+ case ALTIVEC_BUILTIN_VCMPGTSH:
+ case ALTIVEC_BUILTIN_VCMPGTUH:
+ case ALTIVEC_BUILTIN_VCMPGTSW:
+ case ALTIVEC_BUILTIN_VCMPGTUW:
+ case P8V_BUILTIN_VCMPGTUD:
+ case P8V_BUILTIN_VCMPGTSD:
+ fold_compare_helper (gsi, GT_EXPR, stmt);
+ return true;
+
+ case VSX_BUILTIN_CMPLE_16QI:
+ case VSX_BUILTIN_CMPLE_U16QI:
+ case VSX_BUILTIN_CMPLE_8HI:
+ case VSX_BUILTIN_CMPLE_U8HI:
+ case VSX_BUILTIN_CMPLE_4SI:
+ case VSX_BUILTIN_CMPLE_U4SI:
+ case VSX_BUILTIN_CMPLE_2DI:
+ case VSX_BUILTIN_CMPLE_U2DI:
+ fold_compare_helper (gsi, LE_EXPR, stmt);
+ return true;
+
+ /* flavors of vec_splat_[us]{8,16,32}. */
+ case ALTIVEC_BUILTIN_VSPLTISB:
+ case ALTIVEC_BUILTIN_VSPLTISH:
+ case ALTIVEC_BUILTIN_VSPLTISW:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ lhs = gimple_call_lhs (stmt);
+
+ /* Only fold the vec_splat_*() if the lower bits of arg 0 is a
+ 5-bit signed constant in range -16 to +15. */
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15))
+ return false;
+ gimple_seq stmts = NULL;
+ location_t loc = gimple_location (stmt);
+ tree splat_value = gimple_convert (&stmts, loc,
+ TREE_TYPE (TREE_TYPE (lhs)), arg0);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ tree splat_tree = build_vector_from_val (TREE_TYPE (lhs), splat_value);
+ g = gimple_build_assign (lhs, splat_tree);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ /* Flavors of vec_splat. */
+ /* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...}; */
+ case ALTIVEC_BUILTIN_VSPLTB:
+ case ALTIVEC_BUILTIN_VSPLTH:
+ case ALTIVEC_BUILTIN_VSPLTW:
+ case VSX_BUILTIN_XXSPLTD_V2DI:
+ case VSX_BUILTIN_XXSPLTD_V2DF:
+ {
+ arg0 = gimple_call_arg (stmt, 0); /* input vector. */
+ arg1 = gimple_call_arg (stmt, 1); /* index into arg0. */
+ /* Only fold the vec_splat_*() if arg1 is both a constant value and
+ is a valid index into the arg0 vector. */
+ unsigned int n_elts = VECTOR_CST_NELTS (arg0);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) > (n_elts -1))
+ return false;
+ lhs = gimple_call_lhs (stmt);
+ tree lhs_type = TREE_TYPE (lhs);
+ tree arg0_type = TREE_TYPE (arg0);
+ tree splat;
+ if (TREE_CODE (arg0) == VECTOR_CST)
+ splat = VECTOR_CST_ELT (arg0, TREE_INT_CST_LOW (arg1));
+ else
+ {
+ /* Determine (in bits) the length and start location of the
+ splat value for a call to the tree_vec_extract helper. */
+ int splat_elem_size = TREE_INT_CST_LOW (size_in_bytes (arg0_type))
+ * BITS_PER_UNIT / n_elts;
+ int splat_start_bit = TREE_INT_CST_LOW (arg1) * splat_elem_size;
+ tree len = build_int_cst (bitsizetype, splat_elem_size);
+ tree start = build_int_cst (bitsizetype, splat_start_bit);
+ splat = tree_vec_extract (gsi, TREE_TYPE (lhs_type), arg0,
+ len, start);
+ }
+ /* And finally, build the new vector. */
+ tree splat_tree = build_vector_from_val (lhs_type, splat);
+ g = gimple_build_assign (lhs, splat_tree);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ /* vec_mergel (integrals). */
+ case ALTIVEC_BUILTIN_VMRGLH:
+ case ALTIVEC_BUILTIN_VMRGLW:
+ case VSX_BUILTIN_XXMRGLW_4SI:
+ case ALTIVEC_BUILTIN_VMRGLB:
+ case VSX_BUILTIN_VEC_MERGEL_V2DI:
+ case VSX_BUILTIN_XXMRGLW_4SF:
+ case VSX_BUILTIN_VEC_MERGEL_V2DF:
+ fold_mergehl_helper (gsi, stmt, 1);
+ return true;
+ /* vec_mergeh (integrals). */
+ case ALTIVEC_BUILTIN_VMRGHH:
+ case ALTIVEC_BUILTIN_VMRGHW:
+ case VSX_BUILTIN_XXMRGHW_4SI:
+ case ALTIVEC_BUILTIN_VMRGHB:
+ case VSX_BUILTIN_VEC_MERGEH_V2DI:
+ case VSX_BUILTIN_XXMRGHW_4SF:
+ case VSX_BUILTIN_VEC_MERGEH_V2DF:
+ fold_mergehl_helper (gsi, stmt, 0);
+ return true;
+
+ /* Flavors of vec_mergee. */
+ case P8V_BUILTIN_VMRGEW_V4SI:
+ case P8V_BUILTIN_VMRGEW_V2DI:
+ case P8V_BUILTIN_VMRGEW_V4SF:
+ case P8V_BUILTIN_VMRGEW_V2DF:
+ fold_mergeeo_helper (gsi, stmt, 0);
+ return true;
+ /* Flavors of vec_mergeo. */
+ case P8V_BUILTIN_VMRGOW_V4SI:
+ case P8V_BUILTIN_VMRGOW_V2DI:
+ case P8V_BUILTIN_VMRGOW_V4SF:
+ case P8V_BUILTIN_VMRGOW_V2DF:
+ fold_mergeeo_helper (gsi, stmt, 1);
+ return true;
+
+ /* d = vec_pack (a, b) */
+ case P8V_BUILTIN_VPKUDUM:
+ case ALTIVEC_BUILTIN_VPKUHUM:
+ case ALTIVEC_BUILTIN_VPKUWUM:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ lhs = gimple_call_lhs (stmt);
+ gimple *g = gimple_build_assign (lhs, VEC_PACK_TRUNC_EXPR, arg0, arg1);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ /* d = vec_unpackh (a) */
+ /* Note that the UNPACK_{HI,LO}_EXPR used in the gimple_build_assign call
+ in this code is sensitive to endian-ness, and needs to be inverted to
+ handle both LE and BE targets. */
+ case ALTIVEC_BUILTIN_VUPKHSB:
+ case ALTIVEC_BUILTIN_VUPKHSH:
+ case P8V_BUILTIN_VUPKHSW:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ lhs = gimple_call_lhs (stmt);
+ if (BYTES_BIG_ENDIAN)
+ g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
+ else
+ g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+ /* d = vec_unpackl (a) */
+ case ALTIVEC_BUILTIN_VUPKLSB:
+ case ALTIVEC_BUILTIN_VUPKLSH:
+ case P8V_BUILTIN_VUPKLSW:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ lhs = gimple_call_lhs (stmt);
+ if (BYTES_BIG_ENDIAN)
+ g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
+ else
+ g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
+ gimple_set_location (g, gimple_location (stmt));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+ /* There is no gimple type corresponding with pixel, so just return. */
+ case ALTIVEC_BUILTIN_VUPKHPX:
+ case ALTIVEC_BUILTIN_VUPKLPX:
+ return false;
+
+ /* vec_perm. */
+ case ALTIVEC_BUILTIN_VPERM_16QI:
+ case ALTIVEC_BUILTIN_VPERM_8HI:
+ case ALTIVEC_BUILTIN_VPERM_4SI:
+ case ALTIVEC_BUILTIN_VPERM_2DI:
+ case ALTIVEC_BUILTIN_VPERM_4SF:
+ case ALTIVEC_BUILTIN_VPERM_2DF:
+ {
+ arg0 = gimple_call_arg (stmt, 0);
+ arg1 = gimple_call_arg (stmt, 1);
+ tree permute = gimple_call_arg (stmt, 2);
+ lhs = gimple_call_lhs (stmt);
+ location_t loc = gimple_location (stmt);
+ gimple_seq stmts = NULL;
+ // convert arg0 and arg1 to match the type of the permute
+ // for the VEC_PERM_EXPR operation.
+ tree permute_type = (TREE_TYPE (permute));
+ tree arg0_ptype = gimple_convert (&stmts, loc, permute_type, arg0);
+ tree arg1_ptype = gimple_convert (&stmts, loc, permute_type, arg1);
+ tree lhs_ptype = gimple_build (&stmts, loc, VEC_PERM_EXPR,
+ permute_type, arg0_ptype, arg1_ptype,
+ permute);
+ // Convert the result back to the desired lhs type upon completion.
+ tree temp = gimple_convert (&stmts, loc, TREE_TYPE (lhs), lhs_ptype);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, temp);
+ gimple_set_location (g, loc);
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+
+ default:
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "gimple builtin intrinsic not matched:%d %s %s\n",
+ fn_code, fn_name1, fn_name2);
+ break;
+ }
+
+ return false;
+}
+
+/* Expand an expression EXP that calls a built-in function,
+ with result going to TARGET if that's convenient
+ (and in mode MODE if that's convenient).
+ SUBTARGET may be used as the target for computing one of EXP's operands.
+ IGNORE is nonzero if the value is to be ignored. */
+
+rtx
+rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
+{
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ enum rs6000_builtins fcode
+ = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
+ size_t uns_fcode = (size_t)fcode;
+ const struct builtin_description *d;
+ size_t i;
+ rtx ret;
+ bool success;
+ HOST_WIDE_INT mask = rs6000_builtin_info[uns_fcode].mask;
+ bool func_valid_p = ((rs6000_builtin_mask & mask) == mask);
+ enum insn_code icode = rs6000_builtin_info[uns_fcode].icode;
+
+ /* We have two different modes (KFmode, TFmode) that are the IEEE 128-bit
+ floating point type, depending on whether long double is the IBM extended
+ double (KFmode) or long double is IEEE 128-bit (TFmode). It is simpler if
+ we only define one variant of the built-in function, and switch the code
+ when defining it, rather than defining two built-ins and using the
+ overload table in rs6000-c.c to switch between the two. If we don't have
+ the proper assembler, don't do this switch because CODE_FOR_*kf* and
+ CODE_FOR_*tf* will be CODE_FOR_nothing. */
+ if (FLOAT128_IEEE_P (TFmode))
+ switch (icode)
+ {
+ default:
+ break;
+
+ case CODE_FOR_sqrtkf2_odd: icode = CODE_FOR_sqrttf2_odd; break;
+ case CODE_FOR_trunckfdf2_odd: icode = CODE_FOR_trunctfdf2_odd; break;
+ case CODE_FOR_addkf3_odd: icode = CODE_FOR_addtf3_odd; break;
+ case CODE_FOR_subkf3_odd: icode = CODE_FOR_subtf3_odd; break;
+ case CODE_FOR_mulkf3_odd: icode = CODE_FOR_multf3_odd; break;
+ case CODE_FOR_divkf3_odd: icode = CODE_FOR_divtf3_odd; break;
+ case CODE_FOR_fmakf4_odd: icode = CODE_FOR_fmatf4_odd; break;
+ case CODE_FOR_xsxexpqp_kf: icode = CODE_FOR_xsxexpqp_tf; break;
+ case CODE_FOR_xsxsigqp_kf: icode = CODE_FOR_xsxsigqp_tf; break;
+ case CODE_FOR_xststdcnegqp_kf: icode = CODE_FOR_xststdcnegqp_tf; break;
+ case CODE_FOR_xsiexpqp_kf: icode = CODE_FOR_xsiexpqp_tf; break;
+ case CODE_FOR_xsiexpqpf_kf: icode = CODE_FOR_xsiexpqpf_tf; break;
+ case CODE_FOR_xststdcqp_kf: icode = CODE_FOR_xststdcqp_tf; break;
+ }
+
+ if (TARGET_DEBUG_BUILTIN)
+ {
+ const char *name1 = rs6000_builtin_info[uns_fcode].name;
+ const char *name2 = (icode != CODE_FOR_nothing)
+ ? get_insn_name ((int) icode)
+ : "nothing";
+ const char *name3;
+
+ switch (rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK)
+ {
+ default: name3 = "unknown"; break;
+ case RS6000_BTC_SPECIAL: name3 = "special"; break;
+ case RS6000_BTC_UNARY: name3 = "unary"; break;
+ case RS6000_BTC_BINARY: name3 = "binary"; break;
+ case RS6000_BTC_TERNARY: name3 = "ternary"; break;
+ case RS6000_BTC_PREDICATE: name3 = "predicate"; break;
+ case RS6000_BTC_ABS: name3 = "abs"; break;
+ case RS6000_BTC_DST: name3 = "dst"; break;
+ }
+
+
+ fprintf (stderr,
+ "rs6000_expand_builtin, %s (%d), insn = %s (%d), type=%s%s\n",
+ (name1) ? name1 : "---", fcode,
+ (name2) ? name2 : "---", (int) icode,
+ name3,
+ func_valid_p ? "" : ", not valid");
+ }
+
+ if (!func_valid_p)
+ {
+ rs6000_invalid_builtin (fcode);
+
+ /* Given it is invalid, just generate a normal call. */
+ return expand_call (exp, target, ignore);
+ }
+
+ switch (fcode)
+ {
+ case RS6000_BUILTIN_RECIP:
+ return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
+
+ case RS6000_BUILTIN_RECIPF:
+ return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
+
+ case RS6000_BUILTIN_RSQRTF:
+ return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
+
+ case RS6000_BUILTIN_RSQRT:
+ return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
+
+ case POWER7_BUILTIN_BPERMD:
+ return rs6000_expand_binop_builtin (((TARGET_64BIT)
+ ? CODE_FOR_bpermd_di
+ : CODE_FOR_bpermd_si), exp, target);
+
+ case RS6000_BUILTIN_GET_TB:
+ return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_get_timebase,
+ target);
+
+ case RS6000_BUILTIN_MFTB:
+ return rs6000_expand_zeroop_builtin (((TARGET_64BIT)
+ ? CODE_FOR_rs6000_mftb_di
+ : CODE_FOR_rs6000_mftb_si),
+ target);
+
+ case RS6000_BUILTIN_MFFS:
+ return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffs, target);
+
+ case RS6000_BUILTIN_MTFSB0:
+ return rs6000_expand_mtfsb_builtin (CODE_FOR_rs6000_mtfsb0, exp);
+
+ case RS6000_BUILTIN_MTFSB1:
+ return rs6000_expand_mtfsb_builtin (CODE_FOR_rs6000_mtfsb1, exp);
+
+ case RS6000_BUILTIN_SET_FPSCR_RN:
+ return rs6000_expand_set_fpscr_rn_builtin (CODE_FOR_rs6000_set_fpscr_rn,
+ exp);
+
+ case RS6000_BUILTIN_SET_FPSCR_DRN:
+ return
+ rs6000_expand_set_fpscr_drn_builtin (CODE_FOR_rs6000_set_fpscr_drn,
+ exp);
+
+ case RS6000_BUILTIN_MFFSL:
+ return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffsl, target);
+
+ case RS6000_BUILTIN_MTFSF:
+ return rs6000_expand_mtfsf_builtin (CODE_FOR_rs6000_mtfsf, exp);
+
+ case RS6000_BUILTIN_CPU_INIT:
+ case RS6000_BUILTIN_CPU_IS:
+ case RS6000_BUILTIN_CPU_SUPPORTS:
+ return cpu_expand_builtin (fcode, exp, target);
+
+ case MISC_BUILTIN_SPEC_BARRIER:
+ {
+ emit_insn (gen_speculation_barrier ());
+ return NULL_RTX;
+ }
+
+ case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
+ case ALTIVEC_BUILTIN_MASK_FOR_STORE:
+ {
+ int icode2 = (BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct
+ : (int) CODE_FOR_altivec_lvsl_direct);
+ machine_mode tmode = insn_data[icode2].operand[0].mode;
+ machine_mode mode = insn_data[icode2].operand[1].mode;
+ tree arg;
+ rtx op, addr, pat;
+
+ gcc_assert (TARGET_ALTIVEC);
+
+ arg = CALL_EXPR_ARG (exp, 0);
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
+ op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
+ addr = memory_address (mode, op);
+ if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
+ op = addr;
+ else
+ {
+ /* For the load case need to negate the address. */
+ op = gen_reg_rtx (GET_MODE (addr));
+ emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr)));
+ }
+ op = gen_rtx_MEM (mode, op);
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode2].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ pat = GEN_FCN (icode2) (target, op);
+ if (!pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+ }
+
+ case ALTIVEC_BUILTIN_VCFUX:
+ case ALTIVEC_BUILTIN_VCFSX:
+ case ALTIVEC_BUILTIN_VCTUXS:
+ case ALTIVEC_BUILTIN_VCTSXS:
+ /* FIXME: There's got to be a nicer way to handle this case than
+ constructing a new CALL_EXPR. */
+ if (call_expr_nargs (exp) == 1)
+ {
+ exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
+ 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
+ }
+ break;
+
+ /* For the pack and unpack int128 routines, fix up the builtin so it
+ uses the correct IBM128 type. */
+ case MISC_BUILTIN_PACK_IF:
+ if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
+ {
+ icode = CODE_FOR_packtf;
+ fcode = MISC_BUILTIN_PACK_TF;
+ uns_fcode = (size_t)fcode;
+ }
+ break;
+
+ case MISC_BUILTIN_UNPACK_IF:
+ if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
+ {
+ icode = CODE_FOR_unpacktf;
+ fcode = MISC_BUILTIN_UNPACK_TF;
+ uns_fcode = (size_t)fcode;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (TARGET_ALTIVEC)
+ {
+ ret = altivec_expand_builtin (exp, target, &success);
+
+ if (success)
+ return ret;
+ }
+ if (TARGET_HTM)
+ {
+ ret = htm_expand_builtin (exp, target, &success);
+
+ if (success)
+ return ret;
+ }
+
+ unsigned attr = rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK;
+ /* RS6000_BTC_SPECIAL represents no-operand operators. */
+ gcc_assert (attr == RS6000_BTC_UNARY
+ || attr == RS6000_BTC_BINARY
+ || attr == RS6000_BTC_TERNARY
+ || attr == RS6000_BTC_SPECIAL);
+
+ /* Handle simple unary operations. */
+ d = bdesc_1arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
+ if (d->code == fcode)
+ return rs6000_expand_unop_builtin (icode, exp, target);
+
+ /* Handle simple binary operations. */
+ d = bdesc_2arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+ if (d->code == fcode)
+ return rs6000_expand_binop_builtin (icode, exp, target);
+
+ /* Handle simple ternary operations. */
+ d = bdesc_3arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
+ if (d->code == fcode)
+ return rs6000_expand_ternop_builtin (icode, exp, target);
+
+ /* Handle simple no-argument operations. */
+ d = bdesc_0arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
+ if (d->code == fcode)
+ return rs6000_expand_zeroop_builtin (icode, target);
+
+ gcc_unreachable ();
+}
+
+/* Create a builtin vector type with a name. Taking care not to give
+ the canonical type a name. */
+
+static tree
+rs6000_vector_type (const char *name, tree elt_type, unsigned num_elts)
+{
+ tree result = build_vector_type (elt_type, num_elts);
+
+ /* Copy so we don't give the canonical type a name. */
+ result = build_variant_type_copy (result);
+
+ add_builtin_type (name, result);
+
+ return result;
+}
+
+void
+rs6000_init_builtins (void)
+{
+ tree tdecl;
+ tree ftype;
+ machine_mode mode;
+
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_init_builtins%s%s\n",
+ (TARGET_ALTIVEC) ? ", altivec" : "",
+ (TARGET_VSX) ? ", vsx" : "");
+
+ V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector long"
+ : "__vector long long",
+ intDI_type_node, 2);
+ V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2);
+ V4SI_type_node = rs6000_vector_type ("__vector signed int",
+ intSI_type_node, 4);
+ V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4);
+ V8HI_type_node = rs6000_vector_type ("__vector signed short",
+ intHI_type_node, 8);
+ V16QI_type_node = rs6000_vector_type ("__vector signed char",
+ intQI_type_node, 16);
+
+ unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char",
+ unsigned_intQI_type_node, 16);
+ unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short",
+ unsigned_intHI_type_node, 8);
+ unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int",
+ unsigned_intSI_type_node, 4);
+ unsigned_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
+ ? "__vector unsigned long"
+ : "__vector unsigned long long",
+ unsigned_intDI_type_node, 2);
+
+ opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
+
+ const_str_type_node
+ = build_pointer_type (build_qualified_type (char_type_node,
+ TYPE_QUAL_CONST));
+
+ /* We use V1TI mode as a special container to hold __int128_t items that
+ must live in VSX registers. */
+ if (intTI_type_node)
+ {
+ V1TI_type_node = rs6000_vector_type ("__vector __int128",
+ intTI_type_node, 1);
+ unsigned_V1TI_type_node
+ = rs6000_vector_type ("__vector unsigned __int128",
+ unsigned_intTI_type_node, 1);
+ }
+
+ /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
+ types, especially in C++ land. Similarly, 'vector pixel' is distinct from
+ 'vector unsigned short'. */
+
+ bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
+ bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
+ bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
+ bool_long_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
+ pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
+
+ long_integer_type_internal_node = long_integer_type_node;
+ long_unsigned_type_internal_node = long_unsigned_type_node;
+ long_long_integer_type_internal_node = long_long_integer_type_node;
+ long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
+ intQI_type_internal_node = intQI_type_node;
+ uintQI_type_internal_node = unsigned_intQI_type_node;
+ intHI_type_internal_node = intHI_type_node;
+ uintHI_type_internal_node = unsigned_intHI_type_node;
+ intSI_type_internal_node = intSI_type_node;
+ uintSI_type_internal_node = unsigned_intSI_type_node;
+ intDI_type_internal_node = intDI_type_node;
+ uintDI_type_internal_node = unsigned_intDI_type_node;
+ intTI_type_internal_node = intTI_type_node;
+ uintTI_type_internal_node = unsigned_intTI_type_node;
+ float_type_internal_node = float_type_node;
+ double_type_internal_node = double_type_node;
+ long_double_type_internal_node = long_double_type_node;
+ dfloat64_type_internal_node = dfloat64_type_node;
+ dfloat128_type_internal_node = dfloat128_type_node;
+ void_type_internal_node = void_type_node;
+
+ /* 128-bit floating point support. KFmode is IEEE 128-bit floating point.
+ IFmode is the IBM extended 128-bit format that is a pair of doubles.
+ TFmode will be either IEEE 128-bit floating point or the IBM double-double
+ format that uses a pair of doubles, depending on the switches and
+ defaults.
+
+ If we don't support for either 128-bit IBM double double or IEEE 128-bit
+ floating point, we need make sure the type is non-zero or else self-test
+ fails during bootstrap.
+
+ Always create __ibm128 as a separate type, even if the current long double
+ format is IBM extended double.
+
+ For IEEE 128-bit floating point, always create the type __ieee128. If the
+ user used -mfloat128, rs6000-c.c will create a define from __float128 to
+ __ieee128. */
+ if (TARGET_FLOAT128_TYPE)
+ {
+ if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
+ ibm128_float_type_node = long_double_type_node;
+ else
+ {
+ ibm128_float_type_node = make_node (REAL_TYPE);
+ TYPE_PRECISION (ibm128_float_type_node) = 128;
+ SET_TYPE_MODE (ibm128_float_type_node, IFmode);
+ layout_type (ibm128_float_type_node);
+ }
+
+ lang_hooks.types.register_builtin_type (ibm128_float_type_node,
+ "__ibm128");
+
+ if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
+ ieee128_float_type_node = long_double_type_node;
+ else
+ ieee128_float_type_node = float128_type_node;
+
+ lang_hooks.types.register_builtin_type (ieee128_float_type_node,
+ "__ieee128");
+ }
+
+ else
+ ieee128_float_type_node = ibm128_float_type_node = long_double_type_node;
+
+ /* Initialize the modes for builtin_function_type, mapping a machine mode to
+ tree type node. */
+ builtin_mode_to_type[QImode][0] = integer_type_node;
+ builtin_mode_to_type[HImode][0] = integer_type_node;
+ builtin_mode_to_type[SImode][0] = intSI_type_node;
+ builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
+ builtin_mode_to_type[DImode][0] = intDI_type_node;
+ builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
+ builtin_mode_to_type[TImode][0] = intTI_type_node;
+ builtin_mode_to_type[TImode][1] = unsigned_intTI_type_node;
+ builtin_mode_to_type[SFmode][0] = float_type_node;
+ builtin_mode_to_type[DFmode][0] = double_type_node;
+ builtin_mode_to_type[IFmode][0] = ibm128_float_type_node;
+ builtin_mode_to_type[KFmode][0] = ieee128_float_type_node;
+ builtin_mode_to_type[TFmode][0] = long_double_type_node;
+ builtin_mode_to_type[DDmode][0] = dfloat64_type_node;
+ builtin_mode_to_type[TDmode][0] = dfloat128_type_node;
+ builtin_mode_to_type[V1TImode][0] = V1TI_type_node;
+ builtin_mode_to_type[V1TImode][1] = unsigned_V1TI_type_node;
+ builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
+ builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
+ builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
+ builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
+ builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
+ builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
+ builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
+ builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
+ builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
+ builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
+
+ tdecl = add_builtin_type ("__bool char", bool_char_type_node);
+ TYPE_NAME (bool_char_type_node) = tdecl;
+
+ tdecl = add_builtin_type ("__bool short", bool_short_type_node);
+ TYPE_NAME (bool_short_type_node) = tdecl;
+
+ tdecl = add_builtin_type ("__bool int", bool_int_type_node);
+ TYPE_NAME (bool_int_type_node) = tdecl;
+
+ tdecl = add_builtin_type ("__pixel", pixel_type_node);
+ TYPE_NAME (pixel_type_node) = tdecl;
+
+ bool_V16QI_type_node = rs6000_vector_type ("__vector __bool char",
+ bool_char_type_node, 16);
+ bool_V8HI_type_node = rs6000_vector_type ("__vector __bool short",
+ bool_short_type_node, 8);
+ bool_V4SI_type_node = rs6000_vector_type ("__vector __bool int",
+ bool_int_type_node, 4);
+ bool_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
+ ? "__vector __bool long"
+ : "__vector __bool long long",
+ bool_long_long_type_node, 2);
+ pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel",
+ pixel_type_node, 8);
+
+ /* Create Altivec and VSX builtins on machines with at least the
+ general purpose extensions (970 and newer) to allow the use of
+ the target attribute. */
+ if (TARGET_EXTRA_BUILTINS)
+ altivec_init_builtins ();
+ if (TARGET_HTM)
+ htm_init_builtins ();
+
+ if (TARGET_EXTRA_BUILTINS)
+ rs6000_common_init_builtins ();
+
+ ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
+ RS6000_BUILTIN_RECIP, "__builtin_recipdiv");
+ def_builtin ("__builtin_recipdiv", ftype, RS6000_BUILTIN_RECIP);
+
+ ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
+ RS6000_BUILTIN_RECIPF, "__builtin_recipdivf");
+ def_builtin ("__builtin_recipdivf", ftype, RS6000_BUILTIN_RECIPF);
+
+ ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
+ RS6000_BUILTIN_RSQRT, "__builtin_rsqrt");
+ def_builtin ("__builtin_rsqrt", ftype, RS6000_BUILTIN_RSQRT);
+
+ ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
+ RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf");
+ def_builtin ("__builtin_rsqrtf", ftype, RS6000_BUILTIN_RSQRTF);
+
+ mode = (TARGET_64BIT) ? DImode : SImode;
+ ftype = builtin_function_type (mode, mode, mode, VOIDmode,
+ POWER7_BUILTIN_BPERMD, "__builtin_bpermd");
+ def_builtin ("__builtin_bpermd", ftype, POWER7_BUILTIN_BPERMD);
+
+ ftype = build_function_type_list (unsigned_intDI_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_ppc_get_timebase", ftype, RS6000_BUILTIN_GET_TB);
+
+ if (TARGET_64BIT)
+ ftype = build_function_type_list (unsigned_intDI_type_node,
+ NULL_TREE);
+ else
+ ftype = build_function_type_list (unsigned_intSI_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_ppc_mftb", ftype, RS6000_BUILTIN_MFTB);
+
+ ftype = build_function_type_list (double_type_node, NULL_TREE);
+ def_builtin ("__builtin_mffs", ftype, RS6000_BUILTIN_MFFS);
+
+ ftype = build_function_type_list (double_type_node, NULL_TREE);
+ def_builtin ("__builtin_mffsl", ftype, RS6000_BUILTIN_MFFSL);
+
+ ftype = build_function_type_list (void_type_node,
+ intSI_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_mtfsb0", ftype, RS6000_BUILTIN_MTFSB0);
+
+ ftype = build_function_type_list (void_type_node,
+ intSI_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_mtfsb1", ftype, RS6000_BUILTIN_MTFSB1);
+
+ ftype = build_function_type_list (void_type_node,
+ intDI_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_set_fpscr_rn", ftype, RS6000_BUILTIN_SET_FPSCR_RN);
+
+ ftype = build_function_type_list (void_type_node,
+ intDI_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_set_fpscr_drn", ftype, RS6000_BUILTIN_SET_FPSCR_DRN);
+
+ ftype = build_function_type_list (void_type_node,
+ intSI_type_node, double_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_mtfsf", ftype, RS6000_BUILTIN_MTFSF);
+
+ ftype = build_function_type_list (void_type_node, NULL_TREE);
+ def_builtin ("__builtin_cpu_init", ftype, RS6000_BUILTIN_CPU_INIT);
+ def_builtin ("__builtin_ppc_speculation_barrier", ftype,
+ MISC_BUILTIN_SPEC_BARRIER);
+
+ ftype = build_function_type_list (bool_int_type_node, const_ptr_type_node,
+ NULL_TREE);
+ def_builtin ("__builtin_cpu_is", ftype, RS6000_BUILTIN_CPU_IS);
+ def_builtin ("__builtin_cpu_supports", ftype, RS6000_BUILTIN_CPU_SUPPORTS);
+
+ /* AIX libm provides clog as __clog. */
+ if (TARGET_XCOFF &&
+ (tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
+ set_user_assembler_name (tdecl, "__clog");
+
+#ifdef SUBTARGET_INIT_BUILTINS
+ SUBTARGET_INIT_BUILTINS;
+#endif
+}
+
+/* Returns the rs6000 builtin decl for CODE. */
+
+tree
+rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
+{
+ HOST_WIDE_INT fnmask;
+
+ if (code >= RS6000_BUILTIN_COUNT)
+ return error_mark_node;
+
+ fnmask = rs6000_builtin_info[code].mask;
+ if ((fnmask & rs6000_builtin_mask) != fnmask)
+ {
+ rs6000_invalid_builtin ((enum rs6000_builtins)code);
+ return error_mark_node;
+ }
+
+ return rs6000_builtin_decls[code];
+}
+
+static void
+altivec_init_builtins (void)
+{
+ const struct builtin_description *d;
+ size_t i;
+ tree ftype;
+ tree decl;
+ HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
+
+ tree pvoid_type_node = build_pointer_type (void_type_node);
+
+ tree pcvoid_type_node
+ = build_pointer_type (build_qualified_type (void_type_node,
+ TYPE_QUAL_CONST));
+
+ tree int_ftype_opaque
+ = build_function_type_list (integer_type_node,
+ opaque_V4SI_type_node, NULL_TREE);
+ tree opaque_ftype_opaque
+ = build_function_type_list (integer_type_node, NULL_TREE);
+ tree opaque_ftype_opaque_int
+ = build_function_type_list (opaque_V4SI_type_node,
+ opaque_V4SI_type_node, integer_type_node, NULL_TREE);
+ tree opaque_ftype_opaque_opaque_int
+ = build_function_type_list (opaque_V4SI_type_node,
+ opaque_V4SI_type_node, opaque_V4SI_type_node,
+ integer_type_node, NULL_TREE);
+ tree opaque_ftype_opaque_opaque_opaque
+ = build_function_type_list (opaque_V4SI_type_node,
+ opaque_V4SI_type_node, opaque_V4SI_type_node,
+ opaque_V4SI_type_node, NULL_TREE);
+ tree opaque_ftype_opaque_opaque
+ = build_function_type_list (opaque_V4SI_type_node,
+ opaque_V4SI_type_node, opaque_V4SI_type_node,
+ NULL_TREE);
+ tree int_ftype_int_opaque_opaque
+ = build_function_type_list (integer_type_node,
+ integer_type_node, opaque_V4SI_type_node,
+ opaque_V4SI_type_node, NULL_TREE);
+ tree int_ftype_int_v4si_v4si
+ = build_function_type_list (integer_type_node,
+ integer_type_node, V4SI_type_node,
+ V4SI_type_node, NULL_TREE);
+ tree int_ftype_int_v2di_v2di
+ = build_function_type_list (integer_type_node,
+ integer_type_node, V2DI_type_node,
+ V2DI_type_node, NULL_TREE);
+ tree void_ftype_v4si
+ = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
+ tree v8hi_ftype_void
+ = build_function_type_list (V8HI_type_node, NULL_TREE);
+ tree void_ftype_void
+ = build_function_type_list (void_type_node, NULL_TREE);
+ tree void_ftype_int
+ = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
+
+ tree opaque_ftype_long_pcvoid
+ = build_function_type_list (opaque_V4SI_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree v16qi_ftype_long_pcvoid
+ = build_function_type_list (V16QI_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree v8hi_ftype_long_pcvoid
+ = build_function_type_list (V8HI_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree v4si_ftype_long_pcvoid
+ = build_function_type_list (V4SI_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree v4sf_ftype_long_pcvoid
+ = build_function_type_list (V4SF_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree v2df_ftype_long_pcvoid
+ = build_function_type_list (V2DF_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree v2di_ftype_long_pcvoid
+ = build_function_type_list (V2DI_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree v1ti_ftype_long_pcvoid
+ = build_function_type_list (V1TI_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+
+ tree void_ftype_opaque_long_pvoid
+ = build_function_type_list (void_type_node,
+ opaque_V4SI_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ tree void_ftype_v4si_long_pvoid
+ = build_function_type_list (void_type_node,
+ V4SI_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ tree void_ftype_v16qi_long_pvoid
+ = build_function_type_list (void_type_node,
+ V16QI_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+
+ tree void_ftype_v16qi_pvoid_long
+ = build_function_type_list (void_type_node,
+ V16QI_type_node, pvoid_type_node,
+ long_integer_type_node, NULL_TREE);
+
+ tree void_ftype_v8hi_long_pvoid
+ = build_function_type_list (void_type_node,
+ V8HI_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ tree void_ftype_v4sf_long_pvoid
+ = build_function_type_list (void_type_node,
+ V4SF_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ tree void_ftype_v2df_long_pvoid
+ = build_function_type_list (void_type_node,
+ V2DF_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ tree void_ftype_v1ti_long_pvoid
+ = build_function_type_list (void_type_node,
+ V1TI_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ tree void_ftype_v2di_long_pvoid
+ = build_function_type_list (void_type_node,
+ V2DI_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ tree int_ftype_int_v8hi_v8hi
+ = build_function_type_list (integer_type_node,
+ integer_type_node, V8HI_type_node,
+ V8HI_type_node, NULL_TREE);
+ tree int_ftype_int_v16qi_v16qi
+ = build_function_type_list (integer_type_node,
+ integer_type_node, V16QI_type_node,
+ V16QI_type_node, NULL_TREE);
+ tree int_ftype_int_v4sf_v4sf
+ = build_function_type_list (integer_type_node,
+ integer_type_node, V4SF_type_node,
+ V4SF_type_node, NULL_TREE);
+ tree int_ftype_int_v2df_v2df
+ = build_function_type_list (integer_type_node,
+ integer_type_node, V2DF_type_node,
+ V2DF_type_node, NULL_TREE);
+ tree v2di_ftype_v2di
+ = build_function_type_list (V2DI_type_node, V2DI_type_node, NULL_TREE);
+ tree v4si_ftype_v4si
+ = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
+ tree v8hi_ftype_v8hi
+ = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
+ tree v16qi_ftype_v16qi
+ = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
+ tree v4sf_ftype_v4sf
+ = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
+ tree v2df_ftype_v2df
+ = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
+ tree void_ftype_pcvoid_int_int
+ = build_function_type_list (void_type_node,
+ pcvoid_type_node, integer_type_node,
+ integer_type_node, NULL_TREE);
+
+ def_builtin ("__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
+ def_builtin ("__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
+ def_builtin ("__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
+ def_builtin ("__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
+ def_builtin ("__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
+ def_builtin ("__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
+ def_builtin ("__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
+ def_builtin ("__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
+ def_builtin ("__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
+ def_builtin ("__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
+ def_builtin ("__builtin_altivec_lvxl_v2df", v2df_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVXL_V2DF);
+ def_builtin ("__builtin_altivec_lvxl_v2di", v2di_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVXL_V2DI);
+ def_builtin ("__builtin_altivec_lvxl_v4sf", v4sf_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVXL_V4SF);
+ def_builtin ("__builtin_altivec_lvxl_v4si", v4si_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVXL_V4SI);
+ def_builtin ("__builtin_altivec_lvxl_v8hi", v8hi_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVXL_V8HI);
+ def_builtin ("__builtin_altivec_lvxl_v16qi", v16qi_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVXL_V16QI);
+ def_builtin ("__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
+ def_builtin ("__builtin_altivec_lvx_v1ti", v1ti_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVX_V1TI);
+ def_builtin ("__builtin_altivec_lvx_v2df", v2df_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVX_V2DF);
+ def_builtin ("__builtin_altivec_lvx_v2di", v2di_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVX_V2DI);
+ def_builtin ("__builtin_altivec_lvx_v4sf", v4sf_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVX_V4SF);
+ def_builtin ("__builtin_altivec_lvx_v4si", v4si_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVX_V4SI);
+ def_builtin ("__builtin_altivec_lvx_v8hi", v8hi_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVX_V8HI);
+ def_builtin ("__builtin_altivec_lvx_v16qi", v16qi_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_LVX_V16QI);
+ def_builtin ("__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
+ def_builtin ("__builtin_altivec_stvx_v2df", void_ftype_v2df_long_pvoid,
+ ALTIVEC_BUILTIN_STVX_V2DF);
+ def_builtin ("__builtin_altivec_stvx_v2di", void_ftype_v2di_long_pvoid,
+ ALTIVEC_BUILTIN_STVX_V2DI);
+ def_builtin ("__builtin_altivec_stvx_v4sf", void_ftype_v4sf_long_pvoid,
+ ALTIVEC_BUILTIN_STVX_V4SF);
+ def_builtin ("__builtin_altivec_stvx_v4si", void_ftype_v4si_long_pvoid,
+ ALTIVEC_BUILTIN_STVX_V4SI);
+ def_builtin ("__builtin_altivec_stvx_v8hi", void_ftype_v8hi_long_pvoid,
+ ALTIVEC_BUILTIN_STVX_V8HI);
+ def_builtin ("__builtin_altivec_stvx_v16qi", void_ftype_v16qi_long_pvoid,
+ ALTIVEC_BUILTIN_STVX_V16QI);
+ def_builtin ("__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
+ def_builtin ("__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
+ def_builtin ("__builtin_altivec_stvxl_v2df", void_ftype_v2df_long_pvoid,
+ ALTIVEC_BUILTIN_STVXL_V2DF);
+ def_builtin ("__builtin_altivec_stvxl_v2di", void_ftype_v2di_long_pvoid,
+ ALTIVEC_BUILTIN_STVXL_V2DI);
+ def_builtin ("__builtin_altivec_stvxl_v4sf", void_ftype_v4sf_long_pvoid,
+ ALTIVEC_BUILTIN_STVXL_V4SF);
+ def_builtin ("__builtin_altivec_stvxl_v4si", void_ftype_v4si_long_pvoid,
+ ALTIVEC_BUILTIN_STVXL_V4SI);
+ def_builtin ("__builtin_altivec_stvxl_v8hi", void_ftype_v8hi_long_pvoid,
+ ALTIVEC_BUILTIN_STVXL_V8HI);
+ def_builtin ("__builtin_altivec_stvxl_v16qi", void_ftype_v16qi_long_pvoid,
+ ALTIVEC_BUILTIN_STVXL_V16QI);
+ def_builtin ("__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
+ def_builtin ("__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
+ def_builtin ("__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
+ def_builtin ("__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
+ def_builtin ("__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
+ def_builtin ("__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
+ def_builtin ("__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
+ def_builtin ("__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
+ def_builtin ("__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
+ def_builtin ("__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
+ def_builtin ("__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
+ def_builtin ("__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
+ def_builtin ("__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
+ def_builtin ("__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
+ def_builtin ("__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
+ def_builtin ("__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
+
+ def_builtin ("__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
+ VSX_BUILTIN_LXVD2X_V2DF);
+ def_builtin ("__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
+ VSX_BUILTIN_LXVD2X_V2DI);
+ def_builtin ("__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
+ VSX_BUILTIN_LXVW4X_V4SF);
+ def_builtin ("__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
+ VSX_BUILTIN_LXVW4X_V4SI);
+ def_builtin ("__builtin_vsx_lxvw4x_v8hi", v8hi_ftype_long_pcvoid,
+ VSX_BUILTIN_LXVW4X_V8HI);
+ def_builtin ("__builtin_vsx_lxvw4x_v16qi", v16qi_ftype_long_pcvoid,
+ VSX_BUILTIN_LXVW4X_V16QI);
+ def_builtin ("__builtin_vsx_stxvd2x_v2df", void_ftype_v2df_long_pvoid,
+ VSX_BUILTIN_STXVD2X_V2DF);
+ def_builtin ("__builtin_vsx_stxvd2x_v2di", void_ftype_v2di_long_pvoid,
+ VSX_BUILTIN_STXVD2X_V2DI);
+ def_builtin ("__builtin_vsx_stxvw4x_v4sf", void_ftype_v4sf_long_pvoid,
+ VSX_BUILTIN_STXVW4X_V4SF);
+ def_builtin ("__builtin_vsx_stxvw4x_v4si", void_ftype_v4si_long_pvoid,
+ VSX_BUILTIN_STXVW4X_V4SI);
+ def_builtin ("__builtin_vsx_stxvw4x_v8hi", void_ftype_v8hi_long_pvoid,
+ VSX_BUILTIN_STXVW4X_V8HI);
+ def_builtin ("__builtin_vsx_stxvw4x_v16qi", void_ftype_v16qi_long_pvoid,
+ VSX_BUILTIN_STXVW4X_V16QI);
+
+ def_builtin ("__builtin_vsx_ld_elemrev_v2df", v2df_ftype_long_pcvoid,
+ VSX_BUILTIN_LD_ELEMREV_V2DF);
+ def_builtin ("__builtin_vsx_ld_elemrev_v2di", v2di_ftype_long_pcvoid,
+ VSX_BUILTIN_LD_ELEMREV_V2DI);
+ def_builtin ("__builtin_vsx_ld_elemrev_v4sf", v4sf_ftype_long_pcvoid,
+ VSX_BUILTIN_LD_ELEMREV_V4SF);
+ def_builtin ("__builtin_vsx_ld_elemrev_v4si", v4si_ftype_long_pcvoid,
+ VSX_BUILTIN_LD_ELEMREV_V4SI);
+ def_builtin ("__builtin_vsx_ld_elemrev_v8hi", v8hi_ftype_long_pcvoid,
+ VSX_BUILTIN_LD_ELEMREV_V8HI);
+ def_builtin ("__builtin_vsx_ld_elemrev_v16qi", v16qi_ftype_long_pcvoid,
+ VSX_BUILTIN_LD_ELEMREV_V16QI);
+ def_builtin ("__builtin_vsx_st_elemrev_v2df", void_ftype_v2df_long_pvoid,
+ VSX_BUILTIN_ST_ELEMREV_V2DF);
+ def_builtin ("__builtin_vsx_st_elemrev_v1ti", void_ftype_v1ti_long_pvoid,
+ VSX_BUILTIN_ST_ELEMREV_V1TI);
+ def_builtin ("__builtin_vsx_st_elemrev_v2di", void_ftype_v2di_long_pvoid,
+ VSX_BUILTIN_ST_ELEMREV_V2DI);
+ def_builtin ("__builtin_vsx_st_elemrev_v4sf", void_ftype_v4sf_long_pvoid,
+ VSX_BUILTIN_ST_ELEMREV_V4SF);
+ def_builtin ("__builtin_vsx_st_elemrev_v4si", void_ftype_v4si_long_pvoid,
+ VSX_BUILTIN_ST_ELEMREV_V4SI);
+ def_builtin ("__builtin_vsx_st_elemrev_v8hi", void_ftype_v8hi_long_pvoid,
+ VSX_BUILTIN_ST_ELEMREV_V8HI);
+ def_builtin ("__builtin_vsx_st_elemrev_v16qi", void_ftype_v16qi_long_pvoid,
+ VSX_BUILTIN_ST_ELEMREV_V16QI);
+
+ def_builtin ("__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
+ VSX_BUILTIN_VEC_LD);
+ def_builtin ("__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
+ VSX_BUILTIN_VEC_ST);
+ def_builtin ("__builtin_vec_xl", opaque_ftype_long_pcvoid,
+ VSX_BUILTIN_VEC_XL);
+ def_builtin ("__builtin_vec_xl_be", opaque_ftype_long_pcvoid,
+ VSX_BUILTIN_VEC_XL_BE);
+ def_builtin ("__builtin_vec_xst", void_ftype_opaque_long_pvoid,
+ VSX_BUILTIN_VEC_XST);
+ def_builtin ("__builtin_vec_xst_be", void_ftype_opaque_long_pvoid,
+ VSX_BUILTIN_VEC_XST_BE);
+
+ def_builtin ("__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
+ def_builtin ("__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
+ def_builtin ("__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
+
+ def_builtin ("__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
+ def_builtin ("__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
+ def_builtin ("__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
+ def_builtin ("__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
+ def_builtin ("__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
+ def_builtin ("__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
+ def_builtin ("__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
+ def_builtin ("__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
+ def_builtin ("__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
+ def_builtin ("__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
+ def_builtin ("__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
+ def_builtin ("__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
+
+ def_builtin ("__builtin_vec_adde", opaque_ftype_opaque_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_ADDE);
+ def_builtin ("__builtin_vec_addec", opaque_ftype_opaque_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_ADDEC);
+ def_builtin ("__builtin_vec_cmpne", opaque_ftype_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_CMPNE);
+ def_builtin ("__builtin_vec_mul", opaque_ftype_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_MUL);
+ def_builtin ("__builtin_vec_sube", opaque_ftype_opaque_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_SUBE);
+ def_builtin ("__builtin_vec_subec", opaque_ftype_opaque_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_SUBEC);
+
+ /* Cell builtins. */
+ def_builtin ("__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
+ def_builtin ("__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
+ def_builtin ("__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
+ def_builtin ("__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
+
+ def_builtin ("__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
+ def_builtin ("__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
+ def_builtin ("__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
+ def_builtin ("__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
+
+ def_builtin ("__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
+ def_builtin ("__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
+ def_builtin ("__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
+ def_builtin ("__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
+
+ def_builtin ("__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
+ def_builtin ("__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
+ def_builtin ("__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
+ def_builtin ("__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
+
+ if (TARGET_P9_VECTOR)
+ {
+ def_builtin ("__builtin_altivec_stxvl", void_ftype_v16qi_pvoid_long,
+ P9V_BUILTIN_STXVL);
+ def_builtin ("__builtin_xst_len_r", void_ftype_v16qi_pvoid_long,
+ P9V_BUILTIN_XST_LEN_R);
+ }
+
+ /* Add the DST variants. */
+ d = bdesc_dst;
+ for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
+ {
+ HOST_WIDE_INT mask = d->mask;
+
+ /* It is expected that these dst built-in functions may have
+ d->icode equal to CODE_FOR_nothing. */
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "altivec_init_builtins, skip dst %s\n",
+ d->name);
+ continue;
+ }
+ def_builtin (d->name, void_ftype_pcvoid_int_int, d->code);
+ }
+
+ /* Initialize the predicates. */
+ d = bdesc_altivec_preds;
+ for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, d++)
+ {
+ machine_mode mode1;
+ tree type;
+ HOST_WIDE_INT mask = d->mask;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "altivec_init_builtins, skip predicate %s\n",
+ d->name);
+ continue;
+ }
+
+ if (rs6000_overloaded_builtin_p (d->code))
+ mode1 = VOIDmode;
+ else
+ {
+ /* Cannot define builtin if the instruction is disabled. */
+ gcc_assert (d->icode != CODE_FOR_nothing);
+ mode1 = insn_data[d->icode].operand[1].mode;
+ }
+
+ switch (mode1)
+ {
+ case E_VOIDmode:
+ type = int_ftype_int_opaque_opaque;
+ break;
+ case E_V2DImode:
+ type = int_ftype_int_v2di_v2di;
+ break;
+ case E_V4SImode:
+ type = int_ftype_int_v4si_v4si;
+ break;
+ case E_V8HImode:
+ type = int_ftype_int_v8hi_v8hi;
+ break;
+ case E_V16QImode:
+ type = int_ftype_int_v16qi_v16qi;
+ break;
+ case E_V4SFmode:
+ type = int_ftype_int_v4sf_v4sf;
+ break;
+ case E_V2DFmode:
+ type = int_ftype_int_v2df_v2df;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ def_builtin (d->name, type, d->code);
+ }
+
+ /* Initialize the abs* operators. */
+ d = bdesc_abs;
+ for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
+ {
+ machine_mode mode0;
+ tree type;
+ HOST_WIDE_INT mask = d->mask;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "altivec_init_builtins, skip abs %s\n",
+ d->name);
+ continue;
+ }
+
+ /* Cannot define builtin if the instruction is disabled. */
+ gcc_assert (d->icode != CODE_FOR_nothing);
+ mode0 = insn_data[d->icode].operand[0].mode;
+
+ switch (mode0)
+ {
+ case E_V2DImode:
+ type = v2di_ftype_v2di;
+ break;
+ case E_V4SImode:
+ type = v4si_ftype_v4si;
+ break;
+ case E_V8HImode:
+ type = v8hi_ftype_v8hi;
+ break;
+ case E_V16QImode:
+ type = v16qi_ftype_v16qi;
+ break;
+ case E_V4SFmode:
+ type = v4sf_ftype_v4sf;
+ break;
+ case E_V2DFmode:
+ type = v2df_ftype_v2df;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ def_builtin (d->name, type, d->code);
+ }
+
+ /* Initialize target builtin that implements
+ targetm.vectorize.builtin_mask_for_load. */
+
+ decl = add_builtin_function ("__builtin_altivec_mask_for_load",
+ v16qi_ftype_long_pcvoid,
+ ALTIVEC_BUILTIN_MASK_FOR_LOAD,
+ BUILT_IN_MD, NULL, NULL_TREE);
+ TREE_READONLY (decl) = 1;
+ /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
+ altivec_builtin_mask_for_load = decl;
+
+ /* Access to the vec_init patterns. */
+ ftype = build_function_type_list (V4SI_type_node, integer_type_node,
+ integer_type_node, integer_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_init_v4si", ftype, ALTIVEC_BUILTIN_VEC_INIT_V4SI);
+
+ ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
+ short_integer_type_node,
+ short_integer_type_node,
+ short_integer_type_node,
+ short_integer_type_node,
+ short_integer_type_node,
+ short_integer_type_node,
+ short_integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_init_v8hi", ftype, ALTIVEC_BUILTIN_VEC_INIT_V8HI);
+
+ ftype = build_function_type_list (V16QI_type_node, char_type_node,
+ char_type_node, char_type_node,
+ char_type_node, char_type_node,
+ char_type_node, char_type_node,
+ char_type_node, char_type_node,
+ char_type_node, char_type_node,
+ char_type_node, char_type_node,
+ char_type_node, char_type_node,
+ char_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_init_v16qi", ftype,
+ ALTIVEC_BUILTIN_VEC_INIT_V16QI);
+
+ ftype = build_function_type_list (V4SF_type_node, float_type_node,
+ float_type_node, float_type_node,
+ float_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_init_v4sf", ftype, ALTIVEC_BUILTIN_VEC_INIT_V4SF);
+
+ /* VSX builtins. */
+ ftype = build_function_type_list (V2DF_type_node, double_type_node,
+ double_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_init_v2df", ftype, VSX_BUILTIN_VEC_INIT_V2DF);
+
+ ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
+ intDI_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_init_v2di", ftype, VSX_BUILTIN_VEC_INIT_V2DI);
+
+ /* Access to the vec_set patterns. */
+ ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
+ intSI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_set_v4si", ftype, ALTIVEC_BUILTIN_VEC_SET_V4SI);
+
+ ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
+ intHI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_set_v8hi", ftype, ALTIVEC_BUILTIN_VEC_SET_V8HI);
+
+ ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
+ intQI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_set_v16qi", ftype, ALTIVEC_BUILTIN_VEC_SET_V16QI);
+
+ ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
+ float_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_set_v4sf", ftype, ALTIVEC_BUILTIN_VEC_SET_V4SF);
+
+ ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
+ double_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_set_v2df", ftype, VSX_BUILTIN_VEC_SET_V2DF);
+
+ ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
+ intDI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_set_v2di", ftype, VSX_BUILTIN_VEC_SET_V2DI);
+
+ /* Access to the vec_extract patterns. */
+ ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_ext_v4si", ftype, ALTIVEC_BUILTIN_VEC_EXT_V4SI);
+
+ ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_ext_v8hi", ftype, ALTIVEC_BUILTIN_VEC_EXT_V8HI);
+
+ ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_ext_v16qi", ftype, ALTIVEC_BUILTIN_VEC_EXT_V16QI);
+
+ ftype = build_function_type_list (float_type_node, V4SF_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_ext_v4sf", ftype, ALTIVEC_BUILTIN_VEC_EXT_V4SF);
+
+ ftype = build_function_type_list (double_type_node, V2DF_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_ext_v2df", ftype, VSX_BUILTIN_VEC_EXT_V2DF);
+
+ ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_ext_v2di", ftype, VSX_BUILTIN_VEC_EXT_V2DI);
+
+
+ if (V1TI_type_node)
+ {
+ tree v1ti_ftype_long_pcvoid
+ = build_function_type_list (V1TI_type_node,
+ long_integer_type_node, pcvoid_type_node,
+ NULL_TREE);
+ tree void_ftype_v1ti_long_pvoid
+ = build_function_type_list (void_type_node,
+ V1TI_type_node, long_integer_type_node,
+ pvoid_type_node, NULL_TREE);
+ def_builtin ("__builtin_vsx_ld_elemrev_v1ti", v1ti_ftype_long_pcvoid,
+ VSX_BUILTIN_LD_ELEMREV_V1TI);
+ def_builtin ("__builtin_vsx_lxvd2x_v1ti", v1ti_ftype_long_pcvoid,
+ VSX_BUILTIN_LXVD2X_V1TI);
+ def_builtin ("__builtin_vsx_stxvd2x_v1ti", void_ftype_v1ti_long_pvoid,
+ VSX_BUILTIN_STXVD2X_V1TI);
+ ftype = build_function_type_list (V1TI_type_node, intTI_type_node,
+ NULL_TREE, NULL_TREE);
+ def_builtin ("__builtin_vec_init_v1ti", ftype, VSX_BUILTIN_VEC_INIT_V1TI);
+ ftype = build_function_type_list (V1TI_type_node, V1TI_type_node,
+ intTI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_set_v1ti", ftype, VSX_BUILTIN_VEC_SET_V1TI);
+ ftype = build_function_type_list (intTI_type_node, V1TI_type_node,
+ integer_type_node, NULL_TREE);
+ def_builtin ("__builtin_vec_ext_v1ti", ftype, VSX_BUILTIN_VEC_EXT_V1TI);
+ }
+
+}
+
+static void
+htm_init_builtins (void)
+{
+ HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
+ const struct builtin_description *d;
+ size_t i;
+
+ d = bdesc_htm;
+ for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
+ {
+ tree op[MAX_HTM_OPERANDS], type;
+ HOST_WIDE_INT mask = d->mask;
+ unsigned attr = rs6000_builtin_info[d->code].attr;
+ bool void_func = (attr & RS6000_BTC_VOID);
+ int attr_args = (attr & RS6000_BTC_TYPE_MASK);
+ int nopnds = 0;
+ tree gpr_type_node;
+ tree rettype;
+ tree argtype;
+
+ /* It is expected that these htm built-in functions may have
+ d->icode equal to CODE_FOR_nothing. */
+
+ if (TARGET_32BIT && TARGET_POWERPC64)
+ gpr_type_node = long_long_unsigned_type_node;
+ else
+ gpr_type_node = long_unsigned_type_node;
+
+ if (attr & RS6000_BTC_SPR)
+ {
+ rettype = gpr_type_node;
+ argtype = gpr_type_node;
+ }
+ else if (d->code == HTM_BUILTIN_TABORTDC
+ || d->code == HTM_BUILTIN_TABORTDCI)
+ {
+ rettype = unsigned_type_node;
+ argtype = gpr_type_node;
+ }
+ else
+ {
+ rettype = unsigned_type_node;
+ argtype = unsigned_type_node;
+ }
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "htm_builtin, skip binary %s\n", d->name);
+ continue;
+ }
+
+ if (d->name == 0)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "htm_builtin, bdesc_htm[%ld] no name\n",
+ (long unsigned) i);
+ continue;
+ }
+
+ op[nopnds++] = (void_func) ? void_type_node : rettype;
+
+ if (attr_args == RS6000_BTC_UNARY)
+ op[nopnds++] = argtype;
+ else if (attr_args == RS6000_BTC_BINARY)
+ {
+ op[nopnds++] = argtype;
+ op[nopnds++] = argtype;
+ }
+ else if (attr_args == RS6000_BTC_TERNARY)
+ {
+ op[nopnds++] = argtype;
+ op[nopnds++] = argtype;
+ op[nopnds++] = argtype;
+ }
+
+ switch (nopnds)
+ {
+ case 1:
+ type = build_function_type_list (op[0], NULL_TREE);
+ break;
+ case 2:
+ type = build_function_type_list (op[0], op[1], NULL_TREE);
+ break;
+ case 3:
+ type = build_function_type_list (op[0], op[1], op[2], NULL_TREE);
+ break;
+ case 4:
+ type = build_function_type_list (op[0], op[1], op[2], op[3],
+ NULL_TREE);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ def_builtin (d->name, type, d->code);
+ }
+}
+
+/* Map types for builtin functions with an explicit return type and up to 3
+ arguments. Functions with fewer than 3 arguments use VOIDmode as the type
+ of the argument. */
+static tree
+builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
+ machine_mode mode_arg1, machine_mode mode_arg2,
+ enum rs6000_builtins builtin, const char *name)
+{
+ struct builtin_hash_struct h;
+ struct builtin_hash_struct *h2;
+ int num_args = 3;
+ int i;
+ tree ret_type = NULL_TREE;
+ tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
+
+ /* Create builtin_hash_table. */
+ if (builtin_hash_table == NULL)
+ builtin_hash_table = hash_table<builtin_hasher>::create_ggc (1500);
+
+ h.type = NULL_TREE;
+ h.mode[0] = mode_ret;
+ h.mode[1] = mode_arg0;
+ h.mode[2] = mode_arg1;
+ h.mode[3] = mode_arg2;
+ h.uns_p[0] = 0;
+ h.uns_p[1] = 0;
+ h.uns_p[2] = 0;
+ h.uns_p[3] = 0;
+
+ /* If the builtin is a type that produces unsigned results or takes unsigned
+ arguments, and it is returned as a decl for the vectorizer (such as
+ widening multiplies, permute), make sure the arguments and return value
+ are type correct. */
+ switch (builtin)
+ {
+ /* unsigned 1 argument functions. */
+ case CRYPTO_BUILTIN_VSBOX:
+ case CRYPTO_BUILTIN_VSBOX_BE:
+ case P8V_BUILTIN_VGBBD:
+ case MISC_BUILTIN_CDTBCD:
+ case MISC_BUILTIN_CBCDTD:
+ h.uns_p[0] = 1;
+ h.uns_p[1] = 1;
+ break;
+
+ /* unsigned 2 argument functions. */
+ case ALTIVEC_BUILTIN_VMULEUB:
+ case ALTIVEC_BUILTIN_VMULEUH:
+ case P8V_BUILTIN_VMULEUW:
+ case ALTIVEC_BUILTIN_VMULOUB:
+ case ALTIVEC_BUILTIN_VMULOUH:
+ case P8V_BUILTIN_VMULOUW:
+ case CRYPTO_BUILTIN_VCIPHER:
+ case CRYPTO_BUILTIN_VCIPHER_BE:
+ case CRYPTO_BUILTIN_VCIPHERLAST:
+ case CRYPTO_BUILTIN_VCIPHERLAST_BE:
+ case CRYPTO_BUILTIN_VNCIPHER:
+ case CRYPTO_BUILTIN_VNCIPHER_BE:
+ case CRYPTO_BUILTIN_VNCIPHERLAST:
+ case CRYPTO_BUILTIN_VNCIPHERLAST_BE:
+ case CRYPTO_BUILTIN_VPMSUMB:
+ case CRYPTO_BUILTIN_VPMSUMH:
+ case CRYPTO_BUILTIN_VPMSUMW:
+ case CRYPTO_BUILTIN_VPMSUMD:
+ case CRYPTO_BUILTIN_VPMSUM:
+ case MISC_BUILTIN_ADDG6S:
+ case MISC_BUILTIN_DIVWEU:
+ case MISC_BUILTIN_DIVDEU:
+ case VSX_BUILTIN_UDIV_V2DI:
+ case ALTIVEC_BUILTIN_VMAXUB:
+ case ALTIVEC_BUILTIN_VMINUB:
+ case ALTIVEC_BUILTIN_VMAXUH:
+ case ALTIVEC_BUILTIN_VMINUH:
+ case ALTIVEC_BUILTIN_VMAXUW:
+ case ALTIVEC_BUILTIN_VMINUW:
+ case P8V_BUILTIN_VMAXUD:
+ case P8V_BUILTIN_VMINUD:
+ h.uns_p[0] = 1;
+ h.uns_p[1] = 1;
+ h.uns_p[2] = 1;
+ break;
+
+ /* unsigned 3 argument functions. */
+ case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
+ case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
+ case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
+ case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
+ case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
+ case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
+ case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
+ case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
+ case VSX_BUILTIN_VPERM_16QI_UNS:
+ case VSX_BUILTIN_VPERM_8HI_UNS:
+ case VSX_BUILTIN_VPERM_4SI_UNS:
+ case VSX_BUILTIN_VPERM_2DI_UNS:
+ case VSX_BUILTIN_XXSEL_16QI_UNS:
+ case VSX_BUILTIN_XXSEL_8HI_UNS:
+ case VSX_BUILTIN_XXSEL_4SI_UNS:
+ case VSX_BUILTIN_XXSEL_2DI_UNS:
+ case CRYPTO_BUILTIN_VPERMXOR:
+ case CRYPTO_BUILTIN_VPERMXOR_V2DI:
+ case CRYPTO_BUILTIN_VPERMXOR_V4SI:
+ case CRYPTO_BUILTIN_VPERMXOR_V8HI:
+ case CRYPTO_BUILTIN_VPERMXOR_V16QI:
+ case CRYPTO_BUILTIN_VSHASIGMAW:
+ case CRYPTO_BUILTIN_VSHASIGMAD:
+ case CRYPTO_BUILTIN_VSHASIGMA:
+ h.uns_p[0] = 1;
+ h.uns_p[1] = 1;
+ h.uns_p[2] = 1;
+ h.uns_p[3] = 1;
+ break;
+
+ /* signed permute functions with unsigned char mask. */
+ case ALTIVEC_BUILTIN_VPERM_16QI:
+ case ALTIVEC_BUILTIN_VPERM_8HI:
+ case ALTIVEC_BUILTIN_VPERM_4SI:
+ case ALTIVEC_BUILTIN_VPERM_4SF:
+ case ALTIVEC_BUILTIN_VPERM_2DI:
+ case ALTIVEC_BUILTIN_VPERM_2DF:
+ case VSX_BUILTIN_VPERM_16QI:
+ case VSX_BUILTIN_VPERM_8HI:
+ case VSX_BUILTIN_VPERM_4SI:
+ case VSX_BUILTIN_VPERM_4SF:
+ case VSX_BUILTIN_VPERM_2DI:
+ case VSX_BUILTIN_VPERM_2DF:
+ h.uns_p[3] = 1;
+ break;
+
+ /* unsigned args, signed return. */
+ case VSX_BUILTIN_XVCVUXDSP:
+ case VSX_BUILTIN_XVCVUXDDP_UNS:
+ case ALTIVEC_BUILTIN_UNSFLOAT_V4SI_V4SF:
+ h.uns_p[1] = 1;
+ break;
+
+ /* signed args, unsigned return. */
+ case VSX_BUILTIN_XVCVDPUXDS_UNS:
+ case ALTIVEC_BUILTIN_FIXUNS_V4SF_V4SI:
+ case MISC_BUILTIN_UNPACK_TD:
+ case MISC_BUILTIN_UNPACK_V1TI:
+ h.uns_p[0] = 1;
+ break;
+
+ /* unsigned arguments, bool return (compares). */
+ case ALTIVEC_BUILTIN_VCMPEQUB:
+ case ALTIVEC_BUILTIN_VCMPEQUH:
+ case ALTIVEC_BUILTIN_VCMPEQUW:
+ case P8V_BUILTIN_VCMPEQUD:
+ case VSX_BUILTIN_CMPGE_U16QI:
+ case VSX_BUILTIN_CMPGE_U8HI:
+ case VSX_BUILTIN_CMPGE_U4SI:
+ case VSX_BUILTIN_CMPGE_U2DI:
+ case ALTIVEC_BUILTIN_VCMPGTUB:
+ case ALTIVEC_BUILTIN_VCMPGTUH:
+ case ALTIVEC_BUILTIN_VCMPGTUW:
+ case P8V_BUILTIN_VCMPGTUD:
+ h.uns_p[1] = 1;
+ h.uns_p[2] = 1;
+ break;
+
+ /* unsigned arguments for 128-bit pack instructions. */
+ case MISC_BUILTIN_PACK_TD:
+ case MISC_BUILTIN_PACK_V1TI:
+ h.uns_p[1] = 1;
+ h.uns_p[2] = 1;
+ break;
+
+ /* unsigned second arguments (vector shift right). */
+ case ALTIVEC_BUILTIN_VSRB:
+ case ALTIVEC_BUILTIN_VSRH:
+ case ALTIVEC_BUILTIN_VSRW:
+ case P8V_BUILTIN_VSRD:
+ h.uns_p[2] = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Figure out how many args are present. */
+ while (num_args > 0 && h.mode[num_args] == VOIDmode)
+ num_args--;
+
+ ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
+ if (!ret_type && h.uns_p[0])
+ ret_type = builtin_mode_to_type[h.mode[0]][0];
+
+ if (!ret_type)
+ fatal_error (input_location,
+ "internal error: builtin function %qs had an unexpected "
+ "return type %qs", name, GET_MODE_NAME (h.mode[0]));
+
+ for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
+ arg_type[i] = NULL_TREE;
+
+ for (i = 0; i < num_args; i++)
+ {
+ int m = (int) h.mode[i+1];
+ int uns_p = h.uns_p[i+1];
+
+ arg_type[i] = builtin_mode_to_type[m][uns_p];
+ if (!arg_type[i] && uns_p)
+ arg_type[i] = builtin_mode_to_type[m][0];
+
+ if (!arg_type[i])
+ fatal_error (input_location,
+ "internal error: builtin function %qs, argument %d "
+ "had unexpected argument type %qs", name, i,
+ GET_MODE_NAME (m));
+ }
+
+ builtin_hash_struct **found = builtin_hash_table->find_slot (&h, INSERT);
+ if (*found == NULL)
+ {
+ h2 = ggc_alloc<builtin_hash_struct> ();
+ *h2 = h;
+ *found = h2;
+
+ h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
+ arg_type[2], NULL_TREE);
+ }
+
+ return (*found)->type;
+}
+
+static void
+rs6000_common_init_builtins (void)
+{
+ const struct builtin_description *d;
+ size_t i;
+
+ tree opaque_ftype_opaque = NULL_TREE;
+ tree opaque_ftype_opaque_opaque = NULL_TREE;
+ tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
+ HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
+
+ /* Create Altivec and VSX builtins on machines with at least the
+ general purpose extensions (970 and newer) to allow the use of
+ the target attribute. */
+
+ if (TARGET_EXTRA_BUILTINS)
+ builtin_mask |= RS6000_BTM_COMMON;
+
+ /* Add the ternary operators. */
+ d = bdesc_3arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
+ {
+ tree type;
+ HOST_WIDE_INT mask = d->mask;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip ternary %s\n", d->name);
+ continue;
+ }
+
+ if (rs6000_overloaded_builtin_p (d->code))
+ {
+ if (! (type = opaque_ftype_opaque_opaque_opaque))
+ type = opaque_ftype_opaque_opaque_opaque
+ = build_function_type_list (opaque_V4SI_type_node,
+ opaque_V4SI_type_node,
+ opaque_V4SI_type_node,
+ opaque_V4SI_type_node,
+ NULL_TREE);
+ }
+ else
+ {
+ enum insn_code icode = d->icode;
+ if (d->name == 0)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, bdesc_3arg[%ld] no name\n",
+ (long unsigned)i);
+
+ continue;
+ }
+
+ if (icode == CODE_FOR_nothing)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip ternary %s (no code)\n",
+ d->name);
+
+ continue;
+ }
+
+ type = builtin_function_type (insn_data[icode].operand[0].mode,
+ insn_data[icode].operand[1].mode,
+ insn_data[icode].operand[2].mode,
+ insn_data[icode].operand[3].mode,
+ d->code, d->name);
+ }
+
+ def_builtin (d->name, type, d->code);
+ }
+
+ /* Add the binary operators. */
+ d = bdesc_2arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+ {
+ machine_mode mode0, mode1, mode2;
+ tree type;
+ HOST_WIDE_INT mask = d->mask;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip binary %s\n", d->name);
+ continue;
+ }
+
+ if (rs6000_overloaded_builtin_p (d->code))
+ {
+ if (! (type = opaque_ftype_opaque_opaque))
+ type = opaque_ftype_opaque_opaque
+ = build_function_type_list (opaque_V4SI_type_node,
+ opaque_V4SI_type_node,
+ opaque_V4SI_type_node,
+ NULL_TREE);
+ }
+ else
+ {
+ enum insn_code icode = d->icode;
+ if (d->name == 0)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, bdesc_2arg[%ld] no name\n",
+ (long unsigned)i);
+
+ continue;
+ }
+
+ if (icode == CODE_FOR_nothing)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip binary %s (no code)\n",
+ d->name);
+
+ continue;
+ }
+
+ mode0 = insn_data[icode].operand[0].mode;
+ mode1 = insn_data[icode].operand[1].mode;
+ mode2 = insn_data[icode].operand[2].mode;
+
+ type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
+ d->code, d->name);
+ }
+
+ def_builtin (d->name, type, d->code);
+ }
+
+ /* Add the simple unary operators. */
+ d = bdesc_1arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
+ {
+ machine_mode mode0, mode1;
+ tree type;
+ HOST_WIDE_INT mask = d->mask;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip unary %s\n", d->name);
+ continue;
+ }
+
+ if (rs6000_overloaded_builtin_p (d->code))
+ {
+ if (! (type = opaque_ftype_opaque))
+ type = opaque_ftype_opaque
+ = build_function_type_list (opaque_V4SI_type_node,
+ opaque_V4SI_type_node,
+ NULL_TREE);
+ }
+ else
+ {
+ enum insn_code icode = d->icode;
+ if (d->name == 0)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, bdesc_1arg[%ld] no name\n",
+ (long unsigned)i);
+
+ continue;
+ }
+
+ if (icode == CODE_FOR_nothing)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip unary %s (no code)\n",
+ d->name);
+
+ continue;
+ }
+
+ mode0 = insn_data[icode].operand[0].mode;
+ mode1 = insn_data[icode].operand[1].mode;
+
+ type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
+ d->code, d->name);
+ }
+
+ def_builtin (d->name, type, d->code);
+ }
+
+ /* Add the simple no-argument operators. */
+ d = bdesc_0arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
+ {
+ machine_mode mode0;
+ tree type;
+ HOST_WIDE_INT mask = d->mask;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip no-argument %s\n", d->name);
+ continue;
+ }
+ if (rs6000_overloaded_builtin_p (d->code))
+ {
+ if (!opaque_ftype_opaque)
+ opaque_ftype_opaque
+ = build_function_type_list (opaque_V4SI_type_node, NULL_TREE);
+ type = opaque_ftype_opaque;
+ }
+ else
+ {
+ enum insn_code icode = d->icode;
+ if (d->name == 0)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, bdesc_0arg[%lu] no name\n",
+ (long unsigned) i);
+ continue;
+ }
+ if (icode == CODE_FOR_nothing)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr,
+ "rs6000_builtin, skip no-argument %s (no code)\n",
+ d->name);
+ continue;
+ }
+ mode0 = insn_data[icode].operand[0].mode;
+ type = builtin_function_type (mode0, VOIDmode, VOIDmode, VOIDmode,
+ d->code, d->name);
+ }
+ def_builtin (d->name, type, d->code);
+ }
+}
+
+/* Return the internal arg pointer used for function incoming
+ arguments. When -fsplit-stack, the arg pointer is r12 so we need
+ to copy it to a pseudo in order for it to be preserved over calls
+ and suchlike. We'd really like to use a pseudo here for the
+ internal arg pointer but data-flow analysis is not prepared to
+ accept pseudos as live at the beginning of a function. */
+
+rtx
+rs6000_internal_arg_pointer (void)
+{
+ if (flag_split_stack
+ && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl))
+ == NULL))
+
+ {
+ if (cfun->machine->split_stack_arg_pointer == NULL_RTX)
+ {
+ rtx pat;
+
+ cfun->machine->split_stack_arg_pointer = gen_reg_rtx (Pmode);
+ REG_POINTER (cfun->machine->split_stack_arg_pointer) = 1;
+
+ /* Put the pseudo initialization right after the note at the
+ beginning of the function. */
+ pat = gen_rtx_SET (cfun->machine->split_stack_arg_pointer,
+ gen_rtx_REG (Pmode, 12));
+ push_topmost_sequence ();
+ emit_insn_after (pat, get_insns ());
+ pop_topmost_sequence ();
+ }
+ rtx ret = plus_constant (Pmode, cfun->machine->split_stack_arg_pointer,
+ FIRST_PARM_OFFSET (current_function_decl));
+ return copy_to_reg (ret);
+ }
+ return virtual_incoming_args_rtx;
+}
+
+
+/* A C compound statement that outputs the assembler code for a thunk
+ function, used to implement C++ virtual function calls with
+ multiple inheritance. The thunk acts as a wrapper around a virtual
+ function, adjusting the implicit object parameter before handing
+ control off to the real function.
+
+ First, emit code to add the integer DELTA to the location that
+ contains the incoming first argument. Assume that this argument
+ contains a pointer, and is the one used to pass the `this' pointer
+ in C++. This is the incoming argument *before* the function
+ prologue, e.g. `%o0' on a sparc. The addition must preserve the
+ values of all other incoming arguments.
+
+ After the addition, emit code to jump to FUNCTION, which is a
+ `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
+ not touch the return address. Hence returning from FUNCTION will
+ return to whoever called the current `thunk'.
+
+ The effect must be as if FUNCTION had been called directly with the
+ adjusted first argument. This macro is responsible for emitting
+ all of the code for a thunk function; output_function_prologue()
+ and output_function_epilogue() are not invoked.
+
+ The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
+ been extracted from it.) It might possibly be useful on some
+ targets, but probably not.
+
+ If you do not define this macro, the target-independent code in the
+ C++ frontend will generate a less efficient heavyweight thunk that
+ calls FUNCTION instead of jumping to it. The generic approach does
+ not support varargs. */
+
+void
+rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
+{
+ const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
+ rtx this_rtx, funexp;
+ rtx_insn *insn;
+
+ reload_completed = 1;
+ epilogue_completed = 1;
+
+ /* Mark the end of the (empty) prologue. */
+ emit_note (NOTE_INSN_PROLOGUE_END);
+
+ /* Find the "this" pointer. If the function returns a structure,
+ the structure return pointer is in r3. */
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
+ this_rtx = gen_rtx_REG (Pmode, 4);
+ else
+ this_rtx = gen_rtx_REG (Pmode, 3);
+
+ /* Apply the constant offset, if required. */
+ if (delta)
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
+
+ /* Apply the offset from the vtable, if required. */
+ if (vcall_offset)
+ {
+ rtx vcall_offset_rtx = GEN_INT (vcall_offset);
+ rtx tmp = gen_rtx_REG (Pmode, 12);
+
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
+ if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
+ {
+ emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
+ }
+ else
+ {
+ rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
+
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
+ }
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
+ }
+
+ /* Generate a tail call to the target function. */
+ if (!TREE_USED (function))
+ {
+ assemble_external (function);
+ TREE_USED (function) = 1;
+ }
+ funexp = XEXP (DECL_RTL (function), 0);
+ funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
+
+#if TARGET_MACHO
+ if (MACHOPIC_INDIRECT)
+ funexp = machopic_indirect_call_target (funexp);
+#endif
+
+ /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
+ generate sibcall RTL explicitly. */
+ insn = emit_call_insn (
+ gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (3,
+ gen_rtx_CALL (VOIDmode,
+ funexp, const0_rtx),
+ gen_rtx_USE (VOIDmode, const0_rtx),
+ simple_return_rtx)));
+ SIBLING_CALL_P (insn) = 1;
+ emit_barrier ();
+
+ /* Run just enough of rest_of_compilation to get the insns emitted.
+ There's not really enough bulk here to make other passes such as
+ instruction scheduling worth while. */
+ insn = get_insns ();
+ shorten_branches (insn);
+ assemble_start_function (thunk_fndecl, fnname);
+ final_start_function (insn, file, 1);
+ final (insn, file, 1);
+ final_end_function ();
+ assemble_end_function (thunk_fndecl, fnname);
+
+ reload_completed = 0;
+ epilogue_completed = 0;
+}
+
+#include "gt-rs6000-call.h"
diff --git a/gcc/config/rs6000/rs6000-internal.h b/gcc/config/rs6000/rs6000-internal.h
index f69fa5d..0da040c 100644
--- a/gcc/config/rs6000/rs6000-internal.h
+++ b/gcc/config/rs6000/rs6000-internal.h
@@ -92,7 +92,6 @@ extern void rs6000_emit_prologue_components (sbitmap components);
extern void rs6000_emit_epilogue_components (sbitmap components);
extern void rs6000_set_handled_components (sbitmap components);
extern rs6000_stack_t * rs6000_stack_info (void);
-extern rtx create_TOC_reference (rtx symbol, rtx largetoc_reg);
extern rtx rs6000_got_sym (void);
extern struct machine_function *rs6000_init_machine_status (void);
extern bool save_reg_p (int reg);
@@ -100,6 +99,7 @@ extern const char * rs6000_machine_from_flags (void);
extern void emit_asm_machine (void);
extern bool rs6000_global_entry_point_prologue_needed_p (void);
extern bool rs6000_keep_leaf_when_profiled (void);
+extern void rs6000_live_on_entry (bitmap regs);
/* Return true if the OFFSET is valid for the quad address instructions that
use d-form (register + offset) addressing. */
@@ -124,4 +124,76 @@ extern vec<branch_island, va_gc> *branch_islands;
#endif
+/* Declare functions in rs6000-call.c or called in rs6000.c
+ from rs6000-call.c */
+extern int rs6000_darwin64_struct_check_p (machine_mode mode, const_tree type);
+extern bool rs6000_discover_homogeneous_aggregate (machine_mode mode,
+ const_tree type,
+ machine_mode *elt_mode,
+ int *n_elts);
+extern void rs6000_output_mi_thunk (FILE *file,
+ tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset,
+ tree function);
+extern bool rs6000_output_addr_const_extra (FILE *file, rtx x);
+extern bool rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi);
+extern void rs6000_invalid_builtin (enum rs6000_builtins fncode);
+extern tree rs6000_build_builtin_va_list (void);
+extern void rs6000_va_start (tree valist, rtx nextarg);
+extern tree rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
+ gimple_seq *post_p);
+extern machine_mode rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
+ machine_mode mode,
+ int *punsignedp ATTRIBUTE_UNUSED,
+ const_tree, int);
+extern bool rs6000_return_in_memory (const_tree type,
+ const_tree fntype ATTRIBUTE_UNUSED);
+extern bool rs6000_return_in_msb (const_tree valtype);
+extern bool rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
+ machine_mode mode, const_tree type,
+ bool named ATTRIBUTE_UNUSED);
+extern void setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
+ tree type, int *pretend_size ATTRIBUTE_UNUSED,
+ int no_rtl);
+extern unsigned int rs6000_function_arg_boundary (machine_mode mode,
+ const_tree type);
+extern bool rs6000_must_pass_in_stack (machine_mode mode, const_tree type);
+extern int rs6000_arg_partial_bytes (cumulative_args_t cum_v,
+ machine_mode mode, tree type,
+ bool named);
+extern void rs6000_function_arg_advance (cumulative_args_t cum,
+ machine_mode mode,
+ const_tree type, bool named);
+extern pad_direction rs6000_function_arg_padding (machine_mode mode,
+ const_tree type);
+extern rtx rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
+ const_tree type, bool named);
+extern rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
+ bool, bool);
+extern rtx rs6000_internal_arg_pointer (void);
+
+extern void rs6000_init_builtins (void);
+extern tree rs6000_builtin_decl (unsigned code,
+ bool initialize_p ATTRIBUTE_UNUSED);
+extern rtx rs6000_expand_builtin (tree exp, rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED);
+extern tree rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
+ int n_args ATTRIBUTE_UNUSED,
+ tree *args ATTRIBUTE_UNUSED,
+ bool ignore ATTRIBUTE_UNUSED);
+
+#if TARGET_ELF
+extern bool rs6000_passes_ieee128;
+#endif
+extern bool rs6000_passes_float;
+extern bool rs6000_passes_long_double;
+extern bool rs6000_passes_vector;
+extern bool rs6000_returns_struct;
+extern bool cpu_builtin_p;
+extern GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
+extern GTY(()) tree altivec_builtin_mask_for_load;
+
#endif
diff --git a/gcc/config/rs6000/rs6000-logue.c b/gcc/config/rs6000/rs6000-logue.c
index 3fe6230..ebfe533 100644
--- a/gcc/config/rs6000/rs6000-logue.c
+++ b/gcc/config/rs6000/rs6000-logue.c
@@ -1406,41 +1406,6 @@ uses_TOC (void)
}
#endif
-rtx
-create_TOC_reference (rtx symbol, rtx largetoc_reg)
-{
- rtx tocrel, tocreg, hi;
-
- if (TARGET_DEBUG_ADDR)
- {
- if (SYMBOL_REF_P (symbol))
- fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
- XSTR (symbol, 0));
- else
- {
- fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
- GET_RTX_NAME (GET_CODE (symbol)));
- debug_rtx (symbol);
- }
- }
-
- if (!can_create_pseudo_p ())
- df_set_regs_ever_live (TOC_REGISTER, true);
-
- tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
- tocrel = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, symbol, tocreg), UNSPEC_TOCREL);
- if (TARGET_CMODEL == CMODEL_SMALL || can_create_pseudo_p ())
- return tocrel;
-
- hi = gen_rtx_HIGH (Pmode, copy_rtx (tocrel));
- if (largetoc_reg != NULL)
- {
- emit_move_insn (largetoc_reg, hi);
- hi = largetoc_reg;
- }
- return gen_rtx_LO_SUM (Pmode, hi, tocrel);
-}
-
/* Issue assembly directives that create a reference to the given DWARF
FRAME_TABLE_LABEL from the current function section. */
void
@@ -5100,24 +5065,11 @@ macho_branch_islands (void)
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
if (flag_pic)
{
- if (TARGET_LINK_STACK)
- {
- char name[32];
- get_ppc476_thunk_name (name);
- strcat (tmp_buf, ":\n\tmflr r0\n\tbl ");
- strcat (tmp_buf, name);
- strcat (tmp_buf, "\n");
- strcat (tmp_buf, label);
- strcat (tmp_buf, "_pic:\n\tmflr r11\n");
- }
- else
- {
- strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
- strcat (tmp_buf, label);
- strcat (tmp_buf, "_pic\n");
- strcat (tmp_buf, label);
- strcat (tmp_buf, "_pic:\n\tmflr r11\n");
- }
+ strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic\n");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic:\n\tmflr r11\n");
strcat (tmp_buf, "\taddis r11,r11,ha16(");
strcat (tmp_buf, name_buf);
@@ -5285,7 +5237,7 @@ rs6000_output_function_epilogue (FILE *file)
/* Language type. Unfortunately, there does not seem to be any
official way to discover the language being compiled, so we
use language_string.
- C is 0. Fortran is 1. Ada is 3. C++ is 9.
+ C is 0. Fortran is 1. Ada is 3. Modula-2 is 8. C++ is 9.
Java is 13. Objective-C is 14. Objective-C++ isn't assigned
a number, so for now use 9. LTO, Go, D, and JIT aren't assigned
numbers either, so for now use 0. */
@@ -5300,6 +5252,8 @@ rs6000_output_function_epilogue (FILE *file)
i = 1;
else if (! strcmp (language_string, "GNU Ada"))
i = 3;
+ else if (! strcmp (language_string, "GNU Modula-2"))
+ i = 8;
else if (lang_GNU_CXX ()
|| ! strcmp (language_string, "GNU Objective-C++"))
i = 9;
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index feb1250..06e40d9 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -154,7 +154,7 @@ extern align_flags rs6000_loop_align (rtx);
extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
extern bool rs6000_pcrel_p (struct function *);
extern bool rs6000_fndecl_pcrel_p (const_tree);
-extern bool rs6000_prefixed_address (rtx, machine_mode);
+extern bool rs6000_prefixed_address_mode_p (rtx, machine_mode);
#endif /* RTX_CODE */
#ifdef TREE_CODE
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index f59f3a9..edd8f2b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -84,10 +84,6 @@
/* This file should be included last. */
#include "target-def.h"
-#ifndef TARGET_NO_PROTOTYPE
-#define TARGET_NO_PROTOTYPE 0
-#endif
-
/* Set -mabi=ieeelongdouble on some old targets. In the future, power server
systems will also set long double to be IEEE 128-bit. AIX and Darwin
explicitly redefine TARGET_IEEEQUAD and TARGET_IEEEQUAD_DEFAULT to 0, so
@@ -102,10 +98,8 @@
#endif
#endif
-static pad_direction rs6000_function_arg_padding (machine_mode, const_tree);
-
/* Support targetm.vectorize.builtin_mask_for_load. */
-static GTY(()) tree altivec_builtin_mask_for_load;
+GTY(()) tree altivec_builtin_mask_for_load;
/* Set to nonzero once AIX common-mode calls have been defined. */
static GTY(()) int common_mode_defined;
@@ -129,7 +123,7 @@ scalar_int_mode rs6000_pmode;
floating point. We changed the default C++ mangling for these types and we
may want to generate a weak alias of the old mangling (U10__float128) to the
new mangling (u9__ieee128). */
-static bool rs6000_passes_ieee128;
+bool rs6000_passes_ieee128 = false;
#endif
/* Generate the manged name (i.e. U10__float128) used in GCC 8.1, and not the
@@ -148,12 +142,12 @@ unsigned rs6000_pointer_size;
Tag_GNU_Power_ABI_FP .gnu.attributes value this flag controls
should be set for soft-float values passed in gprs and ieee128
values passed in vsx registers. */
-static bool rs6000_passes_float;
-static bool rs6000_passes_long_double;
+bool rs6000_passes_float = false;
+bool rs6000_passes_long_double = false;
/* Flag whether vector values have been passed/returned. */
-static bool rs6000_passes_vector;
+bool rs6000_passes_vector = false;
/* Flag whether small (<= 8 byte) structures have been returned. */
-static bool rs6000_returns_struct;
+bool rs6000_returns_struct = false;
#endif
/* Value is TRUE if register/mode pair is acceptable. */
@@ -193,14 +187,6 @@ static GTY(()) section *sdata2_section;
extern GTY(()) section *toc_section;
section *toc_section = 0;
-struct builtin_description
-{
- const HOST_WIDE_INT mask;
- const enum insn_code icode;
- const char *const name;
- const enum rs6000_builtins code;
-};
-
/* Describe the vector unit used for modes. */
enum rs6000_vector rs6000_vector_unit[NUM_MACHINE_MODES];
enum rs6000_vector rs6000_vector_mem[NUM_MACHINE_MODES];
@@ -213,7 +199,7 @@ enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
int rs6000_vector_align[NUM_MACHINE_MODES];
/* Map selected modes to types for builtins. */
-static GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
+GTY(()) tree builtin_mode_to_type[MAX_MACHINE_MODE][2];
/* What modes to automatically generate reciprocal divide estimate (fre) and
reciprocal sqrt (frsqrte) for. */
@@ -263,82 +249,6 @@ static struct
{ "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
};
-/* Used by __builtin_cpu_is(), mapping from PLATFORM names to values. */
-static const struct
-{
- const char *cpu;
- unsigned int cpuid;
-} cpu_is_info[] = {
- { "power9", PPC_PLATFORM_POWER9 },
- { "power8", PPC_PLATFORM_POWER8 },
- { "power7", PPC_PLATFORM_POWER7 },
- { "power6x", PPC_PLATFORM_POWER6X },
- { "power6", PPC_PLATFORM_POWER6 },
- { "power5+", PPC_PLATFORM_POWER5_PLUS },
- { "power5", PPC_PLATFORM_POWER5 },
- { "ppc970", PPC_PLATFORM_PPC970 },
- { "power4", PPC_PLATFORM_POWER4 },
- { "ppca2", PPC_PLATFORM_PPCA2 },
- { "ppc476", PPC_PLATFORM_PPC476 },
- { "ppc464", PPC_PLATFORM_PPC464 },
- { "ppc440", PPC_PLATFORM_PPC440 },
- { "ppc405", PPC_PLATFORM_PPC405 },
- { "ppc-cell-be", PPC_PLATFORM_CELL_BE }
-};
-
-/* Used by __builtin_cpu_supports(), mapping from HWCAP names to masks. */
-static const struct
-{
- const char *hwcap;
- int mask;
- unsigned int id;
-} cpu_supports_info[] = {
- /* AT_HWCAP masks. */
- { "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0 },
- { "altivec", PPC_FEATURE_HAS_ALTIVEC, 0 },
- { "arch_2_05", PPC_FEATURE_ARCH_2_05, 0 },
- { "arch_2_06", PPC_FEATURE_ARCH_2_06, 0 },
- { "archpmu", PPC_FEATURE_PERFMON_COMPAT, 0 },
- { "booke", PPC_FEATURE_BOOKE, 0 },
- { "cellbe", PPC_FEATURE_CELL_BE, 0 },
- { "dfp", PPC_FEATURE_HAS_DFP, 0 },
- { "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE, 0 },
- { "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE, 0 },
- { "fpu", PPC_FEATURE_HAS_FPU, 0 },
- { "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, 0 },
- { "mmu", PPC_FEATURE_HAS_MMU, 0 },
- { "notb", PPC_FEATURE_NO_TB, 0 },
- { "pa6t", PPC_FEATURE_PA6T, 0 },
- { "power4", PPC_FEATURE_POWER4, 0 },
- { "power5", PPC_FEATURE_POWER5, 0 },
- { "power5+", PPC_FEATURE_POWER5_PLUS, 0 },
- { "power6x", PPC_FEATURE_POWER6_EXT, 0 },
- { "ppc32", PPC_FEATURE_32, 0 },
- { "ppc601", PPC_FEATURE_601_INSTR, 0 },
- { "ppc64", PPC_FEATURE_64, 0 },
- { "ppcle", PPC_FEATURE_PPC_LE, 0 },
- { "smt", PPC_FEATURE_SMT, 0 },
- { "spe", PPC_FEATURE_HAS_SPE, 0 },
- { "true_le", PPC_FEATURE_TRUE_LE, 0 },
- { "ucache", PPC_FEATURE_UNIFIED_CACHE, 0 },
- { "vsx", PPC_FEATURE_HAS_VSX, 0 },
-
- /* AT_HWCAP2 masks. */
- { "arch_2_07", PPC_FEATURE2_ARCH_2_07, 1 },
- { "dscr", PPC_FEATURE2_HAS_DSCR, 1 },
- { "ebb", PPC_FEATURE2_HAS_EBB, 1 },
- { "htm", PPC_FEATURE2_HAS_HTM, 1 },
- { "htm-nosc", PPC_FEATURE2_HTM_NOSC, 1 },
- { "htm-no-suspend", PPC_FEATURE2_HTM_NO_SUSPEND, 1 },
- { "isel", PPC_FEATURE2_HAS_ISEL, 1 },
- { "tar", PPC_FEATURE2_HAS_TAR, 1 },
- { "vcrypto", PPC_FEATURE2_HAS_VEC_CRYPTO, 1 },
- { "arch_3_00", PPC_FEATURE2_ARCH_3_00, 1 },
- { "ieee128", PPC_FEATURE2_HAS_IEEE128, 1 },
- { "darn", PPC_FEATURE2_DARN, 1 },
- { "scv", PPC_FEATURE2_SCV, 1 }
-};
-
/* On PowerPC, we have a limited number of target clones that we care about
which means we can use an array to hold the options, rather than having more
elaborate data structures to identify each possible variation. Order the
@@ -374,7 +284,7 @@ static const struct clone_map rs6000_clone_map[CLONE_MAX] = {
const char *tcb_verification_symbol = "__parse_hwcap_and_convert_at_platform";
/* True if we have expanded a CPU builtin. */
-bool cpu_builtin_p;
+bool cpu_builtin_p = false;
/* Pointer to function (in rs6000-c.c) that can define or undefine target
macros that have changed. Languages that don't support the preprocessor
@@ -1189,67 +1099,6 @@ struct processor_costs ppca2_cost = {
0, /* SF->DF convert */
};
-
-/* Table that classifies rs6000 builtin functions (pure, const, etc.). */
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE) \
- { NAME, ICODE, MASK, ATTR },
-
-struct rs6000_builtin_info_type {
- const char *name;
- const enum insn_code icode;
- const HOST_WIDE_INT mask;
- const unsigned attr;
-};
-
-static const struct rs6000_builtin_info_type rs6000_builtin_info[] =
-{
-#include "rs6000-builtin.def"
-};
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
/* Support for -mveclibabi=<xxx> to control which vector library to use. */
static tree (*rs6000_veclib_handler) (combined_fn, tree, tree);
@@ -1275,17 +1124,9 @@ static bool set_to_load_agen (rtx_insn *,rtx_insn *);
static bool insn_terminates_group_p (rtx_insn *, enum group_termination);
static bool insn_must_be_first_in_group (rtx_insn *);
static bool insn_must_be_last_in_group (rtx_insn *);
-static void altivec_init_builtins (void);
-static tree builtin_function_type (machine_mode, machine_mode,
- machine_mode, machine_mode,
- enum rs6000_builtins, const char *name);
-static void rs6000_common_init_builtins (void);
-static void htm_init_builtins (void);
int easy_vector_constant (rtx, machine_mode);
static rtx rs6000_debug_legitimize_address (rtx, rtx, machine_mode);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
-static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree,
- bool, bool);
#if TARGET_MACHO
static tree get_prev_label (tree);
#endif
@@ -1306,7 +1147,6 @@ static bool rs6000_debug_secondary_memory_needed (machine_mode,
static bool rs6000_debug_can_change_mode_class (machine_mode,
machine_mode,
reg_class_t);
-static rtx rs6000_internal_arg_pointer (void);
static bool (*rs6000_mode_dependent_address_ptr) (const_rtx)
= rs6000_mode_dependent_address;
@@ -1333,7 +1173,6 @@ static bool rs6000_secondary_reload_move (enum rs6000_reg_type,
secondary_reload_info *,
bool);
rtl_opt_pass *make_pass_analyze_swaps (gcc::context*);
-static tree rs6000_fold_builtin (tree, int, tree *, bool);
/* Hash table stuff for keeping track of TOC entries. */
@@ -1354,22 +1193,6 @@ struct toc_hasher : ggc_ptr_hash<toc_hash_struct>
static GTY (()) hash_table<toc_hasher> *toc_hash_table;
-/* Hash table to keep track of the argument types for builtin functions. */
-
-struct GTY((for_user)) builtin_hash_struct
-{
- tree type;
- machine_mode mode[4]; /* return value + 3 arguments. */
- unsigned char uns_p[4]; /* and whether the types are unsigned. */
-};
-
-struct builtin_hasher : ggc_ptr_hash<builtin_hash_struct>
-{
- static hashval_t hash (builtin_hash_struct *);
- static bool equal (builtin_hash_struct *, builtin_hash_struct *);
-};
-
-static GTY (()) hash_table<builtin_hasher> *builtin_hash_table;
/* Default register names. */
@@ -4333,6 +4156,16 @@ rs6000_option_override_internal (bool global_init_p)
SUB3TARGET_OVERRIDE_OPTIONS;
#endif
+ /* -mpcrel requires -mcmodel=medium, but we can't check TARGET_CMODEL until
+ after the subtarget override options are done. */
+ if (TARGET_PCREL && TARGET_CMODEL != CMODEL_MEDIUM)
+ {
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_PCREL) != 0)
+ error ("%qs requires %qs", "-mpcrel", "-mcmodel=medium");
+
+ rs6000_isa_flags &= ~OPTION_MASK_PCREL;
+ }
+
if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
rs6000_print_isa_options (stderr, 0, "after subtarget", rs6000_isa_flags);
@@ -5547,22 +5380,26 @@ const char *rs6000_machine;
const char *
rs6000_machine_from_flags (void)
{
- if ((rs6000_isa_flags & (ISA_FUTURE_MASKS_SERVER & ~ISA_3_0_MASKS_SERVER))
- != 0)
+ HOST_WIDE_INT flags = rs6000_isa_flags;
+
+ /* Disable the flags that should never influence the .machine selection. */
+ flags &= ~(OPTION_MASK_PPC_GFXOPT | OPTION_MASK_PPC_GPOPT);
+
+ if ((flags & (ISA_FUTURE_MASKS_SERVER & ~ISA_3_0_MASKS_SERVER)) != 0)
return "future";
- if ((rs6000_isa_flags & (ISA_3_0_MASKS_SERVER & ~ISA_2_7_MASKS_SERVER)) != 0)
+ if ((flags & (ISA_3_0_MASKS_SERVER & ~ISA_2_7_MASKS_SERVER)) != 0)
return "power9";
- if ((rs6000_isa_flags & (ISA_2_7_MASKS_SERVER & ~ISA_2_6_MASKS_SERVER)) != 0)
+ if ((flags & (ISA_2_7_MASKS_SERVER & ~ISA_2_6_MASKS_SERVER)) != 0)
return "power8";
- if ((rs6000_isa_flags & (ISA_2_6_MASKS_SERVER & ~ISA_2_5_MASKS_SERVER)) != 0)
+ if ((flags & (ISA_2_6_MASKS_SERVER & ~ISA_2_5_MASKS_SERVER)) != 0)
return "power7";
- if ((rs6000_isa_flags & (ISA_2_5_MASKS_SERVER & ~ISA_2_4_MASKS)) != 0)
+ if ((flags & (ISA_2_5_MASKS_SERVER & ~ISA_2_4_MASKS)) != 0)
return "power6";
- if ((rs6000_isa_flags & (ISA_2_4_MASKS & ~ISA_2_1_MASKS)) != 0)
+ if ((flags & (ISA_2_4_MASKS & ~ISA_2_1_MASKS)) != 0)
return "power5";
- if ((rs6000_isa_flags & ISA_2_1_MASKS) != 0)
+ if ((flags & ISA_2_1_MASKS) != 0)
return "power4";
- if ((rs6000_isa_flags & OPTION_MASK_POWERPC64) != 0)
+ if ((flags & OPTION_MASK_POWERPC64) != 0)
return "ppc64";
return "ppc";
}
@@ -5640,9 +5477,7 @@ rs6000_file_start (void)
#ifdef USING_ELFOS_H
rs6000_machine = rs6000_machine_from_flags ();
- if (!(rs6000_default_cpu && rs6000_default_cpu[0])
- && !global_options_set.x_rs6000_cpu_index)
- emit_asm_machine ();
+ emit_asm_machine ();
#endif
if (DEFAULT_ABI == ABI_ELFv2)
@@ -7731,6 +7566,47 @@ constant_pool_expr_p (rtx op)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (base), Pmode));
}
+/* Create a TOC reference for symbol_ref SYMBOL. If LARGETOC_REG is non-null,
+ use that as the register to put the HIGH value into if register allocation
+ is already done. */
+
+rtx
+create_TOC_reference (rtx symbol, rtx largetoc_reg)
+{
+ rtx tocrel, tocreg, hi;
+
+ gcc_assert (TARGET_TOC);
+
+ if (TARGET_DEBUG_ADDR)
+ {
+ if (SYMBOL_REF_P (symbol))
+ fprintf (stderr, "\ncreate_TOC_reference, (symbol_ref %s)\n",
+ XSTR (symbol, 0));
+ else
+ {
+ fprintf (stderr, "\ncreate_TOC_reference, code %s:\n",
+ GET_RTX_NAME (GET_CODE (symbol)));
+ debug_rtx (symbol);
+ }
+ }
+
+ if (!can_create_pseudo_p ())
+ df_set_regs_ever_live (TOC_REGISTER, true);
+
+ tocreg = gen_rtx_REG (Pmode, TOC_REGISTER);
+ tocrel = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, symbol, tocreg), UNSPEC_TOCREL);
+ if (TARGET_CMODEL == CMODEL_SMALL || can_create_pseudo_p ())
+ return tocrel;
+
+ hi = gen_rtx_HIGH (Pmode, copy_rtx (tocrel));
+ if (largetoc_reg != NULL)
+ {
+ emit_move_insn (largetoc_reg, hi);
+ hi = largetoc_reg;
+ }
+ return gen_rtx_LO_SUM (Pmode, hi, tocrel);
+}
+
/* These are only used to pass through from print_operand/print_operand_address
to rs6000_output_addr_const_extra over the intervening function
output_addr_const which is not target code. */
@@ -8080,7 +7956,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
#endif
)
&& TARGET_32BIT
- && TARGET_NO_TOC
+ && TARGET_NO_TOC_OR_PCREL
&& !flag_pic
&& !CONST_INT_P (x)
&& !CONST_WIDE_INT_P (x)
@@ -9770,7 +9646,7 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
}
if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_NO_TOC
+ && TARGET_NO_TOC_OR_PCREL
&& ! flag_pic
&& mode == Pmode
&& CONSTANT_P (operands[1])
@@ -9914,7744 +9790,6 @@ rs6000_emit_move (rtx dest, rtx source, machine_mode mode)
emit_insn (gen_rtx_SET (operands[0], operands[1]));
}
-/* Nonzero if we can use a floating-point register to pass this arg. */
-#define USE_FP_FOR_ARG_P(CUM,MODE) \
- (SCALAR_FLOAT_MODE_NOT_VECTOR_P (MODE) \
- && (CUM)->fregno <= FP_ARG_MAX_REG \
- && TARGET_HARD_FLOAT)
-
-/* Nonzero if we can use an AltiVec register to pass this arg. */
-#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,NAMED) \
- (ALTIVEC_OR_VSX_VECTOR_MODE (MODE) \
- && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
- && TARGET_ALTIVEC_ABI \
- && (NAMED))
-
-/* Walk down the type tree of TYPE counting consecutive base elements.
- If *MODEP is VOIDmode, then set it to the first valid floating point
- or vector type. If a non-floating point or vector type is found, or
- if a floating point or vector type that doesn't match a non-VOIDmode
- *MODEP is found, then return -1, otherwise return the count in the
- sub-tree. */
-
-static int
-rs6000_aggregate_candidate (const_tree type, machine_mode *modep)
-{
- machine_mode mode;
- HOST_WIDE_INT size;
-
- switch (TREE_CODE (type))
- {
- case REAL_TYPE:
- mode = TYPE_MODE (type);
- if (!SCALAR_FLOAT_MODE_P (mode))
- return -1;
-
- if (*modep == VOIDmode)
- *modep = mode;
-
- if (*modep == mode)
- return 1;
-
- break;
-
- case COMPLEX_TYPE:
- mode = TYPE_MODE (TREE_TYPE (type));
- if (!SCALAR_FLOAT_MODE_P (mode))
- return -1;
-
- if (*modep == VOIDmode)
- *modep = mode;
-
- if (*modep == mode)
- return 2;
-
- break;
-
- case VECTOR_TYPE:
- if (!TARGET_ALTIVEC_ABI || !TARGET_ALTIVEC)
- return -1;
-
- /* Use V4SImode as representative of all 128-bit vector types. */
- size = int_size_in_bytes (type);
- switch (size)
- {
- case 16:
- mode = V4SImode;
- break;
- default:
- return -1;
- }
-
- if (*modep == VOIDmode)
- *modep = mode;
-
- /* Vector modes are considered to be opaque: two vectors are
- equivalent for the purposes of being homogeneous aggregates
- if they are the same size. */
- if (*modep == mode)
- return 1;
-
- break;
-
- case ARRAY_TYPE:
- {
- int count;
- tree index = TYPE_DOMAIN (type);
-
- /* Can't handle incomplete types nor sizes that are not
- fixed. */
- if (!COMPLETE_TYPE_P (type)
- || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return -1;
-
- count = rs6000_aggregate_candidate (TREE_TYPE (type), modep);
- if (count == -1
- || !index
- || !TYPE_MAX_VALUE (index)
- || !tree_fits_uhwi_p (TYPE_MAX_VALUE (index))
- || !TYPE_MIN_VALUE (index)
- || !tree_fits_uhwi_p (TYPE_MIN_VALUE (index))
- || count < 0)
- return -1;
-
- count *= (1 + tree_to_uhwi (TYPE_MAX_VALUE (index))
- - tree_to_uhwi (TYPE_MIN_VALUE (index)));
-
- /* There must be no padding. */
- if (wi::to_wide (TYPE_SIZE (type))
- != count * GET_MODE_BITSIZE (*modep))
- return -1;
-
- return count;
- }
-
- case RECORD_TYPE:
- {
- int count = 0;
- int sub_count;
- tree field;
-
- /* Can't handle incomplete types nor sizes that are not
- fixed. */
- if (!COMPLETE_TYPE_P (type)
- || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return -1;
-
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
- if (sub_count < 0)
- return -1;
- count += sub_count;
- }
-
- /* There must be no padding. */
- if (wi::to_wide (TYPE_SIZE (type))
- != count * GET_MODE_BITSIZE (*modep))
- return -1;
-
- return count;
- }
-
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- {
- /* These aren't very interesting except in a degenerate case. */
- int count = 0;
- int sub_count;
- tree field;
-
- /* Can't handle incomplete types nor sizes that are not
- fixed. */
- if (!COMPLETE_TYPE_P (type)
- || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return -1;
-
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- sub_count = rs6000_aggregate_candidate (TREE_TYPE (field), modep);
- if (sub_count < 0)
- return -1;
- count = count > sub_count ? count : sub_count;
- }
-
- /* There must be no padding. */
- if (wi::to_wide (TYPE_SIZE (type))
- != count * GET_MODE_BITSIZE (*modep))
- return -1;
-
- return count;
- }
-
- default:
- break;
- }
-
- return -1;
-}
-
-/* If an argument, whose type is described by TYPE and MODE, is a homogeneous
- float or vector aggregate that shall be passed in FP/vector registers
- according to the ELFv2 ABI, return the homogeneous element mode in
- *ELT_MODE and the number of elements in *N_ELTS, and return TRUE.
-
- Otherwise, set *ELT_MODE to MODE and *N_ELTS to 1, and return FALSE. */
-
-static bool
-rs6000_discover_homogeneous_aggregate (machine_mode mode, const_tree type,
- machine_mode *elt_mode,
- int *n_elts)
-{
- /* Note that we do not accept complex types at the top level as
- homogeneous aggregates; these types are handled via the
- targetm.calls.split_complex_arg mechanism. Complex types
- can be elements of homogeneous aggregates, however. */
- if (TARGET_HARD_FLOAT && DEFAULT_ABI == ABI_ELFv2 && type
- && AGGREGATE_TYPE_P (type))
- {
- machine_mode field_mode = VOIDmode;
- int field_count = rs6000_aggregate_candidate (type, &field_mode);
-
- if (field_count > 0)
- {
- int reg_size = ALTIVEC_OR_VSX_VECTOR_MODE (field_mode) ? 16 : 8;
- int field_size = ROUND_UP (GET_MODE_SIZE (field_mode), reg_size);
-
- /* The ELFv2 ABI allows homogeneous aggregates to occupy
- up to AGGR_ARG_NUM_REG registers. */
- if (field_count * field_size <= AGGR_ARG_NUM_REG * reg_size)
- {
- if (elt_mode)
- *elt_mode = field_mode;
- if (n_elts)
- *n_elts = field_count;
- return true;
- }
- }
- }
-
- if (elt_mode)
- *elt_mode = mode;
- if (n_elts)
- *n_elts = 1;
- return false;
-}
-
-/* Return a nonzero value to say to return the function value in
- memory, just as large structures are always returned. TYPE will be
- the data type of the value, and FNTYPE will be the type of the
- function doing the returning, or @code{NULL} for libcalls.
-
- The AIX ABI for the RS/6000 specifies that all structures are
- returned in memory. The Darwin ABI does the same.
-
- For the Darwin 64 Bit ABI, a function result can be returned in
- registers or in memory, depending on the size of the return data
- type. If it is returned in registers, the value occupies the same
- registers as it would if it were the first and only function
- argument. Otherwise, the function places its result in memory at
- the location pointed to by GPR3.
-
- The SVR4 ABI specifies that structures <= 8 bytes are returned in r3/r4,
- but a draft put them in memory, and GCC used to implement the draft
- instead of the final standard. Therefore, aix_struct_return
- controls this instead of DEFAULT_ABI; V.4 targets needing backward
- compatibility can change DRAFT_V4_STRUCT_RET to override the
- default, and -m switches get the final word. See
- rs6000_option_override_internal for more details.
-
- The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
- long double support is enabled. These values are returned in memory.
-
- int_size_in_bytes returns -1 for variable size objects, which go in
- memory always. The cast to unsigned makes -1 > 8. */
-
-static bool
-rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
-{
- /* For the Darwin64 ABI, test if we can fit the return value in regs. */
- if (TARGET_MACHO
- && rs6000_darwin64_abi
- && TREE_CODE (type) == RECORD_TYPE
- && int_size_in_bytes (type) > 0)
- {
- CUMULATIVE_ARGS valcum;
- rtx valret;
-
- valcum.words = 0;
- valcum.fregno = FP_ARG_MIN_REG;
- valcum.vregno = ALTIVEC_ARG_MIN_REG;
- /* Do a trial code generation as if this were going to be passed
- as an argument; if any part goes in memory, we return NULL. */
- valret = rs6000_darwin64_record_arg (&valcum, type, true, true);
- if (valret)
- return false;
- /* Otherwise fall through to more conventional ABI rules. */
- }
-
- /* The ELFv2 ABI returns homogeneous VFP aggregates in registers */
- if (rs6000_discover_homogeneous_aggregate (TYPE_MODE (type), type,
- NULL, NULL))
- return false;
-
- /* The ELFv2 ABI returns aggregates up to 16B in registers */
- if (DEFAULT_ABI == ABI_ELFv2 && AGGREGATE_TYPE_P (type)
- && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) <= 16)
- return false;
-
- if (AGGREGATE_TYPE_P (type)
- && (aix_struct_return
- || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
- return true;
-
- /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
- modes only exist for GCC vector types if -maltivec. */
- if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
- && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
- return false;
-
- /* Return synthetic vectors in memory. */
- if (TREE_CODE (type) == VECTOR_TYPE
- && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
- {
- static bool warned_for_return_big_vectors = false;
- if (!warned_for_return_big_vectors)
- {
- warning (OPT_Wpsabi, "GCC vector returned by reference: "
- "non-standard ABI extension with no compatibility "
- "guarantee");
- warned_for_return_big_vectors = true;
- }
- return true;
- }
-
- if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD
- && FLOAT128_IEEE_P (TYPE_MODE (type)))
- return true;
-
- return false;
-}
-
-/* Specify whether values returned in registers should be at the most
- significant end of a register. We want aggregates returned by
- value to match the way aggregates are passed to functions. */
-
-static bool
-rs6000_return_in_msb (const_tree valtype)
-{
- return (DEFAULT_ABI == ABI_ELFv2
- && BYTES_BIG_ENDIAN
- && AGGREGATE_TYPE_P (valtype)
- && (rs6000_function_arg_padding (TYPE_MODE (valtype), valtype)
- == PAD_UPWARD));
-}
-
-#ifdef HAVE_AS_GNU_ATTRIBUTE
-/* Return TRUE if a call to function FNDECL may be one that
- potentially affects the function calling ABI of the object file. */
-
-static bool
-call_ABI_of_interest (tree fndecl)
-{
- if (rs6000_gnu_attr && symtab->state == EXPANSION)
- {
- struct cgraph_node *c_node;
-
- /* Libcalls are always interesting. */
- if (fndecl == NULL_TREE)
- return true;
-
- /* Any call to an external function is interesting. */
- if (DECL_EXTERNAL (fndecl))
- return true;
-
- /* Interesting functions that we are emitting in this object file. */
- c_node = cgraph_node::get (fndecl);
- c_node = c_node->ultimate_alias_target ();
- return !c_node->only_called_directly_p ();
- }
- return false;
-}
-#endif
-
-/* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
- For a library call, FNTYPE is 0 and RETURN_MODE the return value mode.
-
- For incoming args we set the number of arguments in the prototype large
- so we never return a PARALLEL. */
-
-void
-init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
- rtx libname ATTRIBUTE_UNUSED, int incoming,
- int libcall, int n_named_args,
- tree fndecl,
- machine_mode return_mode ATTRIBUTE_UNUSED)
-{
- static CUMULATIVE_ARGS zero_cumulative;
-
- *cum = zero_cumulative;
- cum->words = 0;
- cum->fregno = FP_ARG_MIN_REG;
- cum->vregno = ALTIVEC_ARG_MIN_REG;
- cum->prototype = (fntype && prototype_p (fntype));
- cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
- ? CALL_LIBCALL : CALL_NORMAL);
- cum->sysv_gregno = GP_ARG_MIN_REG;
- cum->stdarg = stdarg_p (fntype);
- cum->libcall = libcall;
-
- cum->nargs_prototype = 0;
- if (incoming || cum->prototype)
- cum->nargs_prototype = n_named_args;
-
- /* Check for a longcall attribute. */
- if ((!fntype && rs6000_default_long_calls)
- || (fntype
- && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
- && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
- cum->call_cookie |= CALL_LONG;
- else if (DEFAULT_ABI != ABI_DARWIN)
- {
- bool is_local = (fndecl
- && !DECL_EXTERNAL (fndecl)
- && !DECL_WEAK (fndecl)
- && (*targetm.binds_local_p) (fndecl));
- if (is_local)
- ;
- else if (flag_plt)
- {
- if (fntype
- && lookup_attribute ("noplt", TYPE_ATTRIBUTES (fntype)))
- cum->call_cookie |= CALL_LONG;
- }
- else
- {
- if (!(fntype
- && lookup_attribute ("plt", TYPE_ATTRIBUTES (fntype))))
- cum->call_cookie |= CALL_LONG;
- }
- }
-
- if (TARGET_DEBUG_ARG)
- {
- fprintf (stderr, "\ninit_cumulative_args:");
- if (fntype)
- {
- tree ret_type = TREE_TYPE (fntype);
- fprintf (stderr, " ret code = %s,",
- get_tree_code_name (TREE_CODE (ret_type)));
- }
-
- if (cum->call_cookie & CALL_LONG)
- fprintf (stderr, " longcall,");
-
- fprintf (stderr, " proto = %d, nargs = %d\n",
- cum->prototype, cum->nargs_prototype);
- }
-
-#ifdef HAVE_AS_GNU_ATTRIBUTE
- if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4))
- {
- cum->escapes = call_ABI_of_interest (fndecl);
- if (cum->escapes)
- {
- tree return_type;
-
- if (fntype)
- {
- return_type = TREE_TYPE (fntype);
- return_mode = TYPE_MODE (return_type);
- }
- else
- return_type = lang_hooks.types.type_for_mode (return_mode, 0);
-
- if (return_type != NULL)
- {
- if (TREE_CODE (return_type) == RECORD_TYPE
- && TYPE_TRANSPARENT_AGGR (return_type))
- {
- return_type = TREE_TYPE (first_field (return_type));
- return_mode = TYPE_MODE (return_type);
- }
- if (AGGREGATE_TYPE_P (return_type)
- && ((unsigned HOST_WIDE_INT) int_size_in_bytes (return_type)
- <= 8))
- rs6000_returns_struct = true;
- }
- if (SCALAR_FLOAT_MODE_P (return_mode))
- {
- rs6000_passes_float = true;
- if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE || TARGET_64BIT)
- && (FLOAT128_IBM_P (return_mode)
- || FLOAT128_IEEE_P (return_mode)
- || (return_type != NULL
- && (TYPE_MAIN_VARIANT (return_type)
- == long_double_type_node))))
- rs6000_passes_long_double = true;
-
- /* Note if we passed or return a IEEE 128-bit type. We changed
- the mangling for these types, and we may need to make an alias
- with the old mangling. */
- if (FLOAT128_IEEE_P (return_mode))
- rs6000_passes_ieee128 = true;
- }
- if (ALTIVEC_OR_VSX_VECTOR_MODE (return_mode))
- rs6000_passes_vector = true;
- }
- }
-#endif
-
- if (fntype
- && !TARGET_ALTIVEC
- && TARGET_ALTIVEC_ABI
- && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
- {
- error ("cannot return value in vector register because"
- " altivec instructions are disabled, use %qs"
- " to enable them", "-maltivec");
- }
-}
-
-/* The mode the ABI uses for a word. This is not the same as word_mode
- for -m32 -mpowerpc64. This is used to implement various target hooks. */
-
-static scalar_int_mode
-rs6000_abi_word_mode (void)
-{
- return TARGET_32BIT ? SImode : DImode;
-}
-
-/* Implement the TARGET_OFFLOAD_OPTIONS hook. */
-static char *
-rs6000_offload_options (void)
-{
- if (TARGET_64BIT)
- return xstrdup ("-foffload-abi=lp64");
- else
- return xstrdup ("-foffload-abi=ilp32");
-}
-
-/* On rs6000, function arguments are promoted, as are function return
- values. */
-
-static machine_mode
-rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
- machine_mode mode,
- int *punsignedp ATTRIBUTE_UNUSED,
- const_tree, int)
-{
- PROMOTE_MODE (mode, *punsignedp, type);
-
- return mode;
-}
-
-/* Return true if TYPE must be passed on the stack and not in registers. */
-
-static bool
-rs6000_must_pass_in_stack (machine_mode mode, const_tree type)
-{
- if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2 || TARGET_64BIT)
- return must_pass_in_stack_var_size (mode, type);
- else
- return must_pass_in_stack_var_size_or_pad (mode, type);
-}
-
-static inline bool
-is_complex_IBM_long_double (machine_mode mode)
-{
- return mode == ICmode || (mode == TCmode && FLOAT128_IBM_P (TCmode));
-}
-
-/* Whether ABI_V4 passes MODE args to a function in floating point
- registers. */
-
-static bool
-abi_v4_pass_in_fpr (machine_mode mode, bool named)
-{
- if (!TARGET_HARD_FLOAT)
- return false;
- if (mode == DFmode)
- return true;
- if (mode == SFmode && named)
- return true;
- /* ABI_V4 passes complex IBM long double in 8 gprs.
- Stupid, but we can't change the ABI now. */
- if (is_complex_IBM_long_double (mode))
- return false;
- if (FLOAT128_2REG_P (mode))
- return true;
- if (DECIMAL_FLOAT_MODE_P (mode))
- return true;
- return false;
-}
-
-/* Implement TARGET_FUNCTION_ARG_PADDING.
-
- For the AIX ABI structs are always stored left shifted in their
- argument slot. */
-
-static pad_direction
-rs6000_function_arg_padding (machine_mode mode, const_tree type)
-{
-#ifndef AGGREGATE_PADDING_FIXED
-#define AGGREGATE_PADDING_FIXED 0
-#endif
-#ifndef AGGREGATES_PAD_UPWARD_ALWAYS
-#define AGGREGATES_PAD_UPWARD_ALWAYS 0
-#endif
-
- if (!AGGREGATE_PADDING_FIXED)
- {
- /* GCC used to pass structures of the same size as integer types as
- if they were in fact integers, ignoring TARGET_FUNCTION_ARG_PADDING.
- i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
- passed padded downward, except that -mstrict-align further
- muddied the water in that multi-component structures of 2 and 4
- bytes in size were passed padded upward.
-
- The following arranges for best compatibility with previous
- versions of gcc, but removes the -mstrict-align dependency. */
- if (BYTES_BIG_ENDIAN)
- {
- HOST_WIDE_INT size = 0;
-
- if (mode == BLKmode)
- {
- if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
- size = int_size_in_bytes (type);
- }
- else
- size = GET_MODE_SIZE (mode);
-
- if (size == 1 || size == 2 || size == 4)
- return PAD_DOWNWARD;
- }
- return PAD_UPWARD;
- }
-
- if (AGGREGATES_PAD_UPWARD_ALWAYS)
- {
- if (type != 0 && AGGREGATE_TYPE_P (type))
- return PAD_UPWARD;
- }
-
- /* Fall back to the default. */
- return default_function_arg_padding (mode, type);
-}
-
-/* If defined, a C expression that gives the alignment boundary, in bits,
- of an argument with the specified mode and type. If it is not defined,
- PARM_BOUNDARY is used for all arguments.
-
- V.4 wants long longs and doubles to be double word aligned. Just
- testing the mode size is a boneheaded way to do this as it means
- that other types such as complex int are also double word aligned.
- However, we're stuck with this because changing the ABI might break
- existing library interfaces.
-
- Quadword align Altivec/VSX vectors.
- Quadword align large synthetic vector types. */
-
-static unsigned int
-rs6000_function_arg_boundary (machine_mode mode, const_tree type)
-{
- machine_mode elt_mode;
- int n_elts;
-
- rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
-
- if (DEFAULT_ABI == ABI_V4
- && (GET_MODE_SIZE (mode) == 8
- || (TARGET_HARD_FLOAT
- && !is_complex_IBM_long_double (mode)
- && FLOAT128_2REG_P (mode))))
- return 64;
- else if (FLOAT128_VECTOR_P (mode))
- return 128;
- else if (type && TREE_CODE (type) == VECTOR_TYPE
- && int_size_in_bytes (type) >= 8
- && int_size_in_bytes (type) < 16)
- return 64;
- else if (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode)
- || (type && TREE_CODE (type) == VECTOR_TYPE
- && int_size_in_bytes (type) >= 16))
- return 128;
-
- /* Aggregate types that need > 8 byte alignment are quadword-aligned
- in the parameter area in the ELFv2 ABI, and in the AIX ABI unless
- -mcompat-align-parm is used. */
- if (((DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm)
- || DEFAULT_ABI == ABI_ELFv2)
- && type && TYPE_ALIGN (type) > 64)
- {
- /* "Aggregate" means any AGGREGATE_TYPE except for single-element
- or homogeneous float/vector aggregates here. We already handled
- vector aggregates above, but still need to check for float here. */
- bool aggregate_p = (AGGREGATE_TYPE_P (type)
- && !SCALAR_FLOAT_MODE_P (elt_mode));
-
- /* We used to check for BLKmode instead of the above aggregate type
- check. Warn when this results in any difference to the ABI. */
- if (aggregate_p != (mode == BLKmode))
- {
- static bool warned;
- if (!warned && warn_psabi)
- {
- warned = true;
- inform (input_location,
- "the ABI of passing aggregates with %d-byte alignment"
- " has changed in GCC 5",
- (int) TYPE_ALIGN (type) / BITS_PER_UNIT);
- }
- }
-
- if (aggregate_p)
- return 128;
- }
-
- /* Similar for the Darwin64 ABI. Note that for historical reasons we
- implement the "aggregate type" check as a BLKmode check here; this
- means certain aggregate types are in fact not aligned. */
- if (TARGET_MACHO && rs6000_darwin64_abi
- && mode == BLKmode
- && type && TYPE_ALIGN (type) > 64)
- return 128;
-
- return PARM_BOUNDARY;
-}
-
-/* The offset in words to the start of the parameter save area. */
-
-static unsigned int
-rs6000_parm_offset (void)
-{
- return (DEFAULT_ABI == ABI_V4 ? 2
- : DEFAULT_ABI == ABI_ELFv2 ? 4
- : 6);
-}
-
-/* For a function parm of MODE and TYPE, return the starting word in
- the parameter area. NWORDS of the parameter area are already used. */
-
-static unsigned int
-rs6000_parm_start (machine_mode mode, const_tree type,
- unsigned int nwords)
-{
- unsigned int align;
-
- align = rs6000_function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
- return nwords + (-(rs6000_parm_offset () + nwords) & align);
-}
-
-/* Compute the size (in words) of a function argument. */
-
-static unsigned long
-rs6000_arg_size (machine_mode mode, const_tree type)
-{
- unsigned long size;
-
- if (mode != BLKmode)
- size = GET_MODE_SIZE (mode);
- else
- size = int_size_in_bytes (type);
-
- if (TARGET_32BIT)
- return (size + 3) >> 2;
- else
- return (size + 7) >> 3;
-}
-
-/* Use this to flush pending int fields. */
-
-static void
-rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
- HOST_WIDE_INT bitpos, int final)
-{
- unsigned int startbit, endbit;
- int intregs, intoffset;
-
- /* Handle the situations where a float is taking up the first half
- of the GPR, and the other half is empty (typically due to
- alignment restrictions). We can detect this by a 8-byte-aligned
- int field, or by seeing that this is the final flush for this
- argument. Count the word and continue on. */
- if (cum->floats_in_gpr == 1
- && (cum->intoffset % 64 == 0
- || (cum->intoffset == -1 && final)))
- {
- cum->words++;
- cum->floats_in_gpr = 0;
- }
-
- if (cum->intoffset == -1)
- return;
-
- intoffset = cum->intoffset;
- cum->intoffset = -1;
- cum->floats_in_gpr = 0;
-
- if (intoffset % BITS_PER_WORD != 0)
- {
- unsigned int bits = BITS_PER_WORD - intoffset % BITS_PER_WORD;
- if (!int_mode_for_size (bits, 0).exists ())
- {
- /* We couldn't find an appropriate mode, which happens,
- e.g., in packed structs when there are 3 bytes to load.
- Back intoffset back to the beginning of the word in this
- case. */
- intoffset = ROUND_DOWN (intoffset, BITS_PER_WORD);
- }
- }
-
- startbit = ROUND_DOWN (intoffset, BITS_PER_WORD);
- endbit = ROUND_UP (bitpos, BITS_PER_WORD);
- intregs = (endbit - startbit) / BITS_PER_WORD;
- cum->words += intregs;
- /* words should be unsigned. */
- if ((unsigned)cum->words < (endbit/BITS_PER_WORD))
- {
- int pad = (endbit/BITS_PER_WORD) - cum->words;
- cum->words += pad;
- }
-}
-
-/* The darwin64 ABI calls for us to recurse down through structs,
- looking for elements passed in registers. Unfortunately, we have
- to track int register count here also because of misalignments
- in powerpc alignment mode. */
-
-static void
-rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
- const_tree type,
- HOST_WIDE_INT startbitpos)
-{
- tree f;
-
- for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
- if (TREE_CODE (f) == FIELD_DECL)
- {
- HOST_WIDE_INT bitpos = startbitpos;
- tree ftype = TREE_TYPE (f);
- machine_mode mode;
- if (ftype == error_mark_node)
- continue;
- mode = TYPE_MODE (ftype);
-
- if (DECL_SIZE (f) != 0
- && tree_fits_uhwi_p (bit_position (f)))
- bitpos += int_bit_position (f);
-
- /* ??? FIXME: else assume zero offset. */
-
- if (TREE_CODE (ftype) == RECORD_TYPE)
- rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
- else if (USE_FP_FOR_ARG_P (cum, mode))
- {
- unsigned n_fpregs = (GET_MODE_SIZE (mode) + 7) >> 3;
- rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
- cum->fregno += n_fpregs;
- /* Single-precision floats present a special problem for
- us, because they are smaller than an 8-byte GPR, and so
- the structure-packing rules combined with the standard
- varargs behavior mean that we want to pack float/float
- and float/int combinations into a single register's
- space. This is complicated by the arg advance flushing,
- which works on arbitrarily large groups of int-type
- fields. */
- if (mode == SFmode)
- {
- if (cum->floats_in_gpr == 1)
- {
- /* Two floats in a word; count the word and reset
- the float count. */
- cum->words++;
- cum->floats_in_gpr = 0;
- }
- else if (bitpos % 64 == 0)
- {
- /* A float at the beginning of an 8-byte word;
- count it and put off adjusting cum->words until
- we see if a arg advance flush is going to do it
- for us. */
- cum->floats_in_gpr++;
- }
- else
- {
- /* The float is at the end of a word, preceded
- by integer fields, so the arg advance flush
- just above has already set cum->words and
- everything is taken care of. */
- }
- }
- else
- cum->words += n_fpregs;
- }
- else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, 1))
- {
- rs6000_darwin64_record_arg_advance_flush (cum, bitpos, 0);
- cum->vregno++;
- cum->words += 2;
- }
- else if (cum->intoffset == -1)
- cum->intoffset = bitpos;
- }
-}
-
-/* Check for an item that needs to be considered specially under the darwin 64
- bit ABI. These are record types where the mode is BLK or the structure is
- 8 bytes in size. */
-static int
-rs6000_darwin64_struct_check_p (machine_mode mode, const_tree type)
-{
- return rs6000_darwin64_abi
- && ((mode == BLKmode
- && TREE_CODE (type) == RECORD_TYPE
- && int_size_in_bytes (type) > 0)
- || (type && TREE_CODE (type) == RECORD_TYPE
- && int_size_in_bytes (type) == 8)) ? 1 : 0;
-}
-
-/* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.)
-
- Note that for args passed by reference, function_arg will be called
- with MODE and TYPE set to that of the pointer to the arg, not the arg
- itself. */
-
-static void
-rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
- const_tree type, bool named, int depth)
-{
- machine_mode elt_mode;
- int n_elts;
-
- rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
-
- /* Only tick off an argument if we're not recursing. */
- if (depth == 0)
- cum->nargs_prototype--;
-
-#ifdef HAVE_AS_GNU_ATTRIBUTE
- if (TARGET_ELF && (TARGET_64BIT || DEFAULT_ABI == ABI_V4)
- && cum->escapes)
- {
- if (SCALAR_FLOAT_MODE_P (mode))
- {
- rs6000_passes_float = true;
- if ((HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE || TARGET_64BIT)
- && (FLOAT128_IBM_P (mode)
- || FLOAT128_IEEE_P (mode)
- || (type != NULL
- && TYPE_MAIN_VARIANT (type) == long_double_type_node)))
- rs6000_passes_long_double = true;
-
- /* Note if we passed or return a IEEE 128-bit type. We changed the
- mangling for these types, and we may need to make an alias with
- the old mangling. */
- if (FLOAT128_IEEE_P (mode))
- rs6000_passes_ieee128 = true;
- }
- if (named && ALTIVEC_OR_VSX_VECTOR_MODE (mode))
- rs6000_passes_vector = true;
- }
-#endif
-
- if (TARGET_ALTIVEC_ABI
- && (ALTIVEC_OR_VSX_VECTOR_MODE (elt_mode)
- || (type && TREE_CODE (type) == VECTOR_TYPE
- && int_size_in_bytes (type) == 16)))
- {
- bool stack = false;
-
- if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
- {
- cum->vregno += n_elts;
-
- if (!TARGET_ALTIVEC)
- error ("cannot pass argument in vector register because"
- " altivec instructions are disabled, use %qs"
- " to enable them", "-maltivec");
-
- /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
- even if it is going to be passed in a vector register.
- Darwin does the same for variable-argument functions. */
- if (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
- && TARGET_64BIT)
- || (cum->stdarg && DEFAULT_ABI != ABI_V4))
- stack = true;
- }
- else
- stack = true;
-
- if (stack)
- {
- int align;
-
- /* Vector parameters must be 16-byte aligned. In 32-bit
- mode this means we need to take into account the offset
- to the parameter save area. In 64-bit mode, they just
- have to start on an even word, since the parameter save
- area is 16-byte aligned. */
- if (TARGET_32BIT)
- align = -(rs6000_parm_offset () + cum->words) & 3;
- else
- align = cum->words & 1;
- cum->words += align + rs6000_arg_size (mode, type);
-
- if (TARGET_DEBUG_ARG)
- {
- fprintf (stderr, "function_adv: words = %2d, align=%d, ",
- cum->words, align);
- fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
- cum->nargs_prototype, cum->prototype,
- GET_MODE_NAME (mode));
- }
- }
- }
- else if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
- {
- int size = int_size_in_bytes (type);
- /* Variable sized types have size == -1 and are
- treated as if consisting entirely of ints.
- Pad to 16 byte boundary if needed. */
- if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
- && (cum->words % 2) != 0)
- cum->words++;
- /* For varargs, we can just go up by the size of the struct. */
- if (!named)
- cum->words += (size + 7) / 8;
- else
- {
- /* It is tempting to say int register count just goes up by
- sizeof(type)/8, but this is wrong in a case such as
- { int; double; int; } [powerpc alignment]. We have to
- grovel through the fields for these too. */
- cum->intoffset = 0;
- cum->floats_in_gpr = 0;
- rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
- rs6000_darwin64_record_arg_advance_flush (cum,
- size * BITS_PER_UNIT, 1);
- }
- if (TARGET_DEBUG_ARG)
- {
- fprintf (stderr, "function_adv: words = %2d, align=%d, size=%d",
- cum->words, TYPE_ALIGN (type), size);
- fprintf (stderr,
- "nargs = %4d, proto = %d, mode = %4s (darwin64 abi)\n",
- cum->nargs_prototype, cum->prototype,
- GET_MODE_NAME (mode));
- }
- }
- else if (DEFAULT_ABI == ABI_V4)
- {
- if (abi_v4_pass_in_fpr (mode, named))
- {
- /* _Decimal128 must use an even/odd register pair. This assumes
- that the register number is odd when fregno is odd. */
- if (mode == TDmode && (cum->fregno % 2) == 1)
- cum->fregno++;
-
- if (cum->fregno + (FLOAT128_2REG_P (mode) ? 1 : 0)
- <= FP_ARG_V4_MAX_REG)
- cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
- else
- {
- cum->fregno = FP_ARG_V4_MAX_REG + 1;
- if (mode == DFmode || FLOAT128_IBM_P (mode)
- || mode == DDmode || mode == TDmode)
- cum->words += cum->words & 1;
- cum->words += rs6000_arg_size (mode, type);
- }
- }
- else
- {
- int n_words = rs6000_arg_size (mode, type);
- int gregno = cum->sysv_gregno;
-
- /* Long long is put in (r3,r4), (r5,r6), (r7,r8) or (r9,r10).
- As does any other 2 word item such as complex int due to a
- historical mistake. */
- if (n_words == 2)
- gregno += (1 - gregno) & 1;
-
- /* Multi-reg args are not split between registers and stack. */
- if (gregno + n_words - 1 > GP_ARG_MAX_REG)
- {
- /* Long long is aligned on the stack. So are other 2 word
- items such as complex int due to a historical mistake. */
- if (n_words == 2)
- cum->words += cum->words & 1;
- cum->words += n_words;
- }
-
- /* Note: continuing to accumulate gregno past when we've started
- spilling to the stack indicates the fact that we've started
- spilling to the stack to expand_builtin_saveregs. */
- cum->sysv_gregno = gregno + n_words;
- }
-
- if (TARGET_DEBUG_ARG)
- {
- fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
- cum->words, cum->fregno);
- fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
- cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
- fprintf (stderr, "mode = %4s, named = %d\n",
- GET_MODE_NAME (mode), named);
- }
- }
- else
- {
- int n_words = rs6000_arg_size (mode, type);
- int start_words = cum->words;
- int align_words = rs6000_parm_start (mode, type, start_words);
-
- cum->words = align_words + n_words;
-
- if (SCALAR_FLOAT_MODE_P (elt_mode) && TARGET_HARD_FLOAT)
- {
- /* _Decimal128 must be passed in an even/odd float register pair.
- This assumes that the register number is odd when fregno is
- odd. */
- if (elt_mode == TDmode && (cum->fregno % 2) == 1)
- cum->fregno++;
- cum->fregno += n_elts * ((GET_MODE_SIZE (elt_mode) + 7) >> 3);
- }
-
- if (TARGET_DEBUG_ARG)
- {
- fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
- cum->words, cum->fregno);
- fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
- cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
- fprintf (stderr, "named = %d, align = %d, depth = %d\n",
- named, align_words - start_words, depth);
- }
- }
-}
-
-static void
-rs6000_function_arg_advance (cumulative_args_t cum, machine_mode mode,
- const_tree type, bool named)
-{
- rs6000_function_arg_advance_1 (get_cumulative_args (cum), mode, type, named,
- 0);
-}
-
-/* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
- structure between cum->intoffset and bitpos to integer registers. */
-
-static void
-rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
- HOST_WIDE_INT bitpos, rtx rvec[], int *k)
-{
- machine_mode mode;
- unsigned int regno;
- unsigned int startbit, endbit;
- int this_regno, intregs, intoffset;
- rtx reg;
-
- if (cum->intoffset == -1)
- return;
-
- intoffset = cum->intoffset;
- cum->intoffset = -1;
-
- /* If this is the trailing part of a word, try to only load that
- much into the register. Otherwise load the whole register. Note
- that in the latter case we may pick up unwanted bits. It's not a
- problem at the moment but may wish to revisit. */
-
- if (intoffset % BITS_PER_WORD != 0)
- {
- unsigned int bits = BITS_PER_WORD - intoffset % BITS_PER_WORD;
- if (!int_mode_for_size (bits, 0).exists (&mode))
- {
- /* We couldn't find an appropriate mode, which happens,
- e.g., in packed structs when there are 3 bytes to load.
- Back intoffset back to the beginning of the word in this
- case. */
- intoffset = ROUND_DOWN (intoffset, BITS_PER_WORD);
- mode = word_mode;
- }
- }
- else
- mode = word_mode;
-
- startbit = ROUND_DOWN (intoffset, BITS_PER_WORD);
- endbit = ROUND_UP (bitpos, BITS_PER_WORD);
- intregs = (endbit - startbit) / BITS_PER_WORD;
- this_regno = cum->words + intoffset / BITS_PER_WORD;
-
- if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
- cum->use_stack = 1;
-
- intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
- if (intregs <= 0)
- return;
-
- intoffset /= BITS_PER_UNIT;
- do
- {
- regno = GP_ARG_MIN_REG + this_regno;
- reg = gen_rtx_REG (mode, regno);
- rvec[(*k)++] =
- gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
-
- this_regno += 1;
- intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
- mode = word_mode;
- intregs -= 1;
- }
- while (intregs > 0);
-}
-
-/* Recursive workhorse for the following. */
-
-static void
-rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
- HOST_WIDE_INT startbitpos, rtx rvec[],
- int *k)
-{
- tree f;
-
- for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
- if (TREE_CODE (f) == FIELD_DECL)
- {
- HOST_WIDE_INT bitpos = startbitpos;
- tree ftype = TREE_TYPE (f);
- machine_mode mode;
- if (ftype == error_mark_node)
- continue;
- mode = TYPE_MODE (ftype);
-
- if (DECL_SIZE (f) != 0
- && tree_fits_uhwi_p (bit_position (f)))
- bitpos += int_bit_position (f);
-
- /* ??? FIXME: else assume zero offset. */
-
- if (TREE_CODE (ftype) == RECORD_TYPE)
- rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
- else if (cum->named && USE_FP_FOR_ARG_P (cum, mode))
- {
- unsigned n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
-#if 0
- switch (mode)
- {
- case E_SCmode: mode = SFmode; break;
- case E_DCmode: mode = DFmode; break;
- case E_TCmode: mode = TFmode; break;
- default: break;
- }
-#endif
- rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
- if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
- {
- gcc_assert (cum->fregno == FP_ARG_MAX_REG
- && (mode == TFmode || mode == TDmode));
- /* Long double or _Decimal128 split over regs and memory. */
- mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
- cum->use_stack=1;
- }
- rvec[(*k)++]
- = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode, cum->fregno++),
- GEN_INT (bitpos / BITS_PER_UNIT));
- if (FLOAT128_2REG_P (mode))
- cum->fregno++;
- }
- else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, 1))
- {
- rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
- rvec[(*k)++]
- = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode, cum->vregno++),
- GEN_INT (bitpos / BITS_PER_UNIT));
- }
- else if (cum->intoffset == -1)
- cum->intoffset = bitpos;
- }
-}
-
-/* For the darwin64 ABI, we want to construct a PARALLEL consisting of
- the register(s) to be used for each field and subfield of a struct
- being passed by value, along with the offset of where the
- register's value may be found in the block. FP fields go in FP
- register, vector fields go in vector registers, and everything
- else goes in int registers, packed as in memory.
-
- This code is also used for function return values. RETVAL indicates
- whether this is the case.
-
- Much of this is taken from the SPARC V9 port, which has a similar
- calling convention. */
-
-static rtx
-rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
- bool named, bool retval)
-{
- rtx rvec[FIRST_PSEUDO_REGISTER];
- int k = 1, kbase = 1;
- HOST_WIDE_INT typesize = int_size_in_bytes (type);
- /* This is a copy; modifications are not visible to our caller. */
- CUMULATIVE_ARGS copy_cum = *orig_cum;
- CUMULATIVE_ARGS *cum = &copy_cum;
-
- /* Pad to 16 byte boundary if needed. */
- if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
- && (cum->words % 2) != 0)
- cum->words++;
-
- cum->intoffset = 0;
- cum->use_stack = 0;
- cum->named = named;
-
- /* Put entries into rvec[] for individual FP and vector fields, and
- for the chunks of memory that go in int regs. Note we start at
- element 1; 0 is reserved for an indication of using memory, and
- may or may not be filled in below. */
- rs6000_darwin64_record_arg_recurse (cum, type, /* startbit pos= */ 0, rvec, &k);
- rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
-
- /* If any part of the struct went on the stack put all of it there.
- This hack is because the generic code for
- FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
- parts of the struct are not at the beginning. */
- if (cum->use_stack)
- {
- if (retval)
- return NULL_RTX; /* doesn't go in registers at all */
- kbase = 0;
- rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
- }
- if (k > 1 || cum->use_stack)
- return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
- else
- return NULL_RTX;
-}
-
-/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
-
-static rtx
-rs6000_mixed_function_arg (machine_mode mode, const_tree type,
- int align_words)
-{
- int n_units;
- int i, k;
- rtx rvec[GP_ARG_NUM_REG + 1];
-
- if (align_words >= GP_ARG_NUM_REG)
- return NULL_RTX;
-
- n_units = rs6000_arg_size (mode, type);
-
- /* Optimize the simple case where the arg fits in one gpr, except in
- the case of BLKmode due to assign_parms assuming that registers are
- BITS_PER_WORD wide. */
- if (n_units == 0
- || (n_units == 1 && mode != BLKmode))
- return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
-
- k = 0;
- if (align_words + n_units > GP_ARG_NUM_REG)
- /* Not all of the arg fits in gprs. Say that it goes in memory too,
- using a magic NULL_RTX component.
- This is not strictly correct. Only some of the arg belongs in
- memory, not all of it. However, the normal scheme using
- function_arg_partial_nregs can result in unusual subregs, eg.
- (subreg:SI (reg:DF) 4), which are not handled well. The code to
- store the whole arg to memory is often more efficient than code
- to store pieces, and we know that space is available in the right
- place for the whole arg. */
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
-
- i = 0;
- do
- {
- rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
- rtx off = GEN_INT (i++ * 4);
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
- }
- while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
-
- return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
-}
-
-/* We have an argument of MODE and TYPE that goes into FPRs or VRs,
- but must also be copied into the parameter save area starting at
- offset ALIGN_WORDS. Fill in RVEC with the elements corresponding
- to the GPRs and/or memory. Return the number of elements used. */
-
-static int
-rs6000_psave_function_arg (machine_mode mode, const_tree type,
- int align_words, rtx *rvec)
-{
- int k = 0;
-
- if (align_words < GP_ARG_NUM_REG)
- {
- int n_words = rs6000_arg_size (mode, type);
-
- if (align_words + n_words > GP_ARG_NUM_REG
- || mode == BLKmode
- || (TARGET_32BIT && TARGET_POWERPC64))
- {
- /* If this is partially on the stack, then we only
- include the portion actually in registers here. */
- machine_mode rmode = TARGET_32BIT ? SImode : DImode;
- int i = 0;
-
- if (align_words + n_words > GP_ARG_NUM_REG)
- {
- /* Not all of the arg fits in gprs. Say that it goes in memory
- too, using a magic NULL_RTX component. Also see comment in
- rs6000_mixed_function_arg for why the normal
- function_arg_partial_nregs scheme doesn't work in this case. */
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
- }
-
- do
- {
- rtx r = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
- rtx off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
- }
- while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
- }
- else
- {
- /* The whole arg fits in gprs. */
- rtx r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
- }
- }
- else
- {
- /* It's entirely in memory. */
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
- }
-
- return k;
-}
-
-/* RVEC is a vector of K components of an argument of mode MODE.
- Construct the final function_arg return value from it. */
-
-static rtx
-rs6000_finish_function_arg (machine_mode mode, rtx *rvec, int k)
-{
- gcc_assert (k >= 1);
-
- /* Avoid returning a PARALLEL in the trivial cases. */
- if (k == 1)
- {
- if (XEXP (rvec[0], 0) == NULL_RTX)
- return NULL_RTX;
-
- if (GET_MODE (XEXP (rvec[0], 0)) == mode)
- return XEXP (rvec[0], 0);
- }
-
- return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
-}
-
-/* Determine where to put an argument to a function.
- Value is zero to push the argument on the stack,
- or a hard register in which to store the argument.
-
- MODE is the argument's machine mode.
- TYPE is the data type of the argument (as a tree).
- This is null for libcalls where that information may
- not be available.
- CUM is a variable of type CUMULATIVE_ARGS which gives info about
- the preceding args and about the function being called. It is
- not modified in this routine.
- NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis).
-
- On RS/6000 the first eight words of non-FP are normally in registers
- and the rest are pushed. Under AIX, the first 13 FP args are in registers.
- Under V.4, the first 8 FP args are in registers.
-
- If this is floating-point and no prototype is specified, we use
- both an FP and integer register (or possibly FP reg and stack). Library
- functions (when CALL_LIBCALL is set) always have the proper types for args,
- so we can pass the FP value just in one register. emit_library_function
- doesn't support PARALLEL anyway.
-
- Note that for args passed by reference, function_arg will be called
- with MODE and TYPE set to that of the pointer to the arg, not the arg
- itself. */
-
-static rtx
-rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
- const_tree type, bool named)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- enum rs6000_abi abi = DEFAULT_ABI;
- machine_mode elt_mode;
- int n_elts;
-
- /* Return a marker to indicate whether CR1 needs to set or clear the
- bit that V.4 uses to say fp args were passed in registers.
- Assume that we don't need the marker for software floating point,
- or compiler generated library calls. */
- if (mode == VOIDmode)
- {
- if (abi == ABI_V4
- && (cum->call_cookie & CALL_LIBCALL) == 0
- && (cum->stdarg
- || (cum->nargs_prototype < 0
- && (cum->prototype || TARGET_NO_PROTOTYPE)))
- && TARGET_HARD_FLOAT)
- return GEN_INT (cum->call_cookie
- | ((cum->fregno == FP_ARG_MIN_REG)
- ? CALL_V4_SET_FP_ARGS
- : CALL_V4_CLEAR_FP_ARGS));
-
- return GEN_INT (cum->call_cookie & ~CALL_LIBCALL);
- }
-
- rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
-
- if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
- {
- rtx rslt = rs6000_darwin64_record_arg (cum, type, named, /*retval= */false);
- if (rslt != NULL_RTX)
- return rslt;
- /* Else fall through to usual handling. */
- }
-
- if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
- {
- rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1];
- rtx r, off;
- int i, k = 0;
-
- /* Do we also need to pass this argument in the parameter save area?
- Library support functions for IEEE 128-bit are assumed to not need the
- value passed both in GPRs and in vector registers. */
- if (TARGET_64BIT && !cum->prototype
- && (!cum->libcall || !FLOAT128_VECTOR_P (elt_mode)))
- {
- int align_words = ROUND_UP (cum->words, 2);
- k = rs6000_psave_function_arg (mode, type, align_words, rvec);
- }
-
- /* Describe where this argument goes in the vector registers. */
- for (i = 0; i < n_elts && cum->vregno + i <= ALTIVEC_ARG_MAX_REG; i++)
- {
- r = gen_rtx_REG (elt_mode, cum->vregno + i);
- off = GEN_INT (i * GET_MODE_SIZE (elt_mode));
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
- }
-
- return rs6000_finish_function_arg (mode, rvec, k);
- }
- else if (TARGET_ALTIVEC_ABI
- && (ALTIVEC_OR_VSX_VECTOR_MODE (mode)
- || (type && TREE_CODE (type) == VECTOR_TYPE
- && int_size_in_bytes (type) == 16)))
- {
- if (named || abi == ABI_V4)
- return NULL_RTX;
- else
- {
- /* Vector parameters to varargs functions under AIX or Darwin
- get passed in memory and possibly also in GPRs. */
- int align, align_words, n_words;
- machine_mode part_mode;
-
- /* Vector parameters must be 16-byte aligned. In 32-bit
- mode this means we need to take into account the offset
- to the parameter save area. In 64-bit mode, they just
- have to start on an even word, since the parameter save
- area is 16-byte aligned. */
- if (TARGET_32BIT)
- align = -(rs6000_parm_offset () + cum->words) & 3;
- else
- align = cum->words & 1;
- align_words = cum->words + align;
-
- /* Out of registers? Memory, then. */
- if (align_words >= GP_ARG_NUM_REG)
- return NULL_RTX;
-
- if (TARGET_32BIT && TARGET_POWERPC64)
- return rs6000_mixed_function_arg (mode, type, align_words);
-
- /* The vector value goes in GPRs. Only the part of the
- value in GPRs is reported here. */
- part_mode = mode;
- n_words = rs6000_arg_size (mode, type);
- if (align_words + n_words > GP_ARG_NUM_REG)
- /* Fortunately, there are only two possibilities, the value
- is either wholly in GPRs or half in GPRs and half not. */
- part_mode = DImode;
-
- return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
- }
- }
-
- else if (abi == ABI_V4)
- {
- if (abi_v4_pass_in_fpr (mode, named))
- {
- /* _Decimal128 must use an even/odd register pair. This assumes
- that the register number is odd when fregno is odd. */
- if (mode == TDmode && (cum->fregno % 2) == 1)
- cum->fregno++;
-
- if (cum->fregno + (FLOAT128_2REG_P (mode) ? 1 : 0)
- <= FP_ARG_V4_MAX_REG)
- return gen_rtx_REG (mode, cum->fregno);
- else
- return NULL_RTX;
- }
- else
- {
- int n_words = rs6000_arg_size (mode, type);
- int gregno = cum->sysv_gregno;
-
- /* Long long is put in (r3,r4), (r5,r6), (r7,r8) or (r9,r10).
- As does any other 2 word item such as complex int due to a
- historical mistake. */
- if (n_words == 2)
- gregno += (1 - gregno) & 1;
-
- /* Multi-reg args are not split between registers and stack. */
- if (gregno + n_words - 1 > GP_ARG_MAX_REG)
- return NULL_RTX;
-
- if (TARGET_32BIT && TARGET_POWERPC64)
- return rs6000_mixed_function_arg (mode, type,
- gregno - GP_ARG_MIN_REG);
- return gen_rtx_REG (mode, gregno);
- }
- }
- else
- {
- int align_words = rs6000_parm_start (mode, type, cum->words);
-
- /* _Decimal128 must be passed in an even/odd float register pair.
- This assumes that the register number is odd when fregno is odd. */
- if (elt_mode == TDmode && (cum->fregno % 2) == 1)
- cum->fregno++;
-
- if (USE_FP_FOR_ARG_P (cum, elt_mode)
- && !(TARGET_AIX && !TARGET_ELF
- && type != NULL && AGGREGATE_TYPE_P (type)))
- {
- rtx rvec[GP_ARG_NUM_REG + AGGR_ARG_NUM_REG + 1];
- rtx r, off;
- int i, k = 0;
- unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
- int fpr_words;
-
- /* Do we also need to pass this argument in the parameter
- save area? */
- if (type && (cum->nargs_prototype <= 0
- || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
- && TARGET_XL_COMPAT
- && align_words >= GP_ARG_NUM_REG)))
- k = rs6000_psave_function_arg (mode, type, align_words, rvec);
-
- /* Describe where this argument goes in the fprs. */
- for (i = 0; i < n_elts
- && cum->fregno + i * n_fpreg <= FP_ARG_MAX_REG; i++)
- {
- /* Check if the argument is split over registers and memory.
- This can only ever happen for long double or _Decimal128;
- complex types are handled via split_complex_arg. */
- machine_mode fmode = elt_mode;
- if (cum->fregno + (i + 1) * n_fpreg > FP_ARG_MAX_REG + 1)
- {
- gcc_assert (FLOAT128_2REG_P (fmode));
- fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
- }
-
- r = gen_rtx_REG (fmode, cum->fregno + i * n_fpreg);
- off = GEN_INT (i * GET_MODE_SIZE (elt_mode));
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
- }
-
- /* If there were not enough FPRs to hold the argument, the rest
- usually goes into memory. However, if the current position
- is still within the register parameter area, a portion may
- actually have to go into GPRs.
-
- Note that it may happen that the portion of the argument
- passed in the first "half" of the first GPR was already
- passed in the last FPR as well.
-
- For unnamed arguments, we already set up GPRs to cover the
- whole argument in rs6000_psave_function_arg, so there is
- nothing further to do at this point. */
- fpr_words = (i * GET_MODE_SIZE (elt_mode)) / (TARGET_32BIT ? 4 : 8);
- if (i < n_elts && align_words + fpr_words < GP_ARG_NUM_REG
- && cum->nargs_prototype > 0)
- {
- static bool warned;
-
- machine_mode rmode = TARGET_32BIT ? SImode : DImode;
- int n_words = rs6000_arg_size (mode, type);
-
- align_words += fpr_words;
- n_words -= fpr_words;
-
- do
- {
- r = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
- off = GEN_INT (fpr_words++ * GET_MODE_SIZE (rmode));
- rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
- }
- while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
-
- if (!warned && warn_psabi)
- {
- warned = true;
- inform (input_location,
- "the ABI of passing homogeneous %<float%> aggregates"
- " has changed in GCC 5");
- }
- }
-
- return rs6000_finish_function_arg (mode, rvec, k);
- }
- else if (align_words < GP_ARG_NUM_REG)
- {
- if (TARGET_32BIT && TARGET_POWERPC64)
- return rs6000_mixed_function_arg (mode, type, align_words);
-
- return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
- }
- else
- return NULL_RTX;
- }
-}
-
-/* For an arg passed partly in registers and partly in memory, this is
- the number of bytes passed in registers. For args passed entirely in
- registers or entirely in memory, zero. When an arg is described by a
- PARALLEL, perhaps using more than one register type, this function
- returns the number of bytes used by the first element of the PARALLEL. */
-
-static int
-rs6000_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
- tree type, bool named)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- bool passed_in_gprs = true;
- int ret = 0;
- int align_words;
- machine_mode elt_mode;
- int n_elts;
-
- rs6000_discover_homogeneous_aggregate (mode, type, &elt_mode, &n_elts);
-
- if (DEFAULT_ABI == ABI_V4)
- return 0;
-
- if (USE_ALTIVEC_FOR_ARG_P (cum, elt_mode, named))
- {
- /* If we are passing this arg in the fixed parameter save area (gprs or
- memory) as well as VRs, we do not use the partial bytes mechanism;
- instead, rs6000_function_arg will return a PARALLEL including a memory
- element as necessary. Library support functions for IEEE 128-bit are
- assumed to not need the value passed both in GPRs and in vector
- registers. */
- if (TARGET_64BIT && !cum->prototype
- && (!cum->libcall || !FLOAT128_VECTOR_P (elt_mode)))
- return 0;
-
- /* Otherwise, we pass in VRs only. Check for partial copies. */
- passed_in_gprs = false;
- if (cum->vregno + n_elts > ALTIVEC_ARG_MAX_REG + 1)
- ret = (ALTIVEC_ARG_MAX_REG + 1 - cum->vregno) * 16;
- }
-
- /* In this complicated case we just disable the partial_nregs code. */
- if (TARGET_MACHO && rs6000_darwin64_struct_check_p (mode, type))
- return 0;
-
- align_words = rs6000_parm_start (mode, type, cum->words);
-
- if (USE_FP_FOR_ARG_P (cum, elt_mode)
- && !(TARGET_AIX && !TARGET_ELF
- && type != NULL && AGGREGATE_TYPE_P (type)))
- {
- unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
-
- /* If we are passing this arg in the fixed parameter save area
- (gprs or memory) as well as FPRs, we do not use the partial
- bytes mechanism; instead, rs6000_function_arg will return a
- PARALLEL including a memory element as necessary. */
- if (type
- && (cum->nargs_prototype <= 0
- || ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
- && TARGET_XL_COMPAT
- && align_words >= GP_ARG_NUM_REG)))
- return 0;
-
- /* Otherwise, we pass in FPRs only. Check for partial copies. */
- passed_in_gprs = false;
- if (cum->fregno + n_elts * n_fpreg > FP_ARG_MAX_REG + 1)
- {
- /* Compute number of bytes / words passed in FPRs. If there
- is still space available in the register parameter area
- *after* that amount, a part of the argument will be passed
- in GPRs. In that case, the total amount passed in any
- registers is equal to the amount that would have been passed
- in GPRs if everything were passed there, so we fall back to
- the GPR code below to compute the appropriate value. */
- int fpr = ((FP_ARG_MAX_REG + 1 - cum->fregno)
- * MIN (8, GET_MODE_SIZE (elt_mode)));
- int fpr_words = fpr / (TARGET_32BIT ? 4 : 8);
-
- if (align_words + fpr_words < GP_ARG_NUM_REG)
- passed_in_gprs = true;
- else
- ret = fpr;
- }
- }
-
- if (passed_in_gprs
- && align_words < GP_ARG_NUM_REG
- && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
- ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
-
- if (ret != 0 && TARGET_DEBUG_ARG)
- fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
-
- return ret;
-}
-
-/* A C expression that indicates when an argument must be passed by
- reference. If nonzero for an argument, a copy of that argument is
- made in memory and a pointer to the argument is passed instead of
- the argument itself. The pointer is passed in whatever way is
- appropriate for passing a pointer to that type.
-
- Under V.4, aggregates and long double are passed by reference.
-
- As an extension to all 32-bit ABIs, AltiVec vectors are passed by
- reference unless the AltiVec vector extension ABI is in force.
-
- As an extension to all ABIs, variable sized types are passed by
- reference. */
-
-static bool
-rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED,
- machine_mode mode, const_tree type,
- bool named ATTRIBUTE_UNUSED)
-{
- if (!type)
- return 0;
-
- if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD
- && FLOAT128_IEEE_P (TYPE_MODE (type)))
- {
- if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: V4 IEEE 128-bit\n");
- return 1;
- }
-
- if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
- {
- if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
- return 1;
- }
-
- if (int_size_in_bytes (type) < 0)
- {
- if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
- return 1;
- }
-
- /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
- modes only exist for GCC vector types if -maltivec. */
- if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
- {
- if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
- return 1;
- }
-
- /* Pass synthetic vectors in memory. */
- if (TREE_CODE (type) == VECTOR_TYPE
- && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
- {
- static bool warned_for_pass_big_vectors = false;
- if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
- if (!warned_for_pass_big_vectors)
- {
- warning (OPT_Wpsabi, "GCC vector passed by reference: "
- "non-standard ABI extension with no compatibility "
- "guarantee");
- warned_for_pass_big_vectors = true;
- }
- return 1;
- }
-
- return 0;
-}
-
-/* Process parameter of type TYPE after ARGS_SO_FAR parameters were
- already processes. Return true if the parameter must be passed
- (fully or partially) on the stack. */
-
-static bool
-rs6000_parm_needs_stack (cumulative_args_t args_so_far, tree type)
-{
- machine_mode mode;
- int unsignedp;
- rtx entry_parm;
-
- /* Catch errors. */
- if (type == NULL || type == error_mark_node)
- return true;
-
- /* Handle types with no storage requirement. */
- if (TYPE_MODE (type) == VOIDmode)
- return false;
-
- /* Handle complex types. */
- if (TREE_CODE (type) == COMPLEX_TYPE)
- return (rs6000_parm_needs_stack (args_so_far, TREE_TYPE (type))
- || rs6000_parm_needs_stack (args_so_far, TREE_TYPE (type)));
-
- /* Handle transparent aggregates. */
- if ((TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == RECORD_TYPE)
- && TYPE_TRANSPARENT_AGGR (type))
- type = TREE_TYPE (first_field (type));
-
- /* See if this arg was passed by invisible reference. */
- if (pass_by_reference (get_cumulative_args (args_so_far),
- TYPE_MODE (type), type, true))
- type = build_pointer_type (type);
-
- /* Find mode as it is passed by the ABI. */
- unsignedp = TYPE_UNSIGNED (type);
- mode = promote_mode (type, TYPE_MODE (type), &unsignedp);
-
- /* If we must pass in stack, we need a stack. */
- if (rs6000_must_pass_in_stack (mode, type))
- return true;
-
- /* If there is no incoming register, we need a stack. */
- entry_parm = rs6000_function_arg (args_so_far, mode, type, true);
- if (entry_parm == NULL)
- return true;
-
- /* Likewise if we need to pass both in registers and on the stack. */
- if (GET_CODE (entry_parm) == PARALLEL
- && XEXP (XVECEXP (entry_parm, 0, 0), 0) == NULL_RTX)
- return true;
-
- /* Also true if we're partially in registers and partially not. */
- if (rs6000_arg_partial_bytes (args_so_far, mode, type, true) != 0)
- return true;
-
- /* Update info on where next arg arrives in registers. */
- rs6000_function_arg_advance (args_so_far, mode, type, true);
- return false;
-}
-
-/* Return true if FUN has no prototype, has a variable argument
- list, or passes any parameter in memory. */
-
-static bool
-rs6000_function_parms_need_stack (tree fun, bool incoming)
-{
- tree fntype, result;
- CUMULATIVE_ARGS args_so_far_v;
- cumulative_args_t args_so_far;
-
- if (!fun)
- /* Must be a libcall, all of which only use reg parms. */
- return false;
-
- fntype = fun;
- if (!TYPE_P (fun))
- fntype = TREE_TYPE (fun);
-
- /* Varargs functions need the parameter save area. */
- if ((!incoming && !prototype_p (fntype)) || stdarg_p (fntype))
- return true;
-
- INIT_CUMULATIVE_INCOMING_ARGS (args_so_far_v, fntype, NULL_RTX);
- args_so_far = pack_cumulative_args (&args_so_far_v);
-
- /* When incoming, we will have been passed the function decl.
- It is necessary to use the decl to handle K&R style functions,
- where TYPE_ARG_TYPES may not be available. */
- if (incoming)
- {
- gcc_assert (DECL_P (fun));
- result = DECL_RESULT (fun);
- }
- else
- result = TREE_TYPE (fntype);
-
- if (result && aggregate_value_p (result, fntype))
- {
- if (!TYPE_P (result))
- result = TREE_TYPE (result);
- result = build_pointer_type (result);
- rs6000_parm_needs_stack (args_so_far, result);
- }
-
- if (incoming)
- {
- tree parm;
-
- for (parm = DECL_ARGUMENTS (fun);
- parm && parm != void_list_node;
- parm = TREE_CHAIN (parm))
- if (rs6000_parm_needs_stack (args_so_far, TREE_TYPE (parm)))
- return true;
- }
- else
- {
- function_args_iterator args_iter;
- tree arg_type;
-
- FOREACH_FUNCTION_ARGS (fntype, arg_type, args_iter)
- if (rs6000_parm_needs_stack (args_so_far, arg_type))
- return true;
- }
-
- return false;
-}
-
-/* Return the size of the REG_PARM_STACK_SPACE are for FUN. This is
- usually a constant depending on the ABI. However, in the ELFv2 ABI
- the register parameter area is optional when calling a function that
- has a prototype is scope, has no variable argument list, and passes
- all parameters in registers. */
-
-int
-rs6000_reg_parm_stack_space (tree fun, bool incoming)
-{
- int reg_parm_stack_space;
-
- switch (DEFAULT_ABI)
- {
- default:
- reg_parm_stack_space = 0;
- break;
-
- case ABI_AIX:
- case ABI_DARWIN:
- reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
- break;
-
- case ABI_ELFv2:
- /* ??? Recomputing this every time is a bit expensive. Is there
- a place to cache this information? */
- if (rs6000_function_parms_need_stack (fun, incoming))
- reg_parm_stack_space = TARGET_64BIT ? 64 : 32;
- else
- reg_parm_stack_space = 0;
- break;
- }
-
- return reg_parm_stack_space;
-}
-
-static void
-rs6000_move_block_from_reg (int regno, rtx x, int nregs)
-{
- int i;
- machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
-
- if (nregs == 0)
- return;
-
- for (i = 0; i < nregs; i++)
- {
- rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
- if (reload_completed)
- {
- if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
- tem = NULL_RTX;
- else
- tem = simplify_gen_subreg (reg_mode, x, BLKmode,
- i * GET_MODE_SIZE (reg_mode));
- }
- else
- tem = replace_equiv_address (tem, XEXP (tem, 0));
-
- gcc_assert (tem);
-
- emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
- }
-}
-
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as above.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed. */
-
-static void
-setup_incoming_varargs (cumulative_args_t cum, machine_mode mode,
- tree type, int *pretend_size ATTRIBUTE_UNUSED,
- int no_rtl)
-{
- CUMULATIVE_ARGS next_cum;
- int reg_size = TARGET_32BIT ? 4 : 8;
- rtx save_area = NULL_RTX, mem;
- int first_reg_offset;
- alias_set_type set;
-
- /* Skip the last named argument. */
- next_cum = *get_cumulative_args (cum);
- rs6000_function_arg_advance_1 (&next_cum, mode, type, true, 0);
-
- if (DEFAULT_ABI == ABI_V4)
- {
- first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
-
- if (! no_rtl)
- {
- int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
- HOST_WIDE_INT offset = 0;
-
- /* Try to optimize the size of the varargs save area.
- The ABI requires that ap.reg_save_area is doubleword
- aligned, but we don't need to allocate space for all
- the bytes, only those to which we actually will save
- anything. */
- if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
- gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
- if (TARGET_HARD_FLOAT
- && next_cum.fregno <= FP_ARG_V4_MAX_REG
- && cfun->va_list_fpr_size)
- {
- if (gpr_reg_num)
- fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
- * UNITS_PER_FP_WORD;
- if (cfun->va_list_fpr_size
- < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
- fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
- else
- fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
- * UNITS_PER_FP_WORD;
- }
- if (gpr_reg_num)
- {
- offset = -((first_reg_offset * reg_size) & ~7);
- if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
- {
- gpr_reg_num = cfun->va_list_gpr_size;
- if (reg_size == 4 && (first_reg_offset & 1))
- gpr_reg_num++;
- }
- gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
- }
- else if (fpr_size)
- offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
- * UNITS_PER_FP_WORD
- - (int) (GP_ARG_NUM_REG * reg_size);
-
- if (gpr_size + fpr_size)
- {
- rtx reg_save_area
- = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
- gcc_assert (MEM_P (reg_save_area));
- reg_save_area = XEXP (reg_save_area, 0);
- if (GET_CODE (reg_save_area) == PLUS)
- {
- gcc_assert (XEXP (reg_save_area, 0)
- == virtual_stack_vars_rtx);
- gcc_assert (CONST_INT_P (XEXP (reg_save_area, 1)));
- offset += INTVAL (XEXP (reg_save_area, 1));
- }
- else
- gcc_assert (reg_save_area == virtual_stack_vars_rtx);
- }
-
- cfun->machine->varargs_save_offset = offset;
- save_area = plus_constant (Pmode, virtual_stack_vars_rtx, offset);
- }
- }
- else
- {
- first_reg_offset = next_cum.words;
- save_area = crtl->args.internal_arg_pointer;
-
- if (targetm.calls.must_pass_in_stack (mode, type))
- first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
- }
-
- set = get_varargs_alias_set ();
- if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
- && cfun->va_list_gpr_size)
- {
- int n_gpr, nregs = GP_ARG_NUM_REG - first_reg_offset;
-
- if (va_list_gpr_counter_field)
- /* V4 va_list_gpr_size counts number of registers needed. */
- n_gpr = cfun->va_list_gpr_size;
- else
- /* char * va_list instead counts number of bytes needed. */
- n_gpr = (cfun->va_list_gpr_size + reg_size - 1) / reg_size;
-
- if (nregs > n_gpr)
- nregs = n_gpr;
-
- mem = gen_rtx_MEM (BLKmode,
- plus_constant (Pmode, save_area,
- first_reg_offset * reg_size));
- MEM_NOTRAP_P (mem) = 1;
- set_mem_alias_set (mem, set);
- set_mem_align (mem, BITS_PER_WORD);
-
- rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
- nregs);
- }
-
- /* Save FP registers if needed. */
- if (DEFAULT_ABI == ABI_V4
- && TARGET_HARD_FLOAT
- && ! no_rtl
- && next_cum.fregno <= FP_ARG_V4_MAX_REG
- && cfun->va_list_fpr_size)
- {
- int fregno = next_cum.fregno, nregs;
- rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
- rtx lab = gen_label_rtx ();
- int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
- * UNITS_PER_FP_WORD);
-
- emit_jump_insn
- (gen_rtx_SET (pc_rtx,
- gen_rtx_IF_THEN_ELSE (VOIDmode,
- gen_rtx_NE (VOIDmode, cr1,
- const0_rtx),
- gen_rtx_LABEL_REF (VOIDmode, lab),
- pc_rtx)));
-
- for (nregs = 0;
- fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
- fregno++, off += UNITS_PER_FP_WORD, nregs++)
- {
- mem = gen_rtx_MEM (TARGET_HARD_FLOAT ? DFmode : SFmode,
- plus_constant (Pmode, save_area, off));
- MEM_NOTRAP_P (mem) = 1;
- set_mem_alias_set (mem, set);
- set_mem_align (mem, GET_MODE_ALIGNMENT (
- TARGET_HARD_FLOAT ? DFmode : SFmode));
- emit_move_insn (mem, gen_rtx_REG (
- TARGET_HARD_FLOAT ? DFmode : SFmode, fregno));
- }
-
- emit_label (lab);
- }
-}
-
-/* Create the va_list data type. */
-
-static tree
-rs6000_build_builtin_va_list (void)
-{
- tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
-
- /* For AIX, prefer 'char *' because that's what the system
- header files like. */
- if (DEFAULT_ABI != ABI_V4)
- return build_pointer_type (char_type_node);
-
- record = (*lang_hooks.types.make_type) (RECORD_TYPE);
- type_decl = build_decl (BUILTINS_LOCATION, TYPE_DECL,
- get_identifier ("__va_list_tag"), record);
-
- f_gpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("gpr"),
- unsigned_char_type_node);
- f_fpr = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("fpr"),
- unsigned_char_type_node);
- /* Give the two bytes of padding a name, so that -Wpadded won't warn on
- every user file. */
- f_res = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- get_identifier ("reserved"), short_unsigned_type_node);
- f_ovf = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- get_identifier ("overflow_arg_area"),
- ptr_type_node);
- f_sav = build_decl (BUILTINS_LOCATION, FIELD_DECL,
- get_identifier ("reg_save_area"),
- ptr_type_node);
-
- va_list_gpr_counter_field = f_gpr;
- va_list_fpr_counter_field = f_fpr;
-
- DECL_FIELD_CONTEXT (f_gpr) = record;
- DECL_FIELD_CONTEXT (f_fpr) = record;
- DECL_FIELD_CONTEXT (f_res) = record;
- DECL_FIELD_CONTEXT (f_ovf) = record;
- DECL_FIELD_CONTEXT (f_sav) = record;
-
- TYPE_STUB_DECL (record) = type_decl;
- TYPE_NAME (record) = type_decl;
- TYPE_FIELDS (record) = f_gpr;
- DECL_CHAIN (f_gpr) = f_fpr;
- DECL_CHAIN (f_fpr) = f_res;
- DECL_CHAIN (f_res) = f_ovf;
- DECL_CHAIN (f_ovf) = f_sav;
-
- layout_type (record);
-
- /* The correct type is an array type of one element. */
- return build_array_type (record, build_index_type (size_zero_node));
-}
-
-/* Implement va_start. */
-
-static void
-rs6000_va_start (tree valist, rtx nextarg)
-{
- HOST_WIDE_INT words, n_gpr, n_fpr;
- tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
- tree gpr, fpr, ovf, sav, t;
-
- /* Only SVR4 needs something special. */
- if (DEFAULT_ABI != ABI_V4)
- {
- std_expand_builtin_va_start (valist, nextarg);
- return;
- }
-
- f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
- f_fpr = DECL_CHAIN (f_gpr);
- f_res = DECL_CHAIN (f_fpr);
- f_ovf = DECL_CHAIN (f_res);
- f_sav = DECL_CHAIN (f_ovf);
-
- valist = build_simple_mem_ref (valist);
- gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
- fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
- f_fpr, NULL_TREE);
- ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
- f_ovf, NULL_TREE);
- sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
- f_sav, NULL_TREE);
-
- /* Count number of gp and fp argument registers used. */
- words = crtl->args.info.words;
- n_gpr = MIN (crtl->args.info.sysv_gregno - GP_ARG_MIN_REG,
- GP_ARG_NUM_REG);
- n_fpr = MIN (crtl->args.info.fregno - FP_ARG_MIN_REG,
- FP_ARG_NUM_REG);
-
- if (TARGET_DEBUG_ARG)
- fprintf (stderr, "va_start: words = " HOST_WIDE_INT_PRINT_DEC", n_gpr = "
- HOST_WIDE_INT_PRINT_DEC", n_fpr = " HOST_WIDE_INT_PRINT_DEC"\n",
- words, n_gpr, n_fpr);
-
- if (cfun->va_list_gpr_size)
- {
- t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
- build_int_cst (NULL_TREE, n_gpr));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
-
- if (cfun->va_list_fpr_size)
- {
- t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
- build_int_cst (NULL_TREE, n_fpr));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
-#ifdef HAVE_AS_GNU_ATTRIBUTE
- if (call_ABI_of_interest (cfun->decl))
- rs6000_passes_float = true;
-#endif
- }
-
- /* Find the overflow area. */
- t = make_tree (TREE_TYPE (ovf), crtl->args.internal_arg_pointer);
- if (words != 0)
- t = fold_build_pointer_plus_hwi (t, words * MIN_UNITS_PER_WORD);
- t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-
- /* If there were no va_arg invocations, don't set up the register
- save area. */
- if (!cfun->va_list_gpr_size
- && !cfun->va_list_fpr_size
- && n_gpr < GP_ARG_NUM_REG
- && n_fpr < FP_ARG_V4_MAX_REG)
- return;
-
- /* Find the register save area. */
- t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
- if (cfun->machine->varargs_save_offset)
- t = fold_build_pointer_plus_hwi (t, cfun->machine->varargs_save_offset);
- t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
-}
-
-/* Implement va_arg. */
-
-static tree
-rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
- gimple_seq *post_p)
-{
- tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
- tree gpr, fpr, ovf, sav, reg, t, u;
- int size, rsize, n_reg, sav_ofs, sav_scale;
- tree lab_false, lab_over, addr;
- int align;
- tree ptrtype = build_pointer_type_for_mode (type, ptr_mode, true);
- int regalign = 0;
- gimple *stmt;
-
- if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
- {
- t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
- return build_va_arg_indirect_ref (t);
- }
-
- /* We need to deal with the fact that the darwin ppc64 ABI is defined by an
- earlier version of gcc, with the property that it always applied alignment
- adjustments to the va-args (even for zero-sized types). The cheapest way
- to deal with this is to replicate the effect of the part of
- std_gimplify_va_arg_expr that carries out the align adjust, for the case
- of relevance.
- We don't need to check for pass-by-reference because of the test above.
- We can return a simplifed answer, since we know there's no offset to add. */
-
- if (((TARGET_MACHO
- && rs6000_darwin64_abi)
- || DEFAULT_ABI == ABI_ELFv2
- || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
- && integer_zerop (TYPE_SIZE (type)))
- {
- unsigned HOST_WIDE_INT align, boundary;
- tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
- align = PARM_BOUNDARY / BITS_PER_UNIT;
- boundary = rs6000_function_arg_boundary (TYPE_MODE (type), type);
- if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
- boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
- boundary /= BITS_PER_UNIT;
- if (boundary > align)
- {
- tree t ;
- /* This updates arg ptr by the amount that would be necessary
- to align the zero-sized (but not zero-alignment) item. */
- t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
- fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
- gimplify_and_add (t, pre_p);
-
- t = fold_convert (sizetype, valist_tmp);
- t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
- fold_convert (TREE_TYPE (valist),
- fold_build2 (BIT_AND_EXPR, sizetype, t,
- size_int (-boundary))));
- t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
- gimplify_and_add (t, pre_p);
- }
- /* Since it is zero-sized there's no increment for the item itself. */
- valist_tmp = fold_convert (build_pointer_type (type), valist_tmp);
- return build_va_arg_indirect_ref (valist_tmp);
- }
-
- if (DEFAULT_ABI != ABI_V4)
- {
- if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
- {
- tree elem_type = TREE_TYPE (type);
- machine_mode elem_mode = TYPE_MODE (elem_type);
- int elem_size = GET_MODE_SIZE (elem_mode);
-
- if (elem_size < UNITS_PER_WORD)
- {
- tree real_part, imag_part;
- gimple_seq post = NULL;
-
- real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
- &post);
- /* Copy the value into a temporary, lest the formal temporary
- be reused out from under us. */
- real_part = get_initialized_tmp_var (real_part, pre_p, &post);
- gimple_seq_add_seq (pre_p, post);
-
- imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
- post_p);
-
- return build2 (COMPLEX_EXPR, type, real_part, imag_part);
- }
- }
-
- return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
- }
-
- f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
- f_fpr = DECL_CHAIN (f_gpr);
- f_res = DECL_CHAIN (f_fpr);
- f_ovf = DECL_CHAIN (f_res);
- f_sav = DECL_CHAIN (f_ovf);
-
- gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
- fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), unshare_expr (valist),
- f_fpr, NULL_TREE);
- ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), unshare_expr (valist),
- f_ovf, NULL_TREE);
- sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), unshare_expr (valist),
- f_sav, NULL_TREE);
-
- size = int_size_in_bytes (type);
- rsize = (size + 3) / 4;
- int pad = 4 * rsize - size;
- align = 1;
-
- machine_mode mode = TYPE_MODE (type);
- if (abi_v4_pass_in_fpr (mode, false))
- {
- /* FP args go in FP registers, if present. */
- reg = fpr;
- n_reg = (size + 7) / 8;
- sav_ofs = (TARGET_HARD_FLOAT ? 8 : 4) * 4;
- sav_scale = (TARGET_HARD_FLOAT ? 8 : 4);
- if (mode != SFmode && mode != SDmode)
- align = 8;
- }
- else
- {
- /* Otherwise into GP registers. */
- reg = gpr;
- n_reg = rsize;
- sav_ofs = 0;
- sav_scale = 4;
- if (n_reg == 2)
- align = 8;
- }
-
- /* Pull the value out of the saved registers.... */
-
- lab_over = NULL;
- addr = create_tmp_var (ptr_type_node, "addr");
-
- /* AltiVec vectors never go in registers when -mabi=altivec. */
- if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
- align = 16;
- else
- {
- lab_false = create_artificial_label (input_location);
- lab_over = create_artificial_label (input_location);
-
- /* Long long is aligned in the registers. As are any other 2 gpr
- item such as complex int due to a historical mistake. */
- u = reg;
- if (n_reg == 2 && reg == gpr)
- {
- regalign = 1;
- u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), unshare_expr (reg),
- build_int_cst (TREE_TYPE (reg), n_reg - 1));
- u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg),
- unshare_expr (reg), u);
- }
- /* _Decimal128 is passed in even/odd fpr pairs; the stored
- reg number is 0 for f1, so we want to make it odd. */
- else if (reg == fpr && mode == TDmode)
- {
- t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
- build_int_cst (TREE_TYPE (reg), 1));
- u = build2 (MODIFY_EXPR, void_type_node, unshare_expr (reg), t);
- }
-
- t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
- t = build2 (GE_EXPR, boolean_type_node, u, t);
- u = build1 (GOTO_EXPR, void_type_node, lab_false);
- t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
- gimplify_and_add (t, pre_p);
-
- t = sav;
- if (sav_ofs)
- t = fold_build_pointer_plus_hwi (sav, sav_ofs);
-
- u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), unshare_expr (reg),
- build_int_cst (TREE_TYPE (reg), n_reg));
- u = fold_convert (sizetype, u);
- u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
- t = fold_build_pointer_plus (t, u);
-
- /* _Decimal32 varargs are located in the second word of the 64-bit
- FP register for 32-bit binaries. */
- if (TARGET_32BIT && TARGET_HARD_FLOAT && mode == SDmode)
- t = fold_build_pointer_plus_hwi (t, size);
-
- /* Args are passed right-aligned. */
- if (BYTES_BIG_ENDIAN)
- t = fold_build_pointer_plus_hwi (t, pad);
-
- gimplify_assign (addr, t, pre_p);
-
- gimple_seq_add_stmt (pre_p, gimple_build_goto (lab_over));
-
- stmt = gimple_build_label (lab_false);
- gimple_seq_add_stmt (pre_p, stmt);
-
- if ((n_reg == 2 && !regalign) || n_reg > 2)
- {
- /* Ensure that we don't find any more args in regs.
- Alignment has taken care of for special cases. */
- gimplify_assign (reg, build_int_cst (TREE_TYPE (reg), 8), pre_p);
- }
- }
-
- /* ... otherwise out of the overflow area. */
-
- /* Care for on-stack alignment if needed. */
- t = ovf;
- if (align != 1)
- {
- t = fold_build_pointer_plus_hwi (t, align - 1);
- t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
- build_int_cst (TREE_TYPE (t), -align));
- }
-
- /* Args are passed right-aligned. */
- if (BYTES_BIG_ENDIAN)
- t = fold_build_pointer_plus_hwi (t, pad);
-
- gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
-
- gimplify_assign (unshare_expr (addr), t, pre_p);
-
- t = fold_build_pointer_plus_hwi (t, size);
- gimplify_assign (unshare_expr (ovf), t, pre_p);
-
- if (lab_over)
- {
- stmt = gimple_build_label (lab_over);
- gimple_seq_add_stmt (pre_p, stmt);
- }
-
- if (STRICT_ALIGNMENT
- && (TYPE_ALIGN (type)
- > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
- {
- /* The value (of type complex double, for example) may not be
- aligned in memory in the saved registers, so copy via a
- temporary. (This is the same code as used for SPARC.) */
- tree tmp = create_tmp_var (type, "va_arg_tmp");
- tree dest_addr = build_fold_addr_expr (tmp);
-
- tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY),
- 3, dest_addr, addr, size_int (rsize * 4));
- TREE_ADDRESSABLE (tmp) = 1;
-
- gimplify_and_add (copy, pre_p);
- addr = dest_addr;
- }
-
- addr = fold_convert (ptrtype, addr);
- return build_va_arg_indirect_ref (addr);
-}
-
-/* Builtins. */
-
-static void
-def_builtin (const char *name, tree type, enum rs6000_builtins code)
-{
- tree t;
- unsigned classify = rs6000_builtin_info[(int)code].attr;
- const char *attr_string = "";
-
- gcc_assert (name != NULL);
- gcc_assert (IN_RANGE ((int)code, 0, (int)RS6000_BUILTIN_COUNT));
-
- if (rs6000_builtin_decls[(int)code])
- fatal_error (input_location,
- "internal error: builtin function %qs already processed",
- name);
-
- rs6000_builtin_decls[(int)code] = t =
- add_builtin_function (name, type, (int)code, BUILT_IN_MD, NULL, NULL_TREE);
-
- /* Set any special attributes. */
- if ((classify & RS6000_BTC_CONST) != 0)
- {
- /* const function, function only depends on the inputs. */
- TREE_READONLY (t) = 1;
- TREE_NOTHROW (t) = 1;
- attr_string = ", const";
- }
- else if ((classify & RS6000_BTC_PURE) != 0)
- {
- /* pure function, function can read global memory, but does not set any
- external state. */
- DECL_PURE_P (t) = 1;
- TREE_NOTHROW (t) = 1;
- attr_string = ", pure";
- }
- else if ((classify & RS6000_BTC_FP) != 0)
- {
- /* Function is a math function. If rounding mode is on, then treat the
- function as not reading global memory, but it can have arbitrary side
- effects. If it is off, then assume the function is a const function.
- This mimics the ATTR_MATHFN_FPROUNDING attribute in
- builtin-attribute.def that is used for the math functions. */
- TREE_NOTHROW (t) = 1;
- if (flag_rounding_math)
- {
- DECL_PURE_P (t) = 1;
- DECL_IS_NOVOPS (t) = 1;
- attr_string = ", fp, pure";
- }
- else
- {
- TREE_READONLY (t) = 1;
- attr_string = ", fp, const";
- }
- }
- else if ((classify & RS6000_BTC_ATTR_MASK) != 0)
- gcc_unreachable ();
-
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, code = %4d, %s%s\n",
- (int)code, name, attr_string);
-}
-
-/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-static const struct builtin_description bdesc_3arg[] =
-{
-#include "rs6000-builtin.def"
-};
-
-/* DST operations: void foo (void *, const int, const char). */
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-static const struct builtin_description bdesc_dst[] =
-{
-#include "rs6000-builtin.def"
-};
-
-/* Simple binary operations: VECc = foo (VECa, VECb). */
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-static const struct builtin_description bdesc_2arg[] =
-{
-#include "rs6000-builtin.def"
-};
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-/* AltiVec predicates. */
-
-static const struct builtin_description bdesc_altivec_preds[] =
-{
-#include "rs6000-builtin.def"
-};
-
-/* ABS* operations. */
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-static const struct builtin_description bdesc_abs[] =
-{
-#include "rs6000-builtin.def"
-};
-
-/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
- foo (VECa). */
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-static const struct builtin_description bdesc_1arg[] =
-{
-#include "rs6000-builtin.def"
-};
-
-/* Simple no-argument operations: result = __builtin_darn_32 () */
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-static const struct builtin_description bdesc_0arg[] =
-{
-#include "rs6000-builtin.def"
-};
-
-/* HTM builtins. */
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-#undef RS6000_BUILTIN_X
-
-#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
- { MASK, ICODE, NAME, ENUM },
-
-#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
-#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
-
-static const struct builtin_description bdesc_htm[] =
-{
-#include "rs6000-builtin.def"
-};
-
-#undef RS6000_BUILTIN_0
-#undef RS6000_BUILTIN_1
-#undef RS6000_BUILTIN_2
-#undef RS6000_BUILTIN_3
-#undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_D
-#undef RS6000_BUILTIN_H
-#undef RS6000_BUILTIN_P
-
-/* Return true if a builtin function is overloaded. */
-bool
-rs6000_overloaded_builtin_p (enum rs6000_builtins fncode)
-{
- return (rs6000_builtin_info[(int)fncode].attr & RS6000_BTC_OVERLOADED) != 0;
-}
-
-const char *
-rs6000_overloaded_builtin_name (enum rs6000_builtins fncode)
-{
- return rs6000_builtin_info[(int)fncode].name;
-}
-
-/* Expand an expression EXP that calls a builtin without arguments. */
-static rtx
-rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target)
-{
- rtx pat;
- machine_mode tmode = insn_data[icode].operand[0].mode;
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- if (icode == CODE_FOR_rs6000_mffsl
- && rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
- {
- error ("%<__builtin_mffsl%> not supported with %<-msoft-float%>");
- return const0_rtx;
- }
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- pat = GEN_FCN (icode) (target);
- if (! pat)
- return 0;
- emit_insn (pat);
-
- return target;
-}
-
-
-static rtx
-rs6000_expand_mtfsf_builtin (enum insn_code icode, tree exp)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- machine_mode mode0 = insn_data[icode].operand[0].mode;
- machine_mode mode1 = insn_data[icode].operand[1].mode;
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node || arg1 == error_mark_node)
- return const0_rtx;
-
- if (!CONST_INT_P (op0)
- || INTVAL (op0) > 255
- || INTVAL (op0) < 0)
- {
- error ("argument 1 must be an 8-bit field value");
- return const0_rtx;
- }
-
- if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- pat = GEN_FCN (icode) (op0, op1);
- if (!pat)
- return const0_rtx;
- emit_insn (pat);
-
- return NULL_RTX;
-}
-
-static rtx
-rs6000_expand_mtfsb_builtin (enum insn_code icode, tree exp)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op0 = expand_normal (arg0);
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
- {
- error ("%<__builtin_mtfsb0%> and %<__builtin_mtfsb1%> not supported with "
- "%<-msoft-float%>");
- return const0_rtx;
- }
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node)
- return const0_rtx;
-
- /* Only allow bit numbers 0 to 31. */
- if (!u5bit_cint_operand (op0, VOIDmode))
- {
- error ("Argument must be a constant between 0 and 31.");
- return const0_rtx;
- }
-
- pat = GEN_FCN (icode) (op0);
- if (!pat)
- return const0_rtx;
- emit_insn (pat);
-
- return NULL_RTX;
-}
-
-static rtx
-rs6000_expand_set_fpscr_rn_builtin (enum insn_code icode, tree exp)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op0 = expand_normal (arg0);
- machine_mode mode0 = insn_data[icode].operand[0].mode;
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
- {
- error ("%<__builtin_set_fpscr_rn%> not supported with %<-msoft-float%>");
- return const0_rtx;
- }
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node)
- return const0_rtx;
-
- /* If the argument is a constant, check the range. Argument can only be a
- 2-bit value. Unfortunately, can't check the range of the value at
- compile time if the argument is a variable. The least significant two
- bits of the argument, regardless of type, are used to set the rounding
- mode. All other bits are ignored. */
- if (CONST_INT_P (op0) && !const_0_to_3_operand(op0, VOIDmode))
- {
- error ("Argument must be a value between 0 and 3.");
- return const0_rtx;
- }
-
- if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- pat = GEN_FCN (icode) (op0);
- if (!pat)
- return const0_rtx;
- emit_insn (pat);
-
- return NULL_RTX;
-}
-static rtx
-rs6000_expand_set_fpscr_drn_builtin (enum insn_code icode, tree exp)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op0 = expand_normal (arg0);
- machine_mode mode0 = insn_data[icode].operand[0].mode;
-
- if (TARGET_32BIT)
- /* Builtin not supported in 32-bit mode. */
- fatal_error (input_location,
- "%<__builtin_set_fpscr_drn%> is not supported "
- "in 32-bit mode");
-
- if (rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT)
- {
- error ("%<__builtin_set_fpscr_drn%> not supported with %<-msoft-float%>");
- return const0_rtx;
- }
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node)
- return const0_rtx;
-
- /* If the argument is a constant, check the range. Agrument can only be a
- 3-bit value. Unfortunately, can't check the range of the value at
- compile time if the argument is a variable. The least significant two
- bits of the argument, regardless of type, are used to set the rounding
- mode. All other bits are ignored. */
- if (CONST_INT_P (op0) && !const_0_to_7_operand(op0, VOIDmode))
- {
- error ("Argument must be a value between 0 and 7.");
- return const0_rtx;
- }
-
- if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- pat = GEN_FCN (icode) (op0);
- if (! pat)
- return const0_rtx;
- emit_insn (pat);
-
- return NULL_RTX;
-}
-
-static rtx
-rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op0 = expand_normal (arg0);
- machine_mode tmode = insn_data[icode].operand[0].mode;
- machine_mode mode0 = insn_data[icode].operand[1].mode;
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node)
- return const0_rtx;
-
- if (icode == CODE_FOR_altivec_vspltisb
- || icode == CODE_FOR_altivec_vspltish
- || icode == CODE_FOR_altivec_vspltisw)
- {
- /* Only allow 5-bit *signed* literals. */
- if (!CONST_INT_P (op0)
- || INTVAL (op0) > 15
- || INTVAL (op0) < -16)
- {
- error ("argument 1 must be a 5-bit signed literal");
- return CONST0_RTX (tmode);
- }
- }
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- pat = GEN_FCN (icode) (target, op0);
- if (! pat)
- return 0;
- emit_insn (pat);
-
- return target;
-}
-
-static rtx
-altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
-{
- rtx pat, scratch1, scratch2;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- rtx op0 = expand_normal (arg0);
- machine_mode tmode = insn_data[icode].operand[0].mode;
- machine_mode mode0 = insn_data[icode].operand[1].mode;
-
- /* If we have invalid arguments, bail out before generating bad rtl. */
- if (arg0 == error_mark_node)
- return const0_rtx;
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- scratch1 = gen_reg_rtx (mode0);
- scratch2 = gen_reg_rtx (mode0);
-
- pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
- if (! pat)
- return 0;
- emit_insn (pat);
-
- return target;
-}
-
-static rtx
-rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- machine_mode tmode = insn_data[icode].operand[0].mode;
- machine_mode mode0 = insn_data[icode].operand[1].mode;
- machine_mode mode1 = insn_data[icode].operand[2].mode;
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node || arg1 == error_mark_node)
- return const0_rtx;
-
- if (icode == CODE_FOR_unpackv1ti
- || icode == CODE_FOR_unpackkf
- || icode == CODE_FOR_unpacktf
- || icode == CODE_FOR_unpackif
- || icode == CODE_FOR_unpacktd)
- {
- /* Only allow 1-bit unsigned literals. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 1))
- {
- error ("argument 2 must be a 1-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_altivec_vspltw)
- {
- /* Only allow 2-bit unsigned literals. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || TREE_INT_CST_LOW (arg1) & ~3)
- {
- error ("argument 2 must be a 2-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_altivec_vsplth)
- {
- /* Only allow 3-bit unsigned literals. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || TREE_INT_CST_LOW (arg1) & ~7)
- {
- error ("argument 2 must be a 3-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_altivec_vspltb)
- {
- /* Only allow 4-bit unsigned literals. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || TREE_INT_CST_LOW (arg1) & ~15)
- {
- error ("argument 2 must be a 4-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_altivec_vcfux
- || icode == CODE_FOR_altivec_vcfsx
- || icode == CODE_FOR_altivec_vctsxs
- || icode == CODE_FOR_altivec_vctuxs)
- {
- /* Only allow 5-bit unsigned literals. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || TREE_INT_CST_LOW (arg1) & ~0x1f)
- {
- error ("argument 2 must be a 5-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_dfptstsfi_eq_dd
- || icode == CODE_FOR_dfptstsfi_lt_dd
- || icode == CODE_FOR_dfptstsfi_gt_dd
- || icode == CODE_FOR_dfptstsfi_unordered_dd
- || icode == CODE_FOR_dfptstsfi_eq_td
- || icode == CODE_FOR_dfptstsfi_lt_td
- || icode == CODE_FOR_dfptstsfi_gt_td
- || icode == CODE_FOR_dfptstsfi_unordered_td)
- {
- /* Only allow 6-bit unsigned literals. */
- STRIP_NOPS (arg0);
- if (TREE_CODE (arg0) != INTEGER_CST
- || !IN_RANGE (TREE_INT_CST_LOW (arg0), 0, 63))
- {
- error ("argument 1 must be a 6-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_xststdcqp_kf
- || icode == CODE_FOR_xststdcqp_tf
- || icode == CODE_FOR_xststdcdp
- || icode == CODE_FOR_xststdcsp
- || icode == CODE_FOR_xvtstdcdp
- || icode == CODE_FOR_xvtstdcsp)
- {
- /* Only allow 7-bit unsigned literals. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || !IN_RANGE (TREE_INT_CST_LOW (arg1), 0, 127))
- {
- error ("argument 2 must be a 7-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- pat = GEN_FCN (icode) (target, op0, op1);
- if (! pat)
- return 0;
- emit_insn (pat);
-
- return target;
-}
-
-static rtx
-altivec_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
-{
- rtx pat, scratch;
- tree cr6_form = CALL_EXPR_ARG (exp, 0);
- tree arg0 = CALL_EXPR_ARG (exp, 1);
- tree arg1 = CALL_EXPR_ARG (exp, 2);
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- machine_mode tmode = SImode;
- machine_mode mode0 = insn_data[icode].operand[1].mode;
- machine_mode mode1 = insn_data[icode].operand[2].mode;
- int cr6_form_int;
-
- if (TREE_CODE (cr6_form) != INTEGER_CST)
- {
- error ("argument 1 of %qs must be a constant",
- "__builtin_altivec_predicate");
- return const0_rtx;
- }
- else
- cr6_form_int = TREE_INT_CST_LOW (cr6_form);
-
- gcc_assert (mode0 == mode1);
-
- /* If we have invalid arguments, bail out before generating bad rtl. */
- if (arg0 == error_mark_node || arg1 == error_mark_node)
- return const0_rtx;
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- /* Note that for many of the relevant operations (e.g. cmpne or
- cmpeq) with float or double operands, it makes more sense for the
- mode of the allocated scratch register to select a vector of
- integer. But the choice to copy the mode of operand 0 was made
- long ago and there are no plans to change it. */
- scratch = gen_reg_rtx (mode0);
-
- pat = GEN_FCN (icode) (scratch, op0, op1);
- if (! pat)
- return 0;
- emit_insn (pat);
-
- /* The vec_any* and vec_all* predicates use the same opcodes for two
- different operations, but the bits in CR6 will be different
- depending on what information we want. So we have to play tricks
- with CR6 to get the right bits out.
-
- If you think this is disgusting, look at the specs for the
- AltiVec predicates. */
-
- switch (cr6_form_int)
- {
- case 0:
- emit_insn (gen_cr6_test_for_zero (target));
- break;
- case 1:
- emit_insn (gen_cr6_test_for_zero_reverse (target));
- break;
- case 2:
- emit_insn (gen_cr6_test_for_lt (target));
- break;
- case 3:
- emit_insn (gen_cr6_test_for_lt_reverse (target));
- break;
- default:
- error ("argument 1 of %qs is out of range",
- "__builtin_altivec_predicate");
- break;
- }
-
- return target;
-}
-
-rtx
-swap_endian_selector_for_mode (machine_mode mode)
-{
- unsigned int swap1[16] = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
- unsigned int swap2[16] = {7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8};
- unsigned int swap4[16] = {3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12};
- unsigned int swap8[16] = {1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14};
-
- unsigned int *swaparray, i;
- rtx perm[16];
-
- switch (mode)
- {
- case E_V1TImode:
- swaparray = swap1;
- break;
- case E_V2DFmode:
- case E_V2DImode:
- swaparray = swap2;
- break;
- case E_V4SFmode:
- case E_V4SImode:
- swaparray = swap4;
- break;
- case E_V8HImode:
- swaparray = swap8;
- break;
- default:
- gcc_unreachable ();
- }
-
- for (i = 0; i < 16; ++i)
- perm[i] = GEN_INT (swaparray[i]);
-
- return force_reg (V16QImode, gen_rtx_CONST_VECTOR (V16QImode,
- gen_rtvec_v (16, perm)));
-}
-
-static rtx
-altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target, bool blk)
-{
- rtx pat, addr;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- machine_mode tmode = insn_data[icode].operand[0].mode;
- machine_mode mode0 = Pmode;
- machine_mode mode1 = Pmode;
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node || arg1 == error_mark_node)
- return const0_rtx;
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- op1 = copy_to_mode_reg (mode1, op1);
-
- /* For LVX, express the RTL accurately by ANDing the address with -16.
- LVXL and LVE*X expand to use UNSPECs to hide their special behavior,
- so the raw address is fine. */
- if (icode == CODE_FOR_altivec_lvx_v1ti
- || icode == CODE_FOR_altivec_lvx_v2df
- || icode == CODE_FOR_altivec_lvx_v2di
- || icode == CODE_FOR_altivec_lvx_v4sf
- || icode == CODE_FOR_altivec_lvx_v4si
- || icode == CODE_FOR_altivec_lvx_v8hi
- || icode == CODE_FOR_altivec_lvx_v16qi)
- {
- rtx rawaddr;
- if (op0 == const0_rtx)
- rawaddr = op1;
- else
- {
- op0 = copy_to_mode_reg (mode0, op0);
- rawaddr = gen_rtx_PLUS (Pmode, op1, op0);
- }
- addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
- addr = gen_rtx_MEM (blk ? BLKmode : tmode, addr);
-
- emit_insn (gen_rtx_SET (target, addr));
- }
- else
- {
- if (op0 == const0_rtx)
- addr = gen_rtx_MEM (blk ? BLKmode : tmode, op1);
- else
- {
- op0 = copy_to_mode_reg (mode0, op0);
- addr = gen_rtx_MEM (blk ? BLKmode : tmode,
- gen_rtx_PLUS (Pmode, op1, op0));
- }
-
- pat = GEN_FCN (icode) (target, addr);
- if (! pat)
- return 0;
- emit_insn (pat);
- }
-
- return target;
-}
-
-static rtx
-altivec_expand_stxvl_builtin (enum insn_code icode, tree exp)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- tree arg2 = CALL_EXPR_ARG (exp, 2);
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- rtx op2 = expand_normal (arg2);
- machine_mode mode0 = insn_data[icode].operand[0].mode;
- machine_mode mode1 = insn_data[icode].operand[1].mode;
- machine_mode mode2 = insn_data[icode].operand[2].mode;
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return NULL_RTX;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node
- || arg1 == error_mark_node
- || arg2 == error_mark_node)
- return NULL_RTX;
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
- if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
- op2 = copy_to_mode_reg (mode2, op2);
-
- pat = GEN_FCN (icode) (op0, op1, op2);
- if (pat)
- emit_insn (pat);
-
- return NULL_RTX;
-}
-
-static rtx
-altivec_expand_stv_builtin (enum insn_code icode, tree exp)
-{
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- tree arg2 = CALL_EXPR_ARG (exp, 2);
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- rtx op2 = expand_normal (arg2);
- rtx pat, addr, rawaddr;
- machine_mode tmode = insn_data[icode].operand[0].mode;
- machine_mode smode = insn_data[icode].operand[1].mode;
- machine_mode mode1 = Pmode;
- machine_mode mode2 = Pmode;
-
- /* Invalid arguments. Bail before doing anything stoopid! */
- if (arg0 == error_mark_node
- || arg1 == error_mark_node
- || arg2 == error_mark_node)
- return const0_rtx;
-
- op2 = copy_to_mode_reg (mode2, op2);
-
- /* For STVX, express the RTL accurately by ANDing the address with -16.
- STVXL and STVE*X expand to use UNSPECs to hide their special behavior,
- so the raw address is fine. */
- if (icode == CODE_FOR_altivec_stvx_v2df
- || icode == CODE_FOR_altivec_stvx_v2di
- || icode == CODE_FOR_altivec_stvx_v4sf
- || icode == CODE_FOR_altivec_stvx_v4si
- || icode == CODE_FOR_altivec_stvx_v8hi
- || icode == CODE_FOR_altivec_stvx_v16qi)
- {
- if (op1 == const0_rtx)
- rawaddr = op2;
- else
- {
- op1 = copy_to_mode_reg (mode1, op1);
- rawaddr = gen_rtx_PLUS (Pmode, op2, op1);
- }
-
- addr = gen_rtx_AND (Pmode, rawaddr, gen_rtx_CONST_INT (Pmode, -16));
- addr = gen_rtx_MEM (tmode, addr);
-
- op0 = copy_to_mode_reg (tmode, op0);
-
- emit_insn (gen_rtx_SET (addr, op0));
- }
- else
- {
- if (! (*insn_data[icode].operand[1].predicate) (op0, smode))
- op0 = copy_to_mode_reg (smode, op0);
-
- if (op1 == const0_rtx)
- addr = gen_rtx_MEM (tmode, op2);
- else
- {
- op1 = copy_to_mode_reg (mode1, op1);
- addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op2, op1));
- }
-
- pat = GEN_FCN (icode) (addr, op0);
- if (pat)
- emit_insn (pat);
- }
-
- return NULL_RTX;
-}
-
-/* Return the appropriate SPR number associated with the given builtin. */
-static inline HOST_WIDE_INT
-htm_spr_num (enum rs6000_builtins code)
-{
- if (code == HTM_BUILTIN_GET_TFHAR
- || code == HTM_BUILTIN_SET_TFHAR)
- return TFHAR_SPR;
- else if (code == HTM_BUILTIN_GET_TFIAR
- || code == HTM_BUILTIN_SET_TFIAR)
- return TFIAR_SPR;
- else if (code == HTM_BUILTIN_GET_TEXASR
- || code == HTM_BUILTIN_SET_TEXASR)
- return TEXASR_SPR;
- gcc_assert (code == HTM_BUILTIN_GET_TEXASRU
- || code == HTM_BUILTIN_SET_TEXASRU);
- return TEXASRU_SPR;
-}
-
-/* Return the correct ICODE value depending on whether we are
- setting or reading the HTM SPRs. */
-static inline enum insn_code
-rs6000_htm_spr_icode (bool nonvoid)
-{
- if (nonvoid)
- return (TARGET_POWERPC64) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si;
- else
- return (TARGET_POWERPC64) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si;
-}
-
-/* Expand the HTM builtin in EXP and store the result in TARGET.
- Store true in *EXPANDEDP if we found a builtin to expand. */
-static rtx
-htm_expand_builtin (tree exp, rtx target, bool * expandedp)
-{
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
- enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
- const struct builtin_description *d;
- size_t i;
-
- *expandedp = true;
-
- if (!TARGET_POWERPC64
- && (fcode == HTM_BUILTIN_TABORTDC
- || fcode == HTM_BUILTIN_TABORTDCI))
- {
- size_t uns_fcode = (size_t)fcode;
- const char *name = rs6000_builtin_info[uns_fcode].name;
- error ("builtin %qs is only valid in 64-bit mode", name);
- return const0_rtx;
- }
-
- /* Expand the HTM builtins. */
- d = bdesc_htm;
- for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
- if (d->code == fcode)
- {
- rtx op[MAX_HTM_OPERANDS], pat;
- int nopnds = 0;
- tree arg;
- call_expr_arg_iterator iter;
- unsigned attr = rs6000_builtin_info[fcode].attr;
- enum insn_code icode = d->icode;
- const struct insn_operand_data *insn_op;
- bool uses_spr = (attr & RS6000_BTC_SPR);
- rtx cr = NULL_RTX;
-
- if (uses_spr)
- icode = rs6000_htm_spr_icode (nonvoid);
- insn_op = &insn_data[icode].operand[0];
-
- if (nonvoid)
- {
- machine_mode tmode = (uses_spr) ? insn_op->mode : E_SImode;
- if (!target
- || GET_MODE (target) != tmode
- || (uses_spr && !(*insn_op->predicate) (target, tmode)))
- target = gen_reg_rtx (tmode);
- if (uses_spr)
- op[nopnds++] = target;
- }
-
- FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
- {
- if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS)
- return const0_rtx;
-
- insn_op = &insn_data[icode].operand[nopnds];
-
- op[nopnds] = expand_normal (arg);
-
- if (!(*insn_op->predicate) (op[nopnds], insn_op->mode))
- {
- if (!strcmp (insn_op->constraint, "n"))
- {
- int arg_num = (nonvoid) ? nopnds : nopnds + 1;
- if (!CONST_INT_P (op[nopnds]))
- error ("argument %d must be an unsigned literal", arg_num);
- else
- error ("argument %d is an unsigned literal that is "
- "out of range", arg_num);
- return const0_rtx;
- }
- op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]);
- }
-
- nopnds++;
- }
-
- /* Handle the builtins for extended mnemonics. These accept
- no arguments, but map to builtins that take arguments. */
- switch (fcode)
- {
- case HTM_BUILTIN_TENDALL: /* Alias for: tend. 1 */
- case HTM_BUILTIN_TRESUME: /* Alias for: tsr. 1 */
- op[nopnds++] = GEN_INT (1);
- if (flag_checking)
- attr |= RS6000_BTC_UNARY;
- break;
- case HTM_BUILTIN_TSUSPEND: /* Alias for: tsr. 0 */
- op[nopnds++] = GEN_INT (0);
- if (flag_checking)
- attr |= RS6000_BTC_UNARY;
- break;
- default:
- break;
- }
-
- /* If this builtin accesses SPRs, then pass in the appropriate
- SPR number and SPR regno as the last two operands. */
- if (uses_spr)
- {
- machine_mode mode = (TARGET_POWERPC64) ? DImode : SImode;
- op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode));
- }
- /* If this builtin accesses a CR, then pass in a scratch
- CR as the last operand. */
- else if (attr & RS6000_BTC_CR)
- { cr = gen_reg_rtx (CCmode);
- op[nopnds++] = cr;
- }
-
- if (flag_checking)
- {
- int expected_nopnds = 0;
- if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_UNARY)
- expected_nopnds = 1;
- else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_BINARY)
- expected_nopnds = 2;
- else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_TERNARY)
- expected_nopnds = 3;
- if (!(attr & RS6000_BTC_VOID))
- expected_nopnds += 1;
- if (uses_spr)
- expected_nopnds += 1;
-
- gcc_assert (nopnds == expected_nopnds
- && nopnds <= MAX_HTM_OPERANDS);
- }
-
- switch (nopnds)
- {
- case 1:
- pat = GEN_FCN (icode) (op[0]);
- break;
- case 2:
- pat = GEN_FCN (icode) (op[0], op[1]);
- break;
- case 3:
- pat = GEN_FCN (icode) (op[0], op[1], op[2]);
- break;
- case 4:
- pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
- break;
- default:
- gcc_unreachable ();
- }
- if (!pat)
- return NULL_RTX;
- emit_insn (pat);
-
- if (attr & RS6000_BTC_CR)
- {
- if (fcode == HTM_BUILTIN_TBEGIN)
- {
- /* Emit code to set TARGET to true or false depending on
- whether the tbegin. instruction successfully or failed
- to start a transaction. We do this by placing the 1's
- complement of CR's EQ bit into TARGET. */
- rtx scratch = gen_reg_rtx (SImode);
- emit_insn (gen_rtx_SET (scratch,
- gen_rtx_EQ (SImode, cr,
- const0_rtx)));
- emit_insn (gen_rtx_SET (target,
- gen_rtx_XOR (SImode, scratch,
- GEN_INT (1))));
- }
- else
- {
- /* Emit code to copy the 4-bit condition register field
- CR into the least significant end of register TARGET. */
- rtx scratch1 = gen_reg_rtx (SImode);
- rtx scratch2 = gen_reg_rtx (SImode);
- rtx subreg = simplify_gen_subreg (CCmode, scratch1, SImode, 0);
- emit_insn (gen_movcc (subreg, cr));
- emit_insn (gen_lshrsi3 (scratch2, scratch1, GEN_INT (28)));
- emit_insn (gen_andsi3 (target, scratch2, GEN_INT (0xf)));
- }
- }
-
- if (nonvoid)
- return target;
- return const0_rtx;
- }
-
- *expandedp = false;
- return NULL_RTX;
-}
-
-/* Expand the CPU builtin in FCODE and store the result in TARGET. */
-
-static rtx
-cpu_expand_builtin (enum rs6000_builtins fcode, tree exp ATTRIBUTE_UNUSED,
- rtx target)
-{
- /* __builtin_cpu_init () is a nop, so expand to nothing. */
- if (fcode == RS6000_BUILTIN_CPU_INIT)
- return const0_rtx;
-
- if (target == 0 || GET_MODE (target) != SImode)
- target = gen_reg_rtx (SImode);
-
-#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
- tree arg = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
- /* Target clones creates an ARRAY_REF instead of STRING_CST, convert it back
- to a STRING_CST. */
- if (TREE_CODE (arg) == ARRAY_REF
- && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST
- && TREE_CODE (TREE_OPERAND (arg, 1)) == INTEGER_CST
- && compare_tree_int (TREE_OPERAND (arg, 1), 0) == 0)
- arg = TREE_OPERAND (arg, 0);
-
- if (TREE_CODE (arg) != STRING_CST)
- {
- error ("builtin %qs only accepts a string argument",
- rs6000_builtin_info[(size_t) fcode].name);
- return const0_rtx;
- }
-
- if (fcode == RS6000_BUILTIN_CPU_IS)
- {
- const char *cpu = TREE_STRING_POINTER (arg);
- rtx cpuid = NULL_RTX;
- for (size_t i = 0; i < ARRAY_SIZE (cpu_is_info); i++)
- if (strcmp (cpu, cpu_is_info[i].cpu) == 0)
- {
- /* The CPUID value in the TCB is offset by _DL_FIRST_PLATFORM. */
- cpuid = GEN_INT (cpu_is_info[i].cpuid + _DL_FIRST_PLATFORM);
- break;
- }
- if (cpuid == NULL_RTX)
- {
- /* Invalid CPU argument. */
- error ("cpu %qs is an invalid argument to builtin %qs",
- cpu, rs6000_builtin_info[(size_t) fcode].name);
- return const0_rtx;
- }
-
- rtx platform = gen_reg_rtx (SImode);
- rtx tcbmem = gen_const_mem (SImode,
- gen_rtx_PLUS (Pmode,
- gen_rtx_REG (Pmode, TLS_REGNUM),
- GEN_INT (TCB_PLATFORM_OFFSET)));
- emit_move_insn (platform, tcbmem);
- emit_insn (gen_eqsi3 (target, platform, cpuid));
- }
- else if (fcode == RS6000_BUILTIN_CPU_SUPPORTS)
- {
- const char *hwcap = TREE_STRING_POINTER (arg);
- rtx mask = NULL_RTX;
- int hwcap_offset;
- for (size_t i = 0; i < ARRAY_SIZE (cpu_supports_info); i++)
- if (strcmp (hwcap, cpu_supports_info[i].hwcap) == 0)
- {
- mask = GEN_INT (cpu_supports_info[i].mask);
- hwcap_offset = TCB_HWCAP_OFFSET (cpu_supports_info[i].id);
- break;
- }
- if (mask == NULL_RTX)
- {
- /* Invalid HWCAP argument. */
- error ("%s %qs is an invalid argument to builtin %qs",
- "hwcap", hwcap, rs6000_builtin_info[(size_t) fcode].name);
- return const0_rtx;
- }
-
- rtx tcb_hwcap = gen_reg_rtx (SImode);
- rtx tcbmem = gen_const_mem (SImode,
- gen_rtx_PLUS (Pmode,
- gen_rtx_REG (Pmode, TLS_REGNUM),
- GEN_INT (hwcap_offset)));
- emit_move_insn (tcb_hwcap, tcbmem);
- rtx scratch1 = gen_reg_rtx (SImode);
- emit_insn (gen_rtx_SET (scratch1, gen_rtx_AND (SImode, tcb_hwcap, mask)));
- rtx scratch2 = gen_reg_rtx (SImode);
- emit_insn (gen_eqsi3 (scratch2, scratch1, const0_rtx));
- emit_insn (gen_rtx_SET (target, gen_rtx_XOR (SImode, scratch2, const1_rtx)));
- }
- else
- gcc_unreachable ();
-
- /* Record that we have expanded a CPU builtin, so that we can later
- emit a reference to the special symbol exported by LIBC to ensure we
- do not link against an old LIBC that doesn't support this feature. */
- cpu_builtin_p = true;
-
-#else
- warning (0, "builtin %qs needs GLIBC (2.23 and newer) that exports hardware "
- "capability bits", rs6000_builtin_info[(size_t) fcode].name);
-
- /* For old LIBCs, always return FALSE. */
- emit_move_insn (target, GEN_INT (0));
-#endif /* TARGET_LIBC_PROVIDES_HWCAP_IN_TCB */
-
- return target;
-}
-
-static rtx
-rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
-{
- rtx pat;
- tree arg0 = CALL_EXPR_ARG (exp, 0);
- tree arg1 = CALL_EXPR_ARG (exp, 1);
- tree arg2 = CALL_EXPR_ARG (exp, 2);
- rtx op0 = expand_normal (arg0);
- rtx op1 = expand_normal (arg1);
- rtx op2 = expand_normal (arg2);
- machine_mode tmode = insn_data[icode].operand[0].mode;
- machine_mode mode0 = insn_data[icode].operand[1].mode;
- machine_mode mode1 = insn_data[icode].operand[2].mode;
- machine_mode mode2 = insn_data[icode].operand[3].mode;
-
- if (icode == CODE_FOR_nothing)
- /* Builtin not supported on this processor. */
- return 0;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node
- || arg1 == error_mark_node
- || arg2 == error_mark_node)
- return const0_rtx;
-
- /* Check and prepare argument depending on the instruction code.
-
- Note that a switch statement instead of the sequence of tests
- would be incorrect as many of the CODE_FOR values could be
- CODE_FOR_nothing and that would yield multiple alternatives
- with identical values. We'd never reach here at runtime in
- this case. */
- if (icode == CODE_FOR_altivec_vsldoi_v4sf
- || icode == CODE_FOR_altivec_vsldoi_v2df
- || icode == CODE_FOR_altivec_vsldoi_v4si
- || icode == CODE_FOR_altivec_vsldoi_v8hi
- || icode == CODE_FOR_altivec_vsldoi_v16qi)
- {
- /* Only allow 4-bit unsigned literals. */
- STRIP_NOPS (arg2);
- if (TREE_CODE (arg2) != INTEGER_CST
- || TREE_INT_CST_LOW (arg2) & ~0xf)
- {
- error ("argument 3 must be a 4-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_vsx_xxpermdi_v2df
- || icode == CODE_FOR_vsx_xxpermdi_v2di
- || icode == CODE_FOR_vsx_xxpermdi_v2df_be
- || icode == CODE_FOR_vsx_xxpermdi_v2di_be
- || icode == CODE_FOR_vsx_xxpermdi_v1ti
- || icode == CODE_FOR_vsx_xxpermdi_v4sf
- || icode == CODE_FOR_vsx_xxpermdi_v4si
- || icode == CODE_FOR_vsx_xxpermdi_v8hi
- || icode == CODE_FOR_vsx_xxpermdi_v16qi
- || icode == CODE_FOR_vsx_xxsldwi_v16qi
- || icode == CODE_FOR_vsx_xxsldwi_v8hi
- || icode == CODE_FOR_vsx_xxsldwi_v4si
- || icode == CODE_FOR_vsx_xxsldwi_v4sf
- || icode == CODE_FOR_vsx_xxsldwi_v2di
- || icode == CODE_FOR_vsx_xxsldwi_v2df)
- {
- /* Only allow 2-bit unsigned literals. */
- STRIP_NOPS (arg2);
- if (TREE_CODE (arg2) != INTEGER_CST
- || TREE_INT_CST_LOW (arg2) & ~0x3)
- {
- error ("argument 3 must be a 2-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_vsx_set_v2df
- || icode == CODE_FOR_vsx_set_v2di
- || icode == CODE_FOR_bcdadd
- || icode == CODE_FOR_bcdadd_lt
- || icode == CODE_FOR_bcdadd_eq
- || icode == CODE_FOR_bcdadd_gt
- || icode == CODE_FOR_bcdsub
- || icode == CODE_FOR_bcdsub_lt
- || icode == CODE_FOR_bcdsub_eq
- || icode == CODE_FOR_bcdsub_gt)
- {
- /* Only allow 1-bit unsigned literals. */
- STRIP_NOPS (arg2);
- if (TREE_CODE (arg2) != INTEGER_CST
- || TREE_INT_CST_LOW (arg2) & ~0x1)
- {
- error ("argument 3 must be a 1-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_dfp_ddedpd_dd
- || icode == CODE_FOR_dfp_ddedpd_td)
- {
- /* Only allow 2-bit unsigned literals where the value is 0 or 2. */
- STRIP_NOPS (arg0);
- if (TREE_CODE (arg0) != INTEGER_CST
- || TREE_INT_CST_LOW (arg2) & ~0x3)
- {
- error ("argument 1 must be 0 or 2");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_dfp_denbcd_dd
- || icode == CODE_FOR_dfp_denbcd_td)
- {
- /* Only allow 1-bit unsigned literals. */
- STRIP_NOPS (arg0);
- if (TREE_CODE (arg0) != INTEGER_CST
- || TREE_INT_CST_LOW (arg0) & ~0x1)
- {
- error ("argument 1 must be a 1-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_dfp_dscli_dd
- || icode == CODE_FOR_dfp_dscli_td
- || icode == CODE_FOR_dfp_dscri_dd
- || icode == CODE_FOR_dfp_dscri_td)
- {
- /* Only allow 6-bit unsigned literals. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST
- || TREE_INT_CST_LOW (arg1) & ~0x3f)
- {
- error ("argument 2 must be a 6-bit unsigned literal");
- return CONST0_RTX (tmode);
- }
- }
- else if (icode == CODE_FOR_crypto_vshasigmaw
- || icode == CODE_FOR_crypto_vshasigmad)
- {
- /* Check whether the 2nd and 3rd arguments are integer constants and in
- range and prepare arguments. */
- STRIP_NOPS (arg1);
- if (TREE_CODE (arg1) != INTEGER_CST || wi::geu_p (wi::to_wide (arg1), 2))
- {
- error ("argument 2 must be 0 or 1");
- return CONST0_RTX (tmode);
- }
-
- STRIP_NOPS (arg2);
- if (TREE_CODE (arg2) != INTEGER_CST
- || wi::geu_p (wi::to_wide (arg2), 16))
- {
- error ("argument 3 must be in the range [0, 15]");
- return CONST0_RTX (tmode);
- }
- }
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
- if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
- if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
- op2 = copy_to_mode_reg (mode2, op2);
-
- pat = GEN_FCN (icode) (target, op0, op1, op2);
- if (! pat)
- return 0;
- emit_insn (pat);
-
- return target;
-}
-
-
-/* Expand the dst builtins. */
-static rtx
-altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
- bool *expandedp)
-{
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
- tree arg0, arg1, arg2;
- machine_mode mode0, mode1;
- rtx pat, op0, op1, op2;
- const struct builtin_description *d;
- size_t i;
-
- *expandedp = false;
-
- /* Handle DST variants. */
- d = bdesc_dst;
- for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
- if (d->code == fcode)
- {
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
- arg2 = CALL_EXPR_ARG (exp, 2);
- op0 = expand_normal (arg0);
- op1 = expand_normal (arg1);
- op2 = expand_normal (arg2);
- mode0 = insn_data[d->icode].operand[0].mode;
- mode1 = insn_data[d->icode].operand[1].mode;
-
- /* Invalid arguments, bail out before generating bad rtl. */
- if (arg0 == error_mark_node
- || arg1 == error_mark_node
- || arg2 == error_mark_node)
- return const0_rtx;
-
- *expandedp = true;
- STRIP_NOPS (arg2);
- if (TREE_CODE (arg2) != INTEGER_CST
- || TREE_INT_CST_LOW (arg2) & ~0x3)
- {
- error ("argument to %qs must be a 2-bit unsigned literal", d->name);
- return const0_rtx;
- }
-
- if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (Pmode, op0);
- if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
- op1 = copy_to_mode_reg (mode1, op1);
-
- pat = GEN_FCN (d->icode) (op0, op1, op2);
- if (pat != 0)
- emit_insn (pat);
-
- return NULL_RTX;
- }
-
- return NULL_RTX;
-}
-
-/* Expand vec_init builtin. */
-static rtx
-altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
-{
- machine_mode tmode = TYPE_MODE (type);
- machine_mode inner_mode = GET_MODE_INNER (tmode);
- int i, n_elt = GET_MODE_NUNITS (tmode);
-
- gcc_assert (VECTOR_MODE_P (tmode));
- gcc_assert (n_elt == call_expr_nargs (exp));
-
- if (!target || !register_operand (target, tmode))
- target = gen_reg_rtx (tmode);
-
- /* If we have a vector compromised of a single element, such as V1TImode, do
- the initialization directly. */
- if (n_elt == 1 && GET_MODE_SIZE (tmode) == GET_MODE_SIZE (inner_mode))
- {
- rtx x = expand_normal (CALL_EXPR_ARG (exp, 0));
- emit_move_insn (target, gen_lowpart (tmode, x));
- }
- else
- {
- rtvec v = rtvec_alloc (n_elt);
-
- for (i = 0; i < n_elt; ++i)
- {
- rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
- RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
- }
-
- rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
- }
-
- return target;
-}
-
-/* Return the integer constant in ARG. Constrain it to be in the range
- of the subparts of VEC_TYPE; issue an error if not. */
-
-static int
-get_element_number (tree vec_type, tree arg)
-{
- unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
-
- if (!tree_fits_uhwi_p (arg)
- || (elt = tree_to_uhwi (arg), elt > max))
- {
- error ("selector must be an integer constant in the range [0, %wi]", max);
- return 0;
- }
-
- return elt;
-}
-
-/* Expand vec_set builtin. */
-static rtx
-altivec_expand_vec_set_builtin (tree exp)
-{
- machine_mode tmode, mode1;
- tree arg0, arg1, arg2;
- int elt;
- rtx op0, op1;
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
- arg2 = CALL_EXPR_ARG (exp, 2);
-
- tmode = TYPE_MODE (TREE_TYPE (arg0));
- mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
- gcc_assert (VECTOR_MODE_P (tmode));
-
- op0 = expand_expr (arg0, NULL_RTX, tmode, EXPAND_NORMAL);
- op1 = expand_expr (arg1, NULL_RTX, mode1, EXPAND_NORMAL);
- elt = get_element_number (TREE_TYPE (arg0), arg2);
-
- if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
- op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
-
- op0 = force_reg (tmode, op0);
- op1 = force_reg (mode1, op1);
-
- rs6000_expand_vector_set (op0, op1, elt);
-
- return op0;
-}
-
-/* Expand vec_ext builtin. */
-static rtx
-altivec_expand_vec_ext_builtin (tree exp, rtx target)
-{
- machine_mode tmode, mode0;
- tree arg0, arg1;
- rtx op0;
- rtx op1;
-
- arg0 = CALL_EXPR_ARG (exp, 0);
- arg1 = CALL_EXPR_ARG (exp, 1);
-
- op0 = expand_normal (arg0);
- op1 = expand_normal (arg1);
-
- if (TREE_CODE (arg1) == INTEGER_CST)
- {
- unsigned HOST_WIDE_INT elt;
- unsigned HOST_WIDE_INT size = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
- unsigned int truncated_selector;
- /* Even if !tree_fits_uhwi_p (arg1)), TREE_INT_CST_LOW (arg0)
- returns low-order bits of INTEGER_CST for modulo indexing. */
- elt = TREE_INT_CST_LOW (arg1);
- truncated_selector = elt % size;
- op1 = GEN_INT (truncated_selector);
- }
-
- tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
- mode0 = TYPE_MODE (TREE_TYPE (arg0));
- gcc_assert (VECTOR_MODE_P (mode0));
-
- op0 = force_reg (mode0, op0);
-
- if (optimize || !target || !register_operand (target, tmode))
- target = gen_reg_rtx (tmode);
-
- rs6000_expand_vector_extract (target, op0, op1);
-
- return target;
-}
-
-/* Expand the builtin in EXP and store the result in TARGET. Store
- true in *EXPANDEDP if we found a builtin to expand. */
-static rtx
-altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
-{
- const struct builtin_description *d;
- size_t i;
- enum insn_code icode;
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- tree arg0, arg1, arg2;
- rtx op0, pat;
- machine_mode tmode, mode0;
- enum rs6000_builtins fcode
- = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
-
- if (rs6000_overloaded_builtin_p (fcode))
- {
- *expandedp = true;
- error ("unresolved overload for Altivec builtin %qF", fndecl);
-
- /* Given it is invalid, just generate a normal call. */
- return expand_call (exp, target, false);
- }
-
- target = altivec_expand_dst_builtin (exp, target, expandedp);
- if (*expandedp)
- return target;
-
- *expandedp = true;
-
- switch (fcode)
- {
- case ALTIVEC_BUILTIN_STVX_V2DF:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2df, exp);
- case ALTIVEC_BUILTIN_STVX_V2DI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v2di, exp);
- case ALTIVEC_BUILTIN_STVX_V4SF:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4sf, exp);
- case ALTIVEC_BUILTIN_STVX:
- case ALTIVEC_BUILTIN_STVX_V4SI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v4si, exp);
- case ALTIVEC_BUILTIN_STVX_V8HI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v8hi, exp);
- case ALTIVEC_BUILTIN_STVX_V16QI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx_v16qi, exp);
- case ALTIVEC_BUILTIN_STVEBX:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
- case ALTIVEC_BUILTIN_STVEHX:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
- case ALTIVEC_BUILTIN_STVEWX:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
- case ALTIVEC_BUILTIN_STVXL_V2DF:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v2df, exp);
- case ALTIVEC_BUILTIN_STVXL_V2DI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v2di, exp);
- case ALTIVEC_BUILTIN_STVXL_V4SF:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v4sf, exp);
- case ALTIVEC_BUILTIN_STVXL:
- case ALTIVEC_BUILTIN_STVXL_V4SI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v4si, exp);
- case ALTIVEC_BUILTIN_STVXL_V8HI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v8hi, exp);
- case ALTIVEC_BUILTIN_STVXL_V16QI:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl_v16qi, exp);
-
- case ALTIVEC_BUILTIN_STVLX:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlx, exp);
- case ALTIVEC_BUILTIN_STVLXL:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvlxl, exp);
- case ALTIVEC_BUILTIN_STVRX:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrx, exp);
- case ALTIVEC_BUILTIN_STVRXL:
- return altivec_expand_stv_builtin (CODE_FOR_altivec_stvrxl, exp);
-
- case P9V_BUILTIN_STXVL:
- return altivec_expand_stxvl_builtin (CODE_FOR_stxvl, exp);
-
- case P9V_BUILTIN_XST_LEN_R:
- return altivec_expand_stxvl_builtin (CODE_FOR_xst_len_r, exp);
-
- case VSX_BUILTIN_STXVD2X_V1TI:
- return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v1ti, exp);
- case VSX_BUILTIN_STXVD2X_V2DF:
- return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2df, exp);
- case VSX_BUILTIN_STXVD2X_V2DI:
- return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v2di, exp);
- case VSX_BUILTIN_STXVW4X_V4SF:
- return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4sf, exp);
- case VSX_BUILTIN_STXVW4X_V4SI:
- return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v4si, exp);
- case VSX_BUILTIN_STXVW4X_V8HI:
- return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v8hi, exp);
- case VSX_BUILTIN_STXVW4X_V16QI:
- return altivec_expand_stv_builtin (CODE_FOR_vsx_store_v16qi, exp);
-
- /* For the following on big endian, it's ok to use any appropriate
- unaligned-supporting store, so use a generic expander. For
- little-endian, the exact element-reversing instruction must
- be used. */
- case VSX_BUILTIN_ST_ELEMREV_V1TI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v1ti
- : CODE_FOR_vsx_st_elemrev_v1ti);
- return altivec_expand_stv_builtin (code, exp);
- }
- case VSX_BUILTIN_ST_ELEMREV_V2DF:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2df
- : CODE_FOR_vsx_st_elemrev_v2df);
- return altivec_expand_stv_builtin (code, exp);
- }
- case VSX_BUILTIN_ST_ELEMREV_V2DI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v2di
- : CODE_FOR_vsx_st_elemrev_v2di);
- return altivec_expand_stv_builtin (code, exp);
- }
- case VSX_BUILTIN_ST_ELEMREV_V4SF:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4sf
- : CODE_FOR_vsx_st_elemrev_v4sf);
- return altivec_expand_stv_builtin (code, exp);
- }
- case VSX_BUILTIN_ST_ELEMREV_V4SI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v4si
- : CODE_FOR_vsx_st_elemrev_v4si);
- return altivec_expand_stv_builtin (code, exp);
- }
- case VSX_BUILTIN_ST_ELEMREV_V8HI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v8hi
- : CODE_FOR_vsx_st_elemrev_v8hi);
- return altivec_expand_stv_builtin (code, exp);
- }
- case VSX_BUILTIN_ST_ELEMREV_V16QI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_store_v16qi
- : CODE_FOR_vsx_st_elemrev_v16qi);
- return altivec_expand_stv_builtin (code, exp);
- }
-
- case ALTIVEC_BUILTIN_MFVSCR:
- icode = CODE_FOR_altivec_mfvscr;
- tmode = insn_data[icode].operand[0].mode;
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- pat = GEN_FCN (icode) (target);
- if (! pat)
- return 0;
- emit_insn (pat);
- return target;
-
- case ALTIVEC_BUILTIN_MTVSCR:
- icode = CODE_FOR_altivec_mtvscr;
- arg0 = CALL_EXPR_ARG (exp, 0);
- op0 = expand_normal (arg0);
- mode0 = insn_data[icode].operand[0].mode;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node)
- return const0_rtx;
-
- if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- pat = GEN_FCN (icode) (op0);
- if (pat)
- emit_insn (pat);
- return NULL_RTX;
-
- case ALTIVEC_BUILTIN_DSSALL:
- emit_insn (gen_altivec_dssall ());
- return NULL_RTX;
-
- case ALTIVEC_BUILTIN_DSS:
- icode = CODE_FOR_altivec_dss;
- arg0 = CALL_EXPR_ARG (exp, 0);
- STRIP_NOPS (arg0);
- op0 = expand_normal (arg0);
- mode0 = insn_data[icode].operand[0].mode;
-
- /* If we got invalid arguments bail out before generating bad rtl. */
- if (arg0 == error_mark_node)
- return const0_rtx;
-
- if (TREE_CODE (arg0) != INTEGER_CST
- || TREE_INT_CST_LOW (arg0) & ~0x3)
- {
- error ("argument to %qs must be a 2-bit unsigned literal", "dss");
- return const0_rtx;
- }
-
- if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
-
- emit_insn (gen_altivec_dss (op0));
- return NULL_RTX;
-
- case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
- case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
- case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
- case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
- case VSX_BUILTIN_VEC_INIT_V2DF:
- case VSX_BUILTIN_VEC_INIT_V2DI:
- case VSX_BUILTIN_VEC_INIT_V1TI:
- return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
-
- case ALTIVEC_BUILTIN_VEC_SET_V4SI:
- case ALTIVEC_BUILTIN_VEC_SET_V8HI:
- case ALTIVEC_BUILTIN_VEC_SET_V16QI:
- case ALTIVEC_BUILTIN_VEC_SET_V4SF:
- case VSX_BUILTIN_VEC_SET_V2DF:
- case VSX_BUILTIN_VEC_SET_V2DI:
- case VSX_BUILTIN_VEC_SET_V1TI:
- return altivec_expand_vec_set_builtin (exp);
-
- case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
- case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
- case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
- case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
- case VSX_BUILTIN_VEC_EXT_V2DF:
- case VSX_BUILTIN_VEC_EXT_V2DI:
- case VSX_BUILTIN_VEC_EXT_V1TI:
- return altivec_expand_vec_ext_builtin (exp, target);
-
- case P9V_BUILTIN_VEC_EXTRACT4B:
- arg1 = CALL_EXPR_ARG (exp, 1);
- STRIP_NOPS (arg1);
-
- /* Generate a normal call if it is invalid. */
- if (arg1 == error_mark_node)
- return expand_call (exp, target, false);
-
- if (TREE_CODE (arg1) != INTEGER_CST || TREE_INT_CST_LOW (arg1) > 12)
- {
- error ("second argument to %qs must be [0, 12]", "vec_vextract4b");
- return expand_call (exp, target, false);
- }
- break;
-
- case P9V_BUILTIN_VEC_INSERT4B:
- arg2 = CALL_EXPR_ARG (exp, 2);
- STRIP_NOPS (arg2);
-
- /* Generate a normal call if it is invalid. */
- if (arg2 == error_mark_node)
- return expand_call (exp, target, false);
-
- if (TREE_CODE (arg2) != INTEGER_CST || TREE_INT_CST_LOW (arg2) > 12)
- {
- error ("third argument to %qs must be [0, 12]", "vec_vinsert4b");
- return expand_call (exp, target, false);
- }
- break;
-
- default:
- break;
- /* Fall through. */
- }
-
- /* Expand abs* operations. */
- d = bdesc_abs;
- for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
- if (d->code == fcode)
- return altivec_expand_abs_builtin (d->icode, exp, target);
-
- /* Expand the AltiVec predicates. */
- d = bdesc_altivec_preds;
- for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, d++)
- if (d->code == fcode)
- return altivec_expand_predicate_builtin (d->icode, exp, target);
-
- /* LV* are funky. We initialized them differently. */
- switch (fcode)
- {
- case ALTIVEC_BUILTIN_LVSL:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVSR:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVEBX:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVEHX:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVEWX:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVXL_V2DF:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v2df,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVXL_V2DI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v2di,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVXL_V4SF:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4sf,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVXL:
- case ALTIVEC_BUILTIN_LVXL_V4SI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v4si,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVXL_V8HI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v8hi,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVXL_V16QI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl_v16qi,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVX_V1TI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v1ti,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVX_V2DF:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2df,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVX_V2DI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v2di,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVX_V4SF:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4sf,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVX:
- case ALTIVEC_BUILTIN_LVX_V4SI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v4si,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVX_V8HI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v8hi,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVX_V16QI:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx_v16qi,
- exp, target, false);
- case ALTIVEC_BUILTIN_LVLX:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlx,
- exp, target, true);
- case ALTIVEC_BUILTIN_LVLXL:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvlxl,
- exp, target, true);
- case ALTIVEC_BUILTIN_LVRX:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrx,
- exp, target, true);
- case ALTIVEC_BUILTIN_LVRXL:
- return altivec_expand_lv_builtin (CODE_FOR_altivec_lvrxl,
- exp, target, true);
- case VSX_BUILTIN_LXVD2X_V1TI:
- return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v1ti,
- exp, target, false);
- case VSX_BUILTIN_LXVD2X_V2DF:
- return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2df,
- exp, target, false);
- case VSX_BUILTIN_LXVD2X_V2DI:
- return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v2di,
- exp, target, false);
- case VSX_BUILTIN_LXVW4X_V4SF:
- return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4sf,
- exp, target, false);
- case VSX_BUILTIN_LXVW4X_V4SI:
- return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v4si,
- exp, target, false);
- case VSX_BUILTIN_LXVW4X_V8HI:
- return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v8hi,
- exp, target, false);
- case VSX_BUILTIN_LXVW4X_V16QI:
- return altivec_expand_lv_builtin (CODE_FOR_vsx_load_v16qi,
- exp, target, false);
- /* For the following on big endian, it's ok to use any appropriate
- unaligned-supporting load, so use a generic expander. For
- little-endian, the exact element-reversing instruction must
- be used. */
- case VSX_BUILTIN_LD_ELEMREV_V2DF:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2df
- : CODE_FOR_vsx_ld_elemrev_v2df);
- return altivec_expand_lv_builtin (code, exp, target, false);
- }
- case VSX_BUILTIN_LD_ELEMREV_V1TI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v1ti
- : CODE_FOR_vsx_ld_elemrev_v1ti);
- return altivec_expand_lv_builtin (code, exp, target, false);
- }
- case VSX_BUILTIN_LD_ELEMREV_V2DI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v2di
- : CODE_FOR_vsx_ld_elemrev_v2di);
- return altivec_expand_lv_builtin (code, exp, target, false);
- }
- case VSX_BUILTIN_LD_ELEMREV_V4SF:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4sf
- : CODE_FOR_vsx_ld_elemrev_v4sf);
- return altivec_expand_lv_builtin (code, exp, target, false);
- }
- case VSX_BUILTIN_LD_ELEMREV_V4SI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v4si
- : CODE_FOR_vsx_ld_elemrev_v4si);
- return altivec_expand_lv_builtin (code, exp, target, false);
- }
- case VSX_BUILTIN_LD_ELEMREV_V8HI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v8hi
- : CODE_FOR_vsx_ld_elemrev_v8hi);
- return altivec_expand_lv_builtin (code, exp, target, false);
- }
- case VSX_BUILTIN_LD_ELEMREV_V16QI:
- {
- enum insn_code code = (BYTES_BIG_ENDIAN ? CODE_FOR_vsx_load_v16qi
- : CODE_FOR_vsx_ld_elemrev_v16qi);
- return altivec_expand_lv_builtin (code, exp, target, false);
- }
- break;
- default:
- break;
- /* Fall through. */
- }
-
- *expandedp = false;
- return NULL_RTX;
-}
-
-/* Check whether a builtin function is supported in this target
- configuration. */
-bool
-rs6000_builtin_is_supported_p (enum rs6000_builtins fncode)
-{
- HOST_WIDE_INT fnmask = rs6000_builtin_info[fncode].mask;
- if ((fnmask & rs6000_builtin_mask) != fnmask)
- return false;
- else
- return true;
-}
-
-/* Raise an error message for a builtin function that is called without the
- appropriate target options being set. */
-
-static void
-rs6000_invalid_builtin (enum rs6000_builtins fncode)
-{
- size_t uns_fncode = (size_t) fncode;
- const char *name = rs6000_builtin_info[uns_fncode].name;
- HOST_WIDE_INT fnmask = rs6000_builtin_info[uns_fncode].mask;
-
- gcc_assert (name != NULL);
- if ((fnmask & RS6000_BTM_CELL) != 0)
- error ("builtin function %qs is only valid for the cell processor", name);
- else if ((fnmask & RS6000_BTM_VSX) != 0)
- error ("builtin function %qs requires the %qs option", name, "-mvsx");
- else if ((fnmask & RS6000_BTM_HTM) != 0)
- error ("builtin function %qs requires the %qs option", name, "-mhtm");
- else if ((fnmask & RS6000_BTM_ALTIVEC) != 0)
- error ("builtin function %qs requires the %qs option", name, "-maltivec");
- else if ((fnmask & (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
- == (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
- error ("builtin function %qs requires the %qs and %qs options",
- name, "-mhard-dfp", "-mpower8-vector");
- else if ((fnmask & RS6000_BTM_DFP) != 0)
- error ("builtin function %qs requires the %qs option", name, "-mhard-dfp");
- else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
- error ("builtin function %qs requires the %qs option", name,
- "-mpower8-vector");
- else if ((fnmask & (RS6000_BTM_P9_VECTOR | RS6000_BTM_64BIT))
- == (RS6000_BTM_P9_VECTOR | RS6000_BTM_64BIT))
- error ("builtin function %qs requires the %qs and %qs options",
- name, "-mcpu=power9", "-m64");
- else if ((fnmask & RS6000_BTM_P9_VECTOR) != 0)
- error ("builtin function %qs requires the %qs option", name,
- "-mcpu=power9");
- else if ((fnmask & (RS6000_BTM_P9_MISC | RS6000_BTM_64BIT))
- == (RS6000_BTM_P9_MISC | RS6000_BTM_64BIT))
- error ("builtin function %qs requires the %qs and %qs options",
- name, "-mcpu=power9", "-m64");
- else if ((fnmask & RS6000_BTM_P9_MISC) == RS6000_BTM_P9_MISC)
- error ("builtin function %qs requires the %qs option", name,
- "-mcpu=power9");
- else if ((fnmask & RS6000_BTM_LDBL128) == RS6000_BTM_LDBL128)
- {
- if (!TARGET_HARD_FLOAT)
- error ("builtin function %qs requires the %qs option", name,
- "-mhard-float");
- else
- error ("builtin function %qs requires the %qs option", name,
- TARGET_IEEEQUAD ? "-mabi=ibmlongdouble" : "-mlong-double-128");
- }
- else if ((fnmask & RS6000_BTM_HARD_FLOAT) != 0)
- error ("builtin function %qs requires the %qs option", name,
- "-mhard-float");
- else if ((fnmask & RS6000_BTM_FLOAT128_HW) != 0)
- error ("builtin function %qs requires ISA 3.0 IEEE 128-bit floating point",
- name);
- else if ((fnmask & RS6000_BTM_FLOAT128) != 0)
- error ("builtin function %qs requires the %qs option", name,
- "%<-mfloat128%>");
- else if ((fnmask & (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64))
- == (RS6000_BTM_POPCNTD | RS6000_BTM_POWERPC64))
- error ("builtin function %qs requires the %qs (or newer), and "
- "%qs or %qs options",
- name, "-mcpu=power7", "-m64", "-mpowerpc64");
- else
- error ("builtin function %qs is not supported with the current options",
- name);
-}
-
-/* Target hook for early folding of built-ins, shamelessly stolen
- from ia64.c. */
-
-static tree
-rs6000_fold_builtin (tree fndecl ATTRIBUTE_UNUSED,
- int n_args ATTRIBUTE_UNUSED,
- tree *args ATTRIBUTE_UNUSED,
- bool ignore ATTRIBUTE_UNUSED)
-{
-#ifdef SUBTARGET_FOLD_BUILTIN
- return SUBTARGET_FOLD_BUILTIN (fndecl, n_args, args, ignore);
-#else
- return NULL_TREE;
-#endif
-}
-
-/* Helper function to sort out which built-ins may be valid without having
- a LHS. */
-static bool
-rs6000_builtin_valid_without_lhs (enum rs6000_builtins fn_code)
-{
- switch (fn_code)
- {
- case ALTIVEC_BUILTIN_STVX_V16QI:
- case ALTIVEC_BUILTIN_STVX_V8HI:
- case ALTIVEC_BUILTIN_STVX_V4SI:
- case ALTIVEC_BUILTIN_STVX_V4SF:
- case ALTIVEC_BUILTIN_STVX_V2DI:
- case ALTIVEC_BUILTIN_STVX_V2DF:
- case VSX_BUILTIN_STXVW4X_V16QI:
- case VSX_BUILTIN_STXVW4X_V8HI:
- case VSX_BUILTIN_STXVW4X_V4SF:
- case VSX_BUILTIN_STXVW4X_V4SI:
- case VSX_BUILTIN_STXVD2X_V2DF:
- case VSX_BUILTIN_STXVD2X_V2DI:
- return true;
- default:
- return false;
- }
-}
-
-/* Helper function to handle the gimple folding of a vector compare
- operation. This sets up true/false vectors, and uses the
- VEC_COND_EXPR operation.
- CODE indicates which comparison is to be made. (EQ, GT, ...).
- TYPE indicates the type of the result. */
-static tree
-fold_build_vec_cmp (tree_code code, tree type,
- tree arg0, tree arg1)
-{
- tree cmp_type = build_same_sized_truth_vector_type (type);
- tree zero_vec = build_zero_cst (type);
- tree minus_one_vec = build_minus_one_cst (type);
- tree cmp = fold_build2 (code, cmp_type, arg0, arg1);
- return fold_build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
-}
-
-/* Helper function to handle the in-between steps for the
- vector compare built-ins. */
-static void
-fold_compare_helper (gimple_stmt_iterator *gsi, tree_code code, gimple *stmt)
-{
- tree arg0 = gimple_call_arg (stmt, 0);
- tree arg1 = gimple_call_arg (stmt, 1);
- tree lhs = gimple_call_lhs (stmt);
- tree cmp = fold_build_vec_cmp (code, TREE_TYPE (lhs), arg0, arg1);
- gimple *g = gimple_build_assign (lhs, cmp);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
-}
-
-/* Helper function to map V2DF and V4SF types to their
- integral equivalents (V2DI and V4SI). */
-tree map_to_integral_tree_type (tree input_tree_type)
-{
- if (INTEGRAL_TYPE_P (TREE_TYPE (input_tree_type)))
- return input_tree_type;
- else
- {
- if (types_compatible_p (TREE_TYPE (input_tree_type),
- TREE_TYPE (V2DF_type_node)))
- return V2DI_type_node;
- else if (types_compatible_p (TREE_TYPE (input_tree_type),
- TREE_TYPE (V4SF_type_node)))
- return V4SI_type_node;
- else
- gcc_unreachable ();
- }
-}
-
-/* Helper function to handle the vector merge[hl] built-ins. The
- implementation difference between h and l versions for this code are in
- the values used when building of the permute vector for high word versus
- low word merge. The variance is keyed off the use_high parameter. */
-static void
-fold_mergehl_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_high)
-{
- tree arg0 = gimple_call_arg (stmt, 0);
- tree arg1 = gimple_call_arg (stmt, 1);
- tree lhs = gimple_call_lhs (stmt);
- tree lhs_type = TREE_TYPE (lhs);
- int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
- int midpoint = n_elts / 2;
- int offset = 0;
-
- if (use_high == 1)
- offset = midpoint;
-
- /* The permute_type will match the lhs for integral types. For double and
- float types, the permute type needs to map to the V2 or V4 type that
- matches size. */
- tree permute_type;
- permute_type = map_to_integral_tree_type (lhs_type);
- tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
-
- for (int i = 0; i < midpoint; i++)
- {
- elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
- offset + i));
- elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
- offset + n_elts + i));
- }
-
- tree permute = elts.build ();
-
- gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
-}
-
-/* Helper function to handle the vector merge[eo] built-ins. */
-static void
-fold_mergeeo_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_odd)
-{
- tree arg0 = gimple_call_arg (stmt, 0);
- tree arg1 = gimple_call_arg (stmt, 1);
- tree lhs = gimple_call_lhs (stmt);
- tree lhs_type = TREE_TYPE (lhs);
- int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
-
- /* The permute_type will match the lhs for integral types. For double and
- float types, the permute type needs to map to the V2 or V4 type that
- matches size. */
- tree permute_type;
- permute_type = map_to_integral_tree_type (lhs_type);
-
- tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
-
- /* Build the permute vector. */
- for (int i = 0; i < n_elts / 2; i++)
- {
- elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
- 2*i + use_odd));
- elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
- 2*i + use_odd + n_elts));
- }
-
- tree permute = elts.build ();
-
- gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
-}
-
-/* Fold a machine-dependent built-in in GIMPLE. (For folding into
- a constant, use rs6000_fold_builtin.) */
-
-bool
-rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
-{
- gimple *stmt = gsi_stmt (*gsi);
- tree fndecl = gimple_call_fndecl (stmt);
- gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
- enum rs6000_builtins fn_code
- = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
- tree arg0, arg1, lhs, temp;
- enum tree_code bcode;
- gimple *g;
-
- size_t uns_fncode = (size_t) fn_code;
- enum insn_code icode = rs6000_builtin_info[uns_fncode].icode;
- const char *fn_name1 = rs6000_builtin_info[uns_fncode].name;
- const char *fn_name2 = (icode != CODE_FOR_nothing)
- ? get_insn_name ((int) icode)
- : "nothing";
-
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_gimple_fold_builtin %d %s %s\n",
- fn_code, fn_name1, fn_name2);
-
- if (!rs6000_fold_gimple)
- return false;
-
- /* Prevent gimple folding for code that does not have a LHS, unless it is
- allowed per the rs6000_builtin_valid_without_lhs helper function. */
- if (!gimple_call_lhs (stmt) && !rs6000_builtin_valid_without_lhs (fn_code))
- return false;
-
- /* Don't fold invalid builtins, let rs6000_expand_builtin diagnose it. */
- HOST_WIDE_INT mask = rs6000_builtin_info[uns_fncode].mask;
- bool func_valid_p = (rs6000_builtin_mask & mask) == mask;
- if (!func_valid_p)
- return false;
-
- switch (fn_code)
- {
- /* Flavors of vec_add. We deliberately don't expand
- P8V_BUILTIN_VADDUQM as it gets lowered from V1TImode to
- TImode, resulting in much poorer code generation. */
- case ALTIVEC_BUILTIN_VADDUBM:
- case ALTIVEC_BUILTIN_VADDUHM:
- case ALTIVEC_BUILTIN_VADDUWM:
- case P8V_BUILTIN_VADDUDM:
- case ALTIVEC_BUILTIN_VADDFP:
- case VSX_BUILTIN_XVADDDP:
- bcode = PLUS_EXPR;
- do_binary:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
- && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs))))
- {
- /* Ensure the binary operation is performed in a type
- that wraps if it is integral type. */
- gimple_seq stmts = NULL;
- tree type = unsigned_type_for (TREE_TYPE (lhs));
- tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
- type, arg0);
- tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
- type, arg1);
- tree res = gimple_build (&stmts, gimple_location (stmt), bcode,
- type, uarg0, uarg1);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR,
- build1 (VIEW_CONVERT_EXPR,
- TREE_TYPE (lhs), res));
- gsi_replace (gsi, g, true);
- return true;
- }
- g = gimple_build_assign (lhs, bcode, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_sub. We deliberately don't expand
- P8V_BUILTIN_VSUBUQM. */
- case ALTIVEC_BUILTIN_VSUBUBM:
- case ALTIVEC_BUILTIN_VSUBUHM:
- case ALTIVEC_BUILTIN_VSUBUWM:
- case P8V_BUILTIN_VSUBUDM:
- case ALTIVEC_BUILTIN_VSUBFP:
- case VSX_BUILTIN_XVSUBDP:
- bcode = MINUS_EXPR;
- goto do_binary;
- case VSX_BUILTIN_XVMULSP:
- case VSX_BUILTIN_XVMULDP:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, MULT_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Even element flavors of vec_mul (signed). */
- case ALTIVEC_BUILTIN_VMULESB:
- case ALTIVEC_BUILTIN_VMULESH:
- case P8V_BUILTIN_VMULESW:
- /* Even element flavors of vec_mul (unsigned). */
- case ALTIVEC_BUILTIN_VMULEUB:
- case ALTIVEC_BUILTIN_VMULEUH:
- case P8V_BUILTIN_VMULEUW:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, VEC_WIDEN_MULT_EVEN_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Odd element flavors of vec_mul (signed). */
- case ALTIVEC_BUILTIN_VMULOSB:
- case ALTIVEC_BUILTIN_VMULOSH:
- case P8V_BUILTIN_VMULOSW:
- /* Odd element flavors of vec_mul (unsigned). */
- case ALTIVEC_BUILTIN_VMULOUB:
- case ALTIVEC_BUILTIN_VMULOUH:
- case P8V_BUILTIN_VMULOUW:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, VEC_WIDEN_MULT_ODD_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_div (Integer). */
- case VSX_BUILTIN_DIV_V2DI:
- case VSX_BUILTIN_UDIV_V2DI:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, TRUNC_DIV_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_div (Float). */
- case VSX_BUILTIN_XVDIVSP:
- case VSX_BUILTIN_XVDIVDP:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, RDIV_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_and. */
- case ALTIVEC_BUILTIN_VAND:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_andc. */
- case ALTIVEC_BUILTIN_VANDC:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
- g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- g = gimple_build_assign (lhs, BIT_AND_EXPR, arg0, temp);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_nand. */
- case P8V_BUILTIN_VEC_NAND:
- case P8V_BUILTIN_NAND_V16QI:
- case P8V_BUILTIN_NAND_V8HI:
- case P8V_BUILTIN_NAND_V4SI:
- case P8V_BUILTIN_NAND_V4SF:
- case P8V_BUILTIN_NAND_V2DF:
- case P8V_BUILTIN_NAND_V2DI:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
- g = gimple_build_assign (temp, BIT_AND_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_or. */
- case ALTIVEC_BUILTIN_VOR:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* flavors of vec_orc. */
- case P8V_BUILTIN_ORC_V16QI:
- case P8V_BUILTIN_ORC_V8HI:
- case P8V_BUILTIN_ORC_V4SI:
- case P8V_BUILTIN_ORC_V4SF:
- case P8V_BUILTIN_ORC_V2DF:
- case P8V_BUILTIN_ORC_V2DI:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
- g = gimple_build_assign (temp, BIT_NOT_EXPR, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- g = gimple_build_assign (lhs, BIT_IOR_EXPR, arg0, temp);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_xor. */
- case ALTIVEC_BUILTIN_VXOR:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, BIT_XOR_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_nor. */
- case ALTIVEC_BUILTIN_VNOR:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
- g = gimple_build_assign (temp, BIT_IOR_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* flavors of vec_abs. */
- case ALTIVEC_BUILTIN_ABS_V16QI:
- case ALTIVEC_BUILTIN_ABS_V8HI:
- case ALTIVEC_BUILTIN_ABS_V4SI:
- case ALTIVEC_BUILTIN_ABS_V4SF:
- case P8V_BUILTIN_ABS_V2DI:
- case VSX_BUILTIN_XVABSDP:
- arg0 = gimple_call_arg (stmt, 0);
- if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (arg0)))
- && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (arg0))))
- return false;
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, ABS_EXPR, arg0);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* flavors of vec_min. */
- case VSX_BUILTIN_XVMINDP:
- case P8V_BUILTIN_VMINSD:
- case P8V_BUILTIN_VMINUD:
- case ALTIVEC_BUILTIN_VMINSB:
- case ALTIVEC_BUILTIN_VMINSH:
- case ALTIVEC_BUILTIN_VMINSW:
- case ALTIVEC_BUILTIN_VMINUB:
- case ALTIVEC_BUILTIN_VMINUH:
- case ALTIVEC_BUILTIN_VMINUW:
- case ALTIVEC_BUILTIN_VMINFP:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, MIN_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* flavors of vec_max. */
- case VSX_BUILTIN_XVMAXDP:
- case P8V_BUILTIN_VMAXSD:
- case P8V_BUILTIN_VMAXUD:
- case ALTIVEC_BUILTIN_VMAXSB:
- case ALTIVEC_BUILTIN_VMAXSH:
- case ALTIVEC_BUILTIN_VMAXSW:
- case ALTIVEC_BUILTIN_VMAXUB:
- case ALTIVEC_BUILTIN_VMAXUH:
- case ALTIVEC_BUILTIN_VMAXUW:
- case ALTIVEC_BUILTIN_VMAXFP:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, MAX_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_eqv. */
- case P8V_BUILTIN_EQV_V16QI:
- case P8V_BUILTIN_EQV_V8HI:
- case P8V_BUILTIN_EQV_V4SI:
- case P8V_BUILTIN_EQV_V4SF:
- case P8V_BUILTIN_EQV_V2DF:
- case P8V_BUILTIN_EQV_V2DI:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- temp = create_tmp_reg_or_ssa_name (TREE_TYPE (arg1));
- g = gimple_build_assign (temp, BIT_XOR_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- g = gimple_build_assign (lhs, BIT_NOT_EXPR, temp);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vec_rotate_left. */
- case ALTIVEC_BUILTIN_VRLB:
- case ALTIVEC_BUILTIN_VRLH:
- case ALTIVEC_BUILTIN_VRLW:
- case P8V_BUILTIN_VRLD:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, LROTATE_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- /* Flavors of vector shift right algebraic.
- vec_sra{b,h,w} -> vsra{b,h,w}. */
- case ALTIVEC_BUILTIN_VSRAB:
- case ALTIVEC_BUILTIN_VSRAH:
- case ALTIVEC_BUILTIN_VSRAW:
- case P8V_BUILTIN_VSRAD:
- {
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- tree arg1_type = TREE_TYPE (arg1);
- tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
- tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
- location_t loc = gimple_location (stmt);
- /* Force arg1 into the range valid matching the arg0 type. */
- /* Build a vector consisting of the max valid bit-size values. */
- int n_elts = VECTOR_CST_NELTS (arg1);
- tree element_size = build_int_cst (unsigned_element_type,
- 128 / n_elts);
- tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
- for (int i = 0; i < n_elts; i++)
- elts.safe_push (element_size);
- tree modulo_tree = elts.build ();
- /* Modulo the provided shift value against that vector. */
- gimple_seq stmts = NULL;
- tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
- unsigned_arg1_type, arg1);
- tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
- unsigned_arg1_type, unsigned_arg1,
- modulo_tree);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- /* And finally, do the shift. */
- g = gimple_build_assign (lhs, RSHIFT_EXPR, arg0, new_arg1);
- gimple_set_location (g, loc);
- gsi_replace (gsi, g, true);
- return true;
- }
- /* Flavors of vector shift left.
- builtin_altivec_vsl{b,h,w} -> vsl{b,h,w}. */
- case ALTIVEC_BUILTIN_VSLB:
- case ALTIVEC_BUILTIN_VSLH:
- case ALTIVEC_BUILTIN_VSLW:
- case P8V_BUILTIN_VSLD:
- {
- location_t loc;
- gimple_seq stmts = NULL;
- arg0 = gimple_call_arg (stmt, 0);
- tree arg0_type = TREE_TYPE (arg0);
- if (INTEGRAL_TYPE_P (TREE_TYPE (arg0_type))
- && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0_type)))
- return false;
- arg1 = gimple_call_arg (stmt, 1);
- tree arg1_type = TREE_TYPE (arg1);
- tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
- tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
- loc = gimple_location (stmt);
- lhs = gimple_call_lhs (stmt);
- /* Force arg1 into the range valid matching the arg0 type. */
- /* Build a vector consisting of the max valid bit-size values. */
- int n_elts = VECTOR_CST_NELTS (arg1);
- int tree_size_in_bits = TREE_INT_CST_LOW (size_in_bytes (arg1_type))
- * BITS_PER_UNIT;
- tree element_size = build_int_cst (unsigned_element_type,
- tree_size_in_bits / n_elts);
- tree_vector_builder elts (unsigned_type_for (arg1_type), n_elts, 1);
- for (int i = 0; i < n_elts; i++)
- elts.safe_push (element_size);
- tree modulo_tree = elts.build ();
- /* Modulo the provided shift value against that vector. */
- tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
- unsigned_arg1_type, arg1);
- tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
- unsigned_arg1_type, unsigned_arg1,
- modulo_tree);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- /* And finally, do the shift. */
- g = gimple_build_assign (lhs, LSHIFT_EXPR, arg0, new_arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- }
- /* Flavors of vector shift right. */
- case ALTIVEC_BUILTIN_VSRB:
- case ALTIVEC_BUILTIN_VSRH:
- case ALTIVEC_BUILTIN_VSRW:
- case P8V_BUILTIN_VSRD:
- {
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- tree arg1_type = TREE_TYPE (arg1);
- tree unsigned_arg1_type = unsigned_type_for (TREE_TYPE (arg1));
- tree unsigned_element_type = unsigned_type_for (TREE_TYPE (arg1_type));
- location_t loc = gimple_location (stmt);
- gimple_seq stmts = NULL;
- /* Convert arg0 to unsigned. */
- tree arg0_unsigned
- = gimple_build (&stmts, VIEW_CONVERT_EXPR,
- unsigned_type_for (TREE_TYPE (arg0)), arg0);
- /* Force arg1 into the range valid matching the arg0 type. */
- /* Build a vector consisting of the max valid bit-size values. */
- int n_elts = VECTOR_CST_NELTS (arg1);
- tree element_size = build_int_cst (unsigned_element_type,
- 128 / n_elts);
- tree_vector_builder elts (unsigned_arg1_type, n_elts, 1);
- for (int i = 0; i < n_elts; i++)
- elts.safe_push (element_size);
- tree modulo_tree = elts.build ();
- /* Modulo the provided shift value against that vector. */
- tree unsigned_arg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
- unsigned_arg1_type, arg1);
- tree new_arg1 = gimple_build (&stmts, loc, TRUNC_MOD_EXPR,
- unsigned_arg1_type, unsigned_arg1,
- modulo_tree);
- /* Do the shift. */
- tree res
- = gimple_build (&stmts, RSHIFT_EXPR,
- TREE_TYPE (arg0_unsigned), arg0_unsigned, new_arg1);
- /* Convert result back to the lhs type. */
- res = gimple_build (&stmts, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), res);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- update_call_from_tree (gsi, res);
- return true;
- }
- /* Vector loads. */
- case ALTIVEC_BUILTIN_LVX_V16QI:
- case ALTIVEC_BUILTIN_LVX_V8HI:
- case ALTIVEC_BUILTIN_LVX_V4SI:
- case ALTIVEC_BUILTIN_LVX_V4SF:
- case ALTIVEC_BUILTIN_LVX_V2DI:
- case ALTIVEC_BUILTIN_LVX_V2DF:
- case ALTIVEC_BUILTIN_LVX_V1TI:
- {
- arg0 = gimple_call_arg (stmt, 0); // offset
- arg1 = gimple_call_arg (stmt, 1); // address
- lhs = gimple_call_lhs (stmt);
- location_t loc = gimple_location (stmt);
- /* Since arg1 may be cast to a different type, just use ptr_type_node
- here instead of trying to enforce TBAA on pointer types. */
- tree arg1_type = ptr_type_node;
- tree lhs_type = TREE_TYPE (lhs);
- /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
- the tree using the value from arg0. The resulting type will match
- the type of arg1. */
- gimple_seq stmts = NULL;
- tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
- tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
- arg1_type, arg1, temp_offset);
- /* Mask off any lower bits from the address. */
- tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
- arg1_type, temp_addr,
- build_int_cst (arg1_type, -16));
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- if (!is_gimple_mem_ref_addr (aligned_addr))
- {
- tree t = make_ssa_name (TREE_TYPE (aligned_addr));
- gimple *g = gimple_build_assign (t, aligned_addr);
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- aligned_addr = t;
- }
- /* Use the build2 helper to set up the mem_ref. The MEM_REF could also
- take an offset, but since we've already incorporated the offset
- above, here we just pass in a zero. */
- gimple *g
- = gimple_build_assign (lhs, build2 (MEM_REF, lhs_type, aligned_addr,
- build_int_cst (arg1_type, 0)));
- gimple_set_location (g, loc);
- gsi_replace (gsi, g, true);
- return true;
- }
- /* Vector stores. */
- case ALTIVEC_BUILTIN_STVX_V16QI:
- case ALTIVEC_BUILTIN_STVX_V8HI:
- case ALTIVEC_BUILTIN_STVX_V4SI:
- case ALTIVEC_BUILTIN_STVX_V4SF:
- case ALTIVEC_BUILTIN_STVX_V2DI:
- case ALTIVEC_BUILTIN_STVX_V2DF:
- {
- arg0 = gimple_call_arg (stmt, 0); /* Value to be stored. */
- arg1 = gimple_call_arg (stmt, 1); /* Offset. */
- tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address. */
- location_t loc = gimple_location (stmt);
- tree arg0_type = TREE_TYPE (arg0);
- /* Use ptr_type_node (no TBAA) for the arg2_type.
- FIXME: (Richard) "A proper fix would be to transition this type as
- seen from the frontend to GIMPLE, for example in a similar way we
- do for MEM_REFs by piggy-backing that on an extra argument, a
- constant zero pointer of the alias pointer type to use (which would
- also serve as a type indicator of the store itself). I'd use a
- target specific internal function for this (not sure if we can have
- those target specific, but I guess if it's folded away then that's
- fine) and get away with the overload set." */
- tree arg2_type = ptr_type_node;
- /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
- the tree using the value from arg0. The resulting type will match
- the type of arg2. */
- gimple_seq stmts = NULL;
- tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
- tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
- arg2_type, arg2, temp_offset);
- /* Mask off any lower bits from the address. */
- tree aligned_addr = gimple_build (&stmts, loc, BIT_AND_EXPR,
- arg2_type, temp_addr,
- build_int_cst (arg2_type, -16));
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- if (!is_gimple_mem_ref_addr (aligned_addr))
- {
- tree t = make_ssa_name (TREE_TYPE (aligned_addr));
- gimple *g = gimple_build_assign (t, aligned_addr);
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- aligned_addr = t;
- }
- /* The desired gimple result should be similar to:
- MEM[(__vector floatD.1407 *)_1] = vf1D.2697; */
- gimple *g
- = gimple_build_assign (build2 (MEM_REF, arg0_type, aligned_addr,
- build_int_cst (arg2_type, 0)), arg0);
- gimple_set_location (g, loc);
- gsi_replace (gsi, g, true);
- return true;
- }
-
- /* unaligned Vector loads. */
- case VSX_BUILTIN_LXVW4X_V16QI:
- case VSX_BUILTIN_LXVW4X_V8HI:
- case VSX_BUILTIN_LXVW4X_V4SF:
- case VSX_BUILTIN_LXVW4X_V4SI:
- case VSX_BUILTIN_LXVD2X_V2DF:
- case VSX_BUILTIN_LXVD2X_V2DI:
- {
- arg0 = gimple_call_arg (stmt, 0); // offset
- arg1 = gimple_call_arg (stmt, 1); // address
- lhs = gimple_call_lhs (stmt);
- location_t loc = gimple_location (stmt);
- /* Since arg1 may be cast to a different type, just use ptr_type_node
- here instead of trying to enforce TBAA on pointer types. */
- tree arg1_type = ptr_type_node;
- tree lhs_type = TREE_TYPE (lhs);
- /* In GIMPLE the type of the MEM_REF specifies the alignment. The
- required alignment (power) is 4 bytes regardless of data type. */
- tree align_ltype = build_aligned_type (lhs_type, 4);
- /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
- the tree using the value from arg0. The resulting type will match
- the type of arg1. */
- gimple_seq stmts = NULL;
- tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg0);
- tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
- arg1_type, arg1, temp_offset);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- if (!is_gimple_mem_ref_addr (temp_addr))
- {
- tree t = make_ssa_name (TREE_TYPE (temp_addr));
- gimple *g = gimple_build_assign (t, temp_addr);
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- temp_addr = t;
- }
- /* Use the build2 helper to set up the mem_ref. The MEM_REF could also
- take an offset, but since we've already incorporated the offset
- above, here we just pass in a zero. */
- gimple *g;
- g = gimple_build_assign (lhs, build2 (MEM_REF, align_ltype, temp_addr,
- build_int_cst (arg1_type, 0)));
- gimple_set_location (g, loc);
- gsi_replace (gsi, g, true);
- return true;
- }
-
- /* unaligned Vector stores. */
- case VSX_BUILTIN_STXVW4X_V16QI:
- case VSX_BUILTIN_STXVW4X_V8HI:
- case VSX_BUILTIN_STXVW4X_V4SF:
- case VSX_BUILTIN_STXVW4X_V4SI:
- case VSX_BUILTIN_STXVD2X_V2DF:
- case VSX_BUILTIN_STXVD2X_V2DI:
- {
- arg0 = gimple_call_arg (stmt, 0); /* Value to be stored. */
- arg1 = gimple_call_arg (stmt, 1); /* Offset. */
- tree arg2 = gimple_call_arg (stmt, 2); /* Store-to address. */
- location_t loc = gimple_location (stmt);
- tree arg0_type = TREE_TYPE (arg0);
- /* Use ptr_type_node (no TBAA) for the arg2_type. */
- tree arg2_type = ptr_type_node;
- /* In GIMPLE the type of the MEM_REF specifies the alignment. The
- required alignment (power) is 4 bytes regardless of data type. */
- tree align_stype = build_aligned_type (arg0_type, 4);
- /* POINTER_PLUS_EXPR wants the offset to be of type 'sizetype'. Create
- the tree using the value from arg1. */
- gimple_seq stmts = NULL;
- tree temp_offset = gimple_convert (&stmts, loc, sizetype, arg1);
- tree temp_addr = gimple_build (&stmts, loc, POINTER_PLUS_EXPR,
- arg2_type, arg2, temp_offset);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- if (!is_gimple_mem_ref_addr (temp_addr))
- {
- tree t = make_ssa_name (TREE_TYPE (temp_addr));
- gimple *g = gimple_build_assign (t, temp_addr);
- gsi_insert_before (gsi, g, GSI_SAME_STMT);
- temp_addr = t;
- }
- gimple *g;
- g = gimple_build_assign (build2 (MEM_REF, align_stype, temp_addr,
- build_int_cst (arg2_type, 0)), arg0);
- gimple_set_location (g, loc);
- gsi_replace (gsi, g, true);
- return true;
- }
-
- /* Vector Fused multiply-add (fma). */
- case ALTIVEC_BUILTIN_VMADDFP:
- case VSX_BUILTIN_XVMADDDP:
- case ALTIVEC_BUILTIN_VMLADDUHM:
- {
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- tree arg2 = gimple_call_arg (stmt, 2);
- lhs = gimple_call_lhs (stmt);
- gcall *g = gimple_build_call_internal (IFN_FMA, 3, arg0, arg1, arg2);
- gimple_call_set_lhs (g, lhs);
- gimple_call_set_nothrow (g, true);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- }
-
- /* Vector compares; EQ, NE, GE, GT, LE. */
- case ALTIVEC_BUILTIN_VCMPEQUB:
- case ALTIVEC_BUILTIN_VCMPEQUH:
- case ALTIVEC_BUILTIN_VCMPEQUW:
- case P8V_BUILTIN_VCMPEQUD:
- fold_compare_helper (gsi, EQ_EXPR, stmt);
- return true;
-
- case P9V_BUILTIN_CMPNEB:
- case P9V_BUILTIN_CMPNEH:
- case P9V_BUILTIN_CMPNEW:
- fold_compare_helper (gsi, NE_EXPR, stmt);
- return true;
-
- case VSX_BUILTIN_CMPGE_16QI:
- case VSX_BUILTIN_CMPGE_U16QI:
- case VSX_BUILTIN_CMPGE_8HI:
- case VSX_BUILTIN_CMPGE_U8HI:
- case VSX_BUILTIN_CMPGE_4SI:
- case VSX_BUILTIN_CMPGE_U4SI:
- case VSX_BUILTIN_CMPGE_2DI:
- case VSX_BUILTIN_CMPGE_U2DI:
- fold_compare_helper (gsi, GE_EXPR, stmt);
- return true;
-
- case ALTIVEC_BUILTIN_VCMPGTSB:
- case ALTIVEC_BUILTIN_VCMPGTUB:
- case ALTIVEC_BUILTIN_VCMPGTSH:
- case ALTIVEC_BUILTIN_VCMPGTUH:
- case ALTIVEC_BUILTIN_VCMPGTSW:
- case ALTIVEC_BUILTIN_VCMPGTUW:
- case P8V_BUILTIN_VCMPGTUD:
- case P8V_BUILTIN_VCMPGTSD:
- fold_compare_helper (gsi, GT_EXPR, stmt);
- return true;
-
- case VSX_BUILTIN_CMPLE_16QI:
- case VSX_BUILTIN_CMPLE_U16QI:
- case VSX_BUILTIN_CMPLE_8HI:
- case VSX_BUILTIN_CMPLE_U8HI:
- case VSX_BUILTIN_CMPLE_4SI:
- case VSX_BUILTIN_CMPLE_U4SI:
- case VSX_BUILTIN_CMPLE_2DI:
- case VSX_BUILTIN_CMPLE_U2DI:
- fold_compare_helper (gsi, LE_EXPR, stmt);
- return true;
-
- /* flavors of vec_splat_[us]{8,16,32}. */
- case ALTIVEC_BUILTIN_VSPLTISB:
- case ALTIVEC_BUILTIN_VSPLTISH:
- case ALTIVEC_BUILTIN_VSPLTISW:
- {
- arg0 = gimple_call_arg (stmt, 0);
- lhs = gimple_call_lhs (stmt);
-
- /* Only fold the vec_splat_*() if the lower bits of arg 0 is a
- 5-bit signed constant in range -16 to +15. */
- if (TREE_CODE (arg0) != INTEGER_CST
- || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15))
- return false;
- gimple_seq stmts = NULL;
- location_t loc = gimple_location (stmt);
- tree splat_value = gimple_convert (&stmts, loc,
- TREE_TYPE (TREE_TYPE (lhs)), arg0);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- tree splat_tree = build_vector_from_val (TREE_TYPE (lhs), splat_value);
- g = gimple_build_assign (lhs, splat_tree);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- }
-
- /* Flavors of vec_splat. */
- /* a = vec_splat (b, 0x3) becomes a = { b[3],b[3],b[3],...}; */
- case ALTIVEC_BUILTIN_VSPLTB:
- case ALTIVEC_BUILTIN_VSPLTH:
- case ALTIVEC_BUILTIN_VSPLTW:
- case VSX_BUILTIN_XXSPLTD_V2DI:
- case VSX_BUILTIN_XXSPLTD_V2DF:
- {
- arg0 = gimple_call_arg (stmt, 0); /* input vector. */
- arg1 = gimple_call_arg (stmt, 1); /* index into arg0. */
- /* Only fold the vec_splat_*() if arg1 is both a constant value and
- is a valid index into the arg0 vector. */
- unsigned int n_elts = VECTOR_CST_NELTS (arg0);
- if (TREE_CODE (arg1) != INTEGER_CST
- || TREE_INT_CST_LOW (arg1) > (n_elts -1))
- return false;
- lhs = gimple_call_lhs (stmt);
- tree lhs_type = TREE_TYPE (lhs);
- tree arg0_type = TREE_TYPE (arg0);
- tree splat;
- if (TREE_CODE (arg0) == VECTOR_CST)
- splat = VECTOR_CST_ELT (arg0, TREE_INT_CST_LOW (arg1));
- else
- {
- /* Determine (in bits) the length and start location of the
- splat value for a call to the tree_vec_extract helper. */
- int splat_elem_size = TREE_INT_CST_LOW (size_in_bytes (arg0_type))
- * BITS_PER_UNIT / n_elts;
- int splat_start_bit = TREE_INT_CST_LOW (arg1) * splat_elem_size;
- tree len = build_int_cst (bitsizetype, splat_elem_size);
- tree start = build_int_cst (bitsizetype, splat_start_bit);
- splat = tree_vec_extract (gsi, TREE_TYPE (lhs_type), arg0,
- len, start);
- }
- /* And finally, build the new vector. */
- tree splat_tree = build_vector_from_val (lhs_type, splat);
- g = gimple_build_assign (lhs, splat_tree);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- }
-
- /* vec_mergel (integrals). */
- case ALTIVEC_BUILTIN_VMRGLH:
- case ALTIVEC_BUILTIN_VMRGLW:
- case VSX_BUILTIN_XXMRGLW_4SI:
- case ALTIVEC_BUILTIN_VMRGLB:
- case VSX_BUILTIN_VEC_MERGEL_V2DI:
- case VSX_BUILTIN_XXMRGLW_4SF:
- case VSX_BUILTIN_VEC_MERGEL_V2DF:
- fold_mergehl_helper (gsi, stmt, 1);
- return true;
- /* vec_mergeh (integrals). */
- case ALTIVEC_BUILTIN_VMRGHH:
- case ALTIVEC_BUILTIN_VMRGHW:
- case VSX_BUILTIN_XXMRGHW_4SI:
- case ALTIVEC_BUILTIN_VMRGHB:
- case VSX_BUILTIN_VEC_MERGEH_V2DI:
- case VSX_BUILTIN_XXMRGHW_4SF:
- case VSX_BUILTIN_VEC_MERGEH_V2DF:
- fold_mergehl_helper (gsi, stmt, 0);
- return true;
-
- /* Flavors of vec_mergee. */
- case P8V_BUILTIN_VMRGEW_V4SI:
- case P8V_BUILTIN_VMRGEW_V2DI:
- case P8V_BUILTIN_VMRGEW_V4SF:
- case P8V_BUILTIN_VMRGEW_V2DF:
- fold_mergeeo_helper (gsi, stmt, 0);
- return true;
- /* Flavors of vec_mergeo. */
- case P8V_BUILTIN_VMRGOW_V4SI:
- case P8V_BUILTIN_VMRGOW_V2DI:
- case P8V_BUILTIN_VMRGOW_V4SF:
- case P8V_BUILTIN_VMRGOW_V2DF:
- fold_mergeeo_helper (gsi, stmt, 1);
- return true;
-
- /* d = vec_pack (a, b) */
- case P8V_BUILTIN_VPKUDUM:
- case ALTIVEC_BUILTIN_VPKUHUM:
- case ALTIVEC_BUILTIN_VPKUWUM:
- {
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- gimple *g = gimple_build_assign (lhs, VEC_PACK_TRUNC_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- }
-
- /* d = vec_unpackh (a) */
- /* Note that the UNPACK_{HI,LO}_EXPR used in the gimple_build_assign call
- in this code is sensitive to endian-ness, and needs to be inverted to
- handle both LE and BE targets. */
- case ALTIVEC_BUILTIN_VUPKHSB:
- case ALTIVEC_BUILTIN_VUPKHSH:
- case P8V_BUILTIN_VUPKHSW:
- {
- arg0 = gimple_call_arg (stmt, 0);
- lhs = gimple_call_lhs (stmt);
- if (BYTES_BIG_ENDIAN)
- g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
- else
- g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- }
- /* d = vec_unpackl (a) */
- case ALTIVEC_BUILTIN_VUPKLSB:
- case ALTIVEC_BUILTIN_VUPKLSH:
- case P8V_BUILTIN_VUPKLSW:
- {
- arg0 = gimple_call_arg (stmt, 0);
- lhs = gimple_call_lhs (stmt);
- if (BYTES_BIG_ENDIAN)
- g = gimple_build_assign (lhs, VEC_UNPACK_LO_EXPR, arg0);
- else
- g = gimple_build_assign (lhs, VEC_UNPACK_HI_EXPR, arg0);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
- }
- /* There is no gimple type corresponding with pixel, so just return. */
- case ALTIVEC_BUILTIN_VUPKHPX:
- case ALTIVEC_BUILTIN_VUPKLPX:
- return false;
-
- /* vec_perm. */
- case ALTIVEC_BUILTIN_VPERM_16QI:
- case ALTIVEC_BUILTIN_VPERM_8HI:
- case ALTIVEC_BUILTIN_VPERM_4SI:
- case ALTIVEC_BUILTIN_VPERM_2DI:
- case ALTIVEC_BUILTIN_VPERM_4SF:
- case ALTIVEC_BUILTIN_VPERM_2DF:
- {
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- tree permute = gimple_call_arg (stmt, 2);
- lhs = gimple_call_lhs (stmt);
- location_t loc = gimple_location (stmt);
- gimple_seq stmts = NULL;
- // convert arg0 and arg1 to match the type of the permute
- // for the VEC_PERM_EXPR operation.
- tree permute_type = (TREE_TYPE (permute));
- tree arg0_ptype = gimple_convert (&stmts, loc, permute_type, arg0);
- tree arg1_ptype = gimple_convert (&stmts, loc, permute_type, arg1);
- tree lhs_ptype = gimple_build (&stmts, loc, VEC_PERM_EXPR,
- permute_type, arg0_ptype, arg1_ptype,
- permute);
- // Convert the result back to the desired lhs type upon completion.
- tree temp = gimple_convert (&stmts, loc, TREE_TYPE (lhs), lhs_ptype);
- gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
- g = gimple_build_assign (lhs, temp);
- gimple_set_location (g, loc);
- gsi_replace (gsi, g, true);
- return true;
- }
-
- default:
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "gimple builtin intrinsic not matched:%d %s %s\n",
- fn_code, fn_name1, fn_name2);
- break;
- }
-
- return false;
-}
-
-/* Expand an expression EXP that calls a built-in function,
- with result going to TARGET if that's convenient
- (and in mode MODE if that's convenient).
- SUBTARGET may be used as the target for computing one of EXP's operands.
- IGNORE is nonzero if the value is to be ignored. */
-
-static rtx
-rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
-{
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- enum rs6000_builtins fcode
- = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
- size_t uns_fcode = (size_t)fcode;
- const struct builtin_description *d;
- size_t i;
- rtx ret;
- bool success;
- HOST_WIDE_INT mask = rs6000_builtin_info[uns_fcode].mask;
- bool func_valid_p = ((rs6000_builtin_mask & mask) == mask);
- enum insn_code icode = rs6000_builtin_info[uns_fcode].icode;
-
- /* We have two different modes (KFmode, TFmode) that are the IEEE 128-bit
- floating point type, depending on whether long double is the IBM extended
- double (KFmode) or long double is IEEE 128-bit (TFmode). It is simpler if
- we only define one variant of the built-in function, and switch the code
- when defining it, rather than defining two built-ins and using the
- overload table in rs6000-c.c to switch between the two. If we don't have
- the proper assembler, don't do this switch because CODE_FOR_*kf* and
- CODE_FOR_*tf* will be CODE_FOR_nothing. */
- if (FLOAT128_IEEE_P (TFmode))
- switch (icode)
- {
- default:
- break;
-
- case CODE_FOR_sqrtkf2_odd: icode = CODE_FOR_sqrttf2_odd; break;
- case CODE_FOR_trunckfdf2_odd: icode = CODE_FOR_trunctfdf2_odd; break;
- case CODE_FOR_addkf3_odd: icode = CODE_FOR_addtf3_odd; break;
- case CODE_FOR_subkf3_odd: icode = CODE_FOR_subtf3_odd; break;
- case CODE_FOR_mulkf3_odd: icode = CODE_FOR_multf3_odd; break;
- case CODE_FOR_divkf3_odd: icode = CODE_FOR_divtf3_odd; break;
- case CODE_FOR_fmakf4_odd: icode = CODE_FOR_fmatf4_odd; break;
- case CODE_FOR_xsxexpqp_kf: icode = CODE_FOR_xsxexpqp_tf; break;
- case CODE_FOR_xsxsigqp_kf: icode = CODE_FOR_xsxsigqp_tf; break;
- case CODE_FOR_xststdcnegqp_kf: icode = CODE_FOR_xststdcnegqp_tf; break;
- case CODE_FOR_xsiexpqp_kf: icode = CODE_FOR_xsiexpqp_tf; break;
- case CODE_FOR_xsiexpqpf_kf: icode = CODE_FOR_xsiexpqpf_tf; break;
- case CODE_FOR_xststdcqp_kf: icode = CODE_FOR_xststdcqp_tf; break;
- }
-
- if (TARGET_DEBUG_BUILTIN)
- {
- const char *name1 = rs6000_builtin_info[uns_fcode].name;
- const char *name2 = (icode != CODE_FOR_nothing)
- ? get_insn_name ((int) icode)
- : "nothing";
- const char *name3;
-
- switch (rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK)
- {
- default: name3 = "unknown"; break;
- case RS6000_BTC_SPECIAL: name3 = "special"; break;
- case RS6000_BTC_UNARY: name3 = "unary"; break;
- case RS6000_BTC_BINARY: name3 = "binary"; break;
- case RS6000_BTC_TERNARY: name3 = "ternary"; break;
- case RS6000_BTC_PREDICATE: name3 = "predicate"; break;
- case RS6000_BTC_ABS: name3 = "abs"; break;
- case RS6000_BTC_DST: name3 = "dst"; break;
- }
-
-
- fprintf (stderr,
- "rs6000_expand_builtin, %s (%d), insn = %s (%d), type=%s%s\n",
- (name1) ? name1 : "---", fcode,
- (name2) ? name2 : "---", (int) icode,
- name3,
- func_valid_p ? "" : ", not valid");
- }
-
- if (!func_valid_p)
- {
- rs6000_invalid_builtin (fcode);
-
- /* Given it is invalid, just generate a normal call. */
- return expand_call (exp, target, ignore);
- }
-
- switch (fcode)
- {
- case RS6000_BUILTIN_RECIP:
- return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
-
- case RS6000_BUILTIN_RECIPF:
- return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
-
- case RS6000_BUILTIN_RSQRTF:
- return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
-
- case RS6000_BUILTIN_RSQRT:
- return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
-
- case POWER7_BUILTIN_BPERMD:
- return rs6000_expand_binop_builtin (((TARGET_64BIT)
- ? CODE_FOR_bpermd_di
- : CODE_FOR_bpermd_si), exp, target);
-
- case RS6000_BUILTIN_GET_TB:
- return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_get_timebase,
- target);
-
- case RS6000_BUILTIN_MFTB:
- return rs6000_expand_zeroop_builtin (((TARGET_64BIT)
- ? CODE_FOR_rs6000_mftb_di
- : CODE_FOR_rs6000_mftb_si),
- target);
-
- case RS6000_BUILTIN_MFFS:
- return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffs, target);
-
- case RS6000_BUILTIN_MTFSB0:
- return rs6000_expand_mtfsb_builtin (CODE_FOR_rs6000_mtfsb0, exp);
-
- case RS6000_BUILTIN_MTFSB1:
- return rs6000_expand_mtfsb_builtin (CODE_FOR_rs6000_mtfsb1, exp);
-
- case RS6000_BUILTIN_SET_FPSCR_RN:
- return rs6000_expand_set_fpscr_rn_builtin (CODE_FOR_rs6000_set_fpscr_rn,
- exp);
-
- case RS6000_BUILTIN_SET_FPSCR_DRN:
- return
- rs6000_expand_set_fpscr_drn_builtin (CODE_FOR_rs6000_set_fpscr_drn,
- exp);
-
- case RS6000_BUILTIN_MFFSL:
- return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffsl, target);
-
- case RS6000_BUILTIN_MTFSF:
- return rs6000_expand_mtfsf_builtin (CODE_FOR_rs6000_mtfsf, exp);
-
- case RS6000_BUILTIN_CPU_INIT:
- case RS6000_BUILTIN_CPU_IS:
- case RS6000_BUILTIN_CPU_SUPPORTS:
- return cpu_expand_builtin (fcode, exp, target);
-
- case MISC_BUILTIN_SPEC_BARRIER:
- {
- emit_insn (gen_speculation_barrier ());
- return NULL_RTX;
- }
-
- case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
- case ALTIVEC_BUILTIN_MASK_FOR_STORE:
- {
- int icode2 = (BYTES_BIG_ENDIAN ? (int) CODE_FOR_altivec_lvsr_direct
- : (int) CODE_FOR_altivec_lvsl_direct);
- machine_mode tmode = insn_data[icode2].operand[0].mode;
- machine_mode mode = insn_data[icode2].operand[1].mode;
- tree arg;
- rtx op, addr, pat;
-
- gcc_assert (TARGET_ALTIVEC);
-
- arg = CALL_EXPR_ARG (exp, 0);
- gcc_assert (POINTER_TYPE_P (TREE_TYPE (arg)));
- op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
- addr = memory_address (mode, op);
- if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
- op = addr;
- else
- {
- /* For the load case need to negate the address. */
- op = gen_reg_rtx (GET_MODE (addr));
- emit_insn (gen_rtx_SET (op, gen_rtx_NEG (GET_MODE (addr), addr)));
- }
- op = gen_rtx_MEM (mode, op);
-
- if (target == 0
- || GET_MODE (target) != tmode
- || ! (*insn_data[icode2].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
-
- pat = GEN_FCN (icode2) (target, op);
- if (!pat)
- return 0;
- emit_insn (pat);
-
- return target;
- }
-
- case ALTIVEC_BUILTIN_VCFUX:
- case ALTIVEC_BUILTIN_VCFSX:
- case ALTIVEC_BUILTIN_VCTUXS:
- case ALTIVEC_BUILTIN_VCTSXS:
- /* FIXME: There's got to be a nicer way to handle this case than
- constructing a new CALL_EXPR. */
- if (call_expr_nargs (exp) == 1)
- {
- exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
- 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
- }
- break;
-
- /* For the pack and unpack int128 routines, fix up the builtin so it
- uses the correct IBM128 type. */
- case MISC_BUILTIN_PACK_IF:
- if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
- {
- icode = CODE_FOR_packtf;
- fcode = MISC_BUILTIN_PACK_TF;
- uns_fcode = (size_t)fcode;
- }
- break;
-
- case MISC_BUILTIN_UNPACK_IF:
- if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
- {
- icode = CODE_FOR_unpacktf;
- fcode = MISC_BUILTIN_UNPACK_TF;
- uns_fcode = (size_t)fcode;
- }
- break;
-
- default:
- break;
- }
-
- if (TARGET_ALTIVEC)
- {
- ret = altivec_expand_builtin (exp, target, &success);
-
- if (success)
- return ret;
- }
- if (TARGET_HTM)
- {
- ret = htm_expand_builtin (exp, target, &success);
-
- if (success)
- return ret;
- }
-
- unsigned attr = rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK;
- /* RS6000_BTC_SPECIAL represents no-operand operators. */
- gcc_assert (attr == RS6000_BTC_UNARY
- || attr == RS6000_BTC_BINARY
- || attr == RS6000_BTC_TERNARY
- || attr == RS6000_BTC_SPECIAL);
-
- /* Handle simple unary operations. */
- d = bdesc_1arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
- if (d->code == fcode)
- return rs6000_expand_unop_builtin (icode, exp, target);
-
- /* Handle simple binary operations. */
- d = bdesc_2arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
- if (d->code == fcode)
- return rs6000_expand_binop_builtin (icode, exp, target);
-
- /* Handle simple ternary operations. */
- d = bdesc_3arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
- if (d->code == fcode)
- return rs6000_expand_ternop_builtin (icode, exp, target);
-
- /* Handle simple no-argument operations. */
- d = bdesc_0arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
- if (d->code == fcode)
- return rs6000_expand_zeroop_builtin (icode, target);
-
- gcc_unreachable ();
-}
-
-/* Create a builtin vector type with a name. Taking care not to give
- the canonical type a name. */
-
-static tree
-rs6000_vector_type (const char *name, tree elt_type, unsigned num_elts)
-{
- tree result = build_vector_type (elt_type, num_elts);
-
- /* Copy so we don't give the canonical type a name. */
- result = build_variant_type_copy (result);
-
- add_builtin_type (name, result);
-
- return result;
-}
-
-static void
-rs6000_init_builtins (void)
-{
- tree tdecl;
- tree ftype;
- machine_mode mode;
-
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_init_builtins%s%s\n",
- (TARGET_ALTIVEC) ? ", altivec" : "",
- (TARGET_VSX) ? ", vsx" : "");
-
- V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64 ? "__vector long"
- : "__vector long long",
- intDI_type_node, 2);
- V2DF_type_node = rs6000_vector_type ("__vector double", double_type_node, 2);
- V4SI_type_node = rs6000_vector_type ("__vector signed int",
- intSI_type_node, 4);
- V4SF_type_node = rs6000_vector_type ("__vector float", float_type_node, 4);
- V8HI_type_node = rs6000_vector_type ("__vector signed short",
- intHI_type_node, 8);
- V16QI_type_node = rs6000_vector_type ("__vector signed char",
- intQI_type_node, 16);
-
- unsigned_V16QI_type_node = rs6000_vector_type ("__vector unsigned char",
- unsigned_intQI_type_node, 16);
- unsigned_V8HI_type_node = rs6000_vector_type ("__vector unsigned short",
- unsigned_intHI_type_node, 8);
- unsigned_V4SI_type_node = rs6000_vector_type ("__vector unsigned int",
- unsigned_intSI_type_node, 4);
- unsigned_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
- ? "__vector unsigned long"
- : "__vector unsigned long long",
- unsigned_intDI_type_node, 2);
-
- opaque_V4SI_type_node = build_opaque_vector_type (intSI_type_node, 4);
-
- const_str_type_node
- = build_pointer_type (build_qualified_type (char_type_node,
- TYPE_QUAL_CONST));
-
- /* We use V1TI mode as a special container to hold __int128_t items that
- must live in VSX registers. */
- if (intTI_type_node)
- {
- V1TI_type_node = rs6000_vector_type ("__vector __int128",
- intTI_type_node, 1);
- unsigned_V1TI_type_node
- = rs6000_vector_type ("__vector unsigned __int128",
- unsigned_intTI_type_node, 1);
- }
-
- /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
- types, especially in C++ land. Similarly, 'vector pixel' is distinct from
- 'vector unsigned short'. */
-
- bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
- bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
- bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
- bool_long_long_type_node = build_distinct_type_copy (unsigned_intDI_type_node);
- pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
-
- long_integer_type_internal_node = long_integer_type_node;
- long_unsigned_type_internal_node = long_unsigned_type_node;
- long_long_integer_type_internal_node = long_long_integer_type_node;
- long_long_unsigned_type_internal_node = long_long_unsigned_type_node;
- intQI_type_internal_node = intQI_type_node;
- uintQI_type_internal_node = unsigned_intQI_type_node;
- intHI_type_internal_node = intHI_type_node;
- uintHI_type_internal_node = unsigned_intHI_type_node;
- intSI_type_internal_node = intSI_type_node;
- uintSI_type_internal_node = unsigned_intSI_type_node;
- intDI_type_internal_node = intDI_type_node;
- uintDI_type_internal_node = unsigned_intDI_type_node;
- intTI_type_internal_node = intTI_type_node;
- uintTI_type_internal_node = unsigned_intTI_type_node;
- float_type_internal_node = float_type_node;
- double_type_internal_node = double_type_node;
- long_double_type_internal_node = long_double_type_node;
- dfloat64_type_internal_node = dfloat64_type_node;
- dfloat128_type_internal_node = dfloat128_type_node;
- void_type_internal_node = void_type_node;
-
- /* 128-bit floating point support. KFmode is IEEE 128-bit floating point.
- IFmode is the IBM extended 128-bit format that is a pair of doubles.
- TFmode will be either IEEE 128-bit floating point or the IBM double-double
- format that uses a pair of doubles, depending on the switches and
- defaults.
-
- If we don't support for either 128-bit IBM double double or IEEE 128-bit
- floating point, we need make sure the type is non-zero or else self-test
- fails during bootstrap.
-
- Always create __ibm128 as a separate type, even if the current long double
- format is IBM extended double.
-
- For IEEE 128-bit floating point, always create the type __ieee128. If the
- user used -mfloat128, rs6000-c.c will create a define from __float128 to
- __ieee128. */
- if (TARGET_FLOAT128_TYPE)
- {
- if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
- ibm128_float_type_node = long_double_type_node;
- else
- {
- ibm128_float_type_node = make_node (REAL_TYPE);
- TYPE_PRECISION (ibm128_float_type_node) = 128;
- SET_TYPE_MODE (ibm128_float_type_node, IFmode);
- layout_type (ibm128_float_type_node);
- }
-
- lang_hooks.types.register_builtin_type (ibm128_float_type_node,
- "__ibm128");
-
- if (TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128)
- ieee128_float_type_node = long_double_type_node;
- else
- ieee128_float_type_node = float128_type_node;
-
- lang_hooks.types.register_builtin_type (ieee128_float_type_node,
- "__ieee128");
- }
-
- else
- ieee128_float_type_node = ibm128_float_type_node = long_double_type_node;
-
- /* Initialize the modes for builtin_function_type, mapping a machine mode to
- tree type node. */
- builtin_mode_to_type[QImode][0] = integer_type_node;
- builtin_mode_to_type[HImode][0] = integer_type_node;
- builtin_mode_to_type[SImode][0] = intSI_type_node;
- builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
- builtin_mode_to_type[DImode][0] = intDI_type_node;
- builtin_mode_to_type[DImode][1] = unsigned_intDI_type_node;
- builtin_mode_to_type[TImode][0] = intTI_type_node;
- builtin_mode_to_type[TImode][1] = unsigned_intTI_type_node;
- builtin_mode_to_type[SFmode][0] = float_type_node;
- builtin_mode_to_type[DFmode][0] = double_type_node;
- builtin_mode_to_type[IFmode][0] = ibm128_float_type_node;
- builtin_mode_to_type[KFmode][0] = ieee128_float_type_node;
- builtin_mode_to_type[TFmode][0] = long_double_type_node;
- builtin_mode_to_type[DDmode][0] = dfloat64_type_node;
- builtin_mode_to_type[TDmode][0] = dfloat128_type_node;
- builtin_mode_to_type[V1TImode][0] = V1TI_type_node;
- builtin_mode_to_type[V1TImode][1] = unsigned_V1TI_type_node;
- builtin_mode_to_type[V2DImode][0] = V2DI_type_node;
- builtin_mode_to_type[V2DImode][1] = unsigned_V2DI_type_node;
- builtin_mode_to_type[V2DFmode][0] = V2DF_type_node;
- builtin_mode_to_type[V4SImode][0] = V4SI_type_node;
- builtin_mode_to_type[V4SImode][1] = unsigned_V4SI_type_node;
- builtin_mode_to_type[V4SFmode][0] = V4SF_type_node;
- builtin_mode_to_type[V8HImode][0] = V8HI_type_node;
- builtin_mode_to_type[V8HImode][1] = unsigned_V8HI_type_node;
- builtin_mode_to_type[V16QImode][0] = V16QI_type_node;
- builtin_mode_to_type[V16QImode][1] = unsigned_V16QI_type_node;
-
- tdecl = add_builtin_type ("__bool char", bool_char_type_node);
- TYPE_NAME (bool_char_type_node) = tdecl;
-
- tdecl = add_builtin_type ("__bool short", bool_short_type_node);
- TYPE_NAME (bool_short_type_node) = tdecl;
-
- tdecl = add_builtin_type ("__bool int", bool_int_type_node);
- TYPE_NAME (bool_int_type_node) = tdecl;
-
- tdecl = add_builtin_type ("__pixel", pixel_type_node);
- TYPE_NAME (pixel_type_node) = tdecl;
-
- bool_V16QI_type_node = rs6000_vector_type ("__vector __bool char",
- bool_char_type_node, 16);
- bool_V8HI_type_node = rs6000_vector_type ("__vector __bool short",
- bool_short_type_node, 8);
- bool_V4SI_type_node = rs6000_vector_type ("__vector __bool int",
- bool_int_type_node, 4);
- bool_V2DI_type_node = rs6000_vector_type (TARGET_POWERPC64
- ? "__vector __bool long"
- : "__vector __bool long long",
- bool_long_long_type_node, 2);
- pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel",
- pixel_type_node, 8);
-
- /* Create Altivec and VSX builtins on machines with at least the
- general purpose extensions (970 and newer) to allow the use of
- the target attribute. */
- if (TARGET_EXTRA_BUILTINS)
- altivec_init_builtins ();
- if (TARGET_HTM)
- htm_init_builtins ();
-
- if (TARGET_EXTRA_BUILTINS)
- rs6000_common_init_builtins ();
-
- ftype = builtin_function_type (DFmode, DFmode, DFmode, VOIDmode,
- RS6000_BUILTIN_RECIP, "__builtin_recipdiv");
- def_builtin ("__builtin_recipdiv", ftype, RS6000_BUILTIN_RECIP);
-
- ftype = builtin_function_type (SFmode, SFmode, SFmode, VOIDmode,
- RS6000_BUILTIN_RECIPF, "__builtin_recipdivf");
- def_builtin ("__builtin_recipdivf", ftype, RS6000_BUILTIN_RECIPF);
-
- ftype = builtin_function_type (DFmode, DFmode, VOIDmode, VOIDmode,
- RS6000_BUILTIN_RSQRT, "__builtin_rsqrt");
- def_builtin ("__builtin_rsqrt", ftype, RS6000_BUILTIN_RSQRT);
-
- ftype = builtin_function_type (SFmode, SFmode, VOIDmode, VOIDmode,
- RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf");
- def_builtin ("__builtin_rsqrtf", ftype, RS6000_BUILTIN_RSQRTF);
-
- mode = (TARGET_64BIT) ? DImode : SImode;
- ftype = builtin_function_type (mode, mode, mode, VOIDmode,
- POWER7_BUILTIN_BPERMD, "__builtin_bpermd");
- def_builtin ("__builtin_bpermd", ftype, POWER7_BUILTIN_BPERMD);
-
- ftype = build_function_type_list (unsigned_intDI_type_node,
- NULL_TREE);
- def_builtin ("__builtin_ppc_get_timebase", ftype, RS6000_BUILTIN_GET_TB);
-
- if (TARGET_64BIT)
- ftype = build_function_type_list (unsigned_intDI_type_node,
- NULL_TREE);
- else
- ftype = build_function_type_list (unsigned_intSI_type_node,
- NULL_TREE);
- def_builtin ("__builtin_ppc_mftb", ftype, RS6000_BUILTIN_MFTB);
-
- ftype = build_function_type_list (double_type_node, NULL_TREE);
- def_builtin ("__builtin_mffs", ftype, RS6000_BUILTIN_MFFS);
-
- ftype = build_function_type_list (double_type_node, NULL_TREE);
- def_builtin ("__builtin_mffsl", ftype, RS6000_BUILTIN_MFFSL);
-
- ftype = build_function_type_list (void_type_node,
- intSI_type_node,
- NULL_TREE);
- def_builtin ("__builtin_mtfsb0", ftype, RS6000_BUILTIN_MTFSB0);
-
- ftype = build_function_type_list (void_type_node,
- intSI_type_node,
- NULL_TREE);
- def_builtin ("__builtin_mtfsb1", ftype, RS6000_BUILTIN_MTFSB1);
-
- ftype = build_function_type_list (void_type_node,
- intDI_type_node,
- NULL_TREE);
- def_builtin ("__builtin_set_fpscr_rn", ftype, RS6000_BUILTIN_SET_FPSCR_RN);
-
- ftype = build_function_type_list (void_type_node,
- intDI_type_node,
- NULL_TREE);
- def_builtin ("__builtin_set_fpscr_drn", ftype, RS6000_BUILTIN_SET_FPSCR_DRN);
-
- ftype = build_function_type_list (void_type_node,
- intSI_type_node, double_type_node,
- NULL_TREE);
- def_builtin ("__builtin_mtfsf", ftype, RS6000_BUILTIN_MTFSF);
-
- ftype = build_function_type_list (void_type_node, NULL_TREE);
- def_builtin ("__builtin_cpu_init", ftype, RS6000_BUILTIN_CPU_INIT);
- def_builtin ("__builtin_ppc_speculation_barrier", ftype,
- MISC_BUILTIN_SPEC_BARRIER);
-
- ftype = build_function_type_list (bool_int_type_node, const_ptr_type_node,
- NULL_TREE);
- def_builtin ("__builtin_cpu_is", ftype, RS6000_BUILTIN_CPU_IS);
- def_builtin ("__builtin_cpu_supports", ftype, RS6000_BUILTIN_CPU_SUPPORTS);
-
- /* AIX libm provides clog as __clog. */
- if (TARGET_XCOFF &&
- (tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
- set_user_assembler_name (tdecl, "__clog");
-
-#ifdef SUBTARGET_INIT_BUILTINS
- SUBTARGET_INIT_BUILTINS;
-#endif
-}
-
-/* Returns the rs6000 builtin decl for CODE. */
-
-static tree
-rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
-{
- HOST_WIDE_INT fnmask;
-
- if (code >= RS6000_BUILTIN_COUNT)
- return error_mark_node;
-
- fnmask = rs6000_builtin_info[code].mask;
- if ((fnmask & rs6000_builtin_mask) != fnmask)
- {
- rs6000_invalid_builtin ((enum rs6000_builtins)code);
- return error_mark_node;
- }
-
- return rs6000_builtin_decls[code];
-}
-
-static void
-altivec_init_builtins (void)
-{
- const struct builtin_description *d;
- size_t i;
- tree ftype;
- tree decl;
- HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
-
- tree pvoid_type_node = build_pointer_type (void_type_node);
-
- tree pcvoid_type_node
- = build_pointer_type (build_qualified_type (void_type_node,
- TYPE_QUAL_CONST));
-
- tree int_ftype_opaque
- = build_function_type_list (integer_type_node,
- opaque_V4SI_type_node, NULL_TREE);
- tree opaque_ftype_opaque
- = build_function_type_list (integer_type_node, NULL_TREE);
- tree opaque_ftype_opaque_int
- = build_function_type_list (opaque_V4SI_type_node,
- opaque_V4SI_type_node, integer_type_node, NULL_TREE);
- tree opaque_ftype_opaque_opaque_int
- = build_function_type_list (opaque_V4SI_type_node,
- opaque_V4SI_type_node, opaque_V4SI_type_node,
- integer_type_node, NULL_TREE);
- tree opaque_ftype_opaque_opaque_opaque
- = build_function_type_list (opaque_V4SI_type_node,
- opaque_V4SI_type_node, opaque_V4SI_type_node,
- opaque_V4SI_type_node, NULL_TREE);
- tree opaque_ftype_opaque_opaque
- = build_function_type_list (opaque_V4SI_type_node,
- opaque_V4SI_type_node, opaque_V4SI_type_node,
- NULL_TREE);
- tree int_ftype_int_opaque_opaque
- = build_function_type_list (integer_type_node,
- integer_type_node, opaque_V4SI_type_node,
- opaque_V4SI_type_node, NULL_TREE);
- tree int_ftype_int_v4si_v4si
- = build_function_type_list (integer_type_node,
- integer_type_node, V4SI_type_node,
- V4SI_type_node, NULL_TREE);
- tree int_ftype_int_v2di_v2di
- = build_function_type_list (integer_type_node,
- integer_type_node, V2DI_type_node,
- V2DI_type_node, NULL_TREE);
- tree void_ftype_v4si
- = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
- tree v8hi_ftype_void
- = build_function_type_list (V8HI_type_node, NULL_TREE);
- tree void_ftype_void
- = build_function_type_list (void_type_node, NULL_TREE);
- tree void_ftype_int
- = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
-
- tree opaque_ftype_long_pcvoid
- = build_function_type_list (opaque_V4SI_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree v16qi_ftype_long_pcvoid
- = build_function_type_list (V16QI_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree v8hi_ftype_long_pcvoid
- = build_function_type_list (V8HI_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree v4si_ftype_long_pcvoid
- = build_function_type_list (V4SI_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree v4sf_ftype_long_pcvoid
- = build_function_type_list (V4SF_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree v2df_ftype_long_pcvoid
- = build_function_type_list (V2DF_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree v2di_ftype_long_pcvoid
- = build_function_type_list (V2DI_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree v1ti_ftype_long_pcvoid
- = build_function_type_list (V1TI_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
-
- tree void_ftype_opaque_long_pvoid
- = build_function_type_list (void_type_node,
- opaque_V4SI_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- tree void_ftype_v4si_long_pvoid
- = build_function_type_list (void_type_node,
- V4SI_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- tree void_ftype_v16qi_long_pvoid
- = build_function_type_list (void_type_node,
- V16QI_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
-
- tree void_ftype_v16qi_pvoid_long
- = build_function_type_list (void_type_node,
- V16QI_type_node, pvoid_type_node,
- long_integer_type_node, NULL_TREE);
-
- tree void_ftype_v8hi_long_pvoid
- = build_function_type_list (void_type_node,
- V8HI_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- tree void_ftype_v4sf_long_pvoid
- = build_function_type_list (void_type_node,
- V4SF_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- tree void_ftype_v2df_long_pvoid
- = build_function_type_list (void_type_node,
- V2DF_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- tree void_ftype_v1ti_long_pvoid
- = build_function_type_list (void_type_node,
- V1TI_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- tree void_ftype_v2di_long_pvoid
- = build_function_type_list (void_type_node,
- V2DI_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- tree int_ftype_int_v8hi_v8hi
- = build_function_type_list (integer_type_node,
- integer_type_node, V8HI_type_node,
- V8HI_type_node, NULL_TREE);
- tree int_ftype_int_v16qi_v16qi
- = build_function_type_list (integer_type_node,
- integer_type_node, V16QI_type_node,
- V16QI_type_node, NULL_TREE);
- tree int_ftype_int_v4sf_v4sf
- = build_function_type_list (integer_type_node,
- integer_type_node, V4SF_type_node,
- V4SF_type_node, NULL_TREE);
- tree int_ftype_int_v2df_v2df
- = build_function_type_list (integer_type_node,
- integer_type_node, V2DF_type_node,
- V2DF_type_node, NULL_TREE);
- tree v2di_ftype_v2di
- = build_function_type_list (V2DI_type_node, V2DI_type_node, NULL_TREE);
- tree v4si_ftype_v4si
- = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
- tree v8hi_ftype_v8hi
- = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
- tree v16qi_ftype_v16qi
- = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
- tree v4sf_ftype_v4sf
- = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
- tree v2df_ftype_v2df
- = build_function_type_list (V2DF_type_node, V2DF_type_node, NULL_TREE);
- tree void_ftype_pcvoid_int_int
- = build_function_type_list (void_type_node,
- pcvoid_type_node, integer_type_node,
- integer_type_node, NULL_TREE);
-
- def_builtin ("__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
- def_builtin ("__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
- def_builtin ("__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
- def_builtin ("__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
- def_builtin ("__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
- def_builtin ("__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
- def_builtin ("__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
- def_builtin ("__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
- def_builtin ("__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
- def_builtin ("__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
- def_builtin ("__builtin_altivec_lvxl_v2df", v2df_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVXL_V2DF);
- def_builtin ("__builtin_altivec_lvxl_v2di", v2di_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVXL_V2DI);
- def_builtin ("__builtin_altivec_lvxl_v4sf", v4sf_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVXL_V4SF);
- def_builtin ("__builtin_altivec_lvxl_v4si", v4si_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVXL_V4SI);
- def_builtin ("__builtin_altivec_lvxl_v8hi", v8hi_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVXL_V8HI);
- def_builtin ("__builtin_altivec_lvxl_v16qi", v16qi_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVXL_V16QI);
- def_builtin ("__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
- def_builtin ("__builtin_altivec_lvx_v1ti", v1ti_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVX_V1TI);
- def_builtin ("__builtin_altivec_lvx_v2df", v2df_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVX_V2DF);
- def_builtin ("__builtin_altivec_lvx_v2di", v2di_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVX_V2DI);
- def_builtin ("__builtin_altivec_lvx_v4sf", v4sf_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVX_V4SF);
- def_builtin ("__builtin_altivec_lvx_v4si", v4si_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVX_V4SI);
- def_builtin ("__builtin_altivec_lvx_v8hi", v8hi_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVX_V8HI);
- def_builtin ("__builtin_altivec_lvx_v16qi", v16qi_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_LVX_V16QI);
- def_builtin ("__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
- def_builtin ("__builtin_altivec_stvx_v2df", void_ftype_v2df_long_pvoid,
- ALTIVEC_BUILTIN_STVX_V2DF);
- def_builtin ("__builtin_altivec_stvx_v2di", void_ftype_v2di_long_pvoid,
- ALTIVEC_BUILTIN_STVX_V2DI);
- def_builtin ("__builtin_altivec_stvx_v4sf", void_ftype_v4sf_long_pvoid,
- ALTIVEC_BUILTIN_STVX_V4SF);
- def_builtin ("__builtin_altivec_stvx_v4si", void_ftype_v4si_long_pvoid,
- ALTIVEC_BUILTIN_STVX_V4SI);
- def_builtin ("__builtin_altivec_stvx_v8hi", void_ftype_v8hi_long_pvoid,
- ALTIVEC_BUILTIN_STVX_V8HI);
- def_builtin ("__builtin_altivec_stvx_v16qi", void_ftype_v16qi_long_pvoid,
- ALTIVEC_BUILTIN_STVX_V16QI);
- def_builtin ("__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
- def_builtin ("__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
- def_builtin ("__builtin_altivec_stvxl_v2df", void_ftype_v2df_long_pvoid,
- ALTIVEC_BUILTIN_STVXL_V2DF);
- def_builtin ("__builtin_altivec_stvxl_v2di", void_ftype_v2di_long_pvoid,
- ALTIVEC_BUILTIN_STVXL_V2DI);
- def_builtin ("__builtin_altivec_stvxl_v4sf", void_ftype_v4sf_long_pvoid,
- ALTIVEC_BUILTIN_STVXL_V4SF);
- def_builtin ("__builtin_altivec_stvxl_v4si", void_ftype_v4si_long_pvoid,
- ALTIVEC_BUILTIN_STVXL_V4SI);
- def_builtin ("__builtin_altivec_stvxl_v8hi", void_ftype_v8hi_long_pvoid,
- ALTIVEC_BUILTIN_STVXL_V8HI);
- def_builtin ("__builtin_altivec_stvxl_v16qi", void_ftype_v16qi_long_pvoid,
- ALTIVEC_BUILTIN_STVXL_V16QI);
- def_builtin ("__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
- def_builtin ("__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
- def_builtin ("__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
- def_builtin ("__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
- def_builtin ("__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
- def_builtin ("__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
- def_builtin ("__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
- def_builtin ("__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
- def_builtin ("__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
- def_builtin ("__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
- def_builtin ("__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
- def_builtin ("__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
- def_builtin ("__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
- def_builtin ("__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
- def_builtin ("__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
- def_builtin ("__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
-
- def_builtin ("__builtin_vsx_lxvd2x_v2df", v2df_ftype_long_pcvoid,
- VSX_BUILTIN_LXVD2X_V2DF);
- def_builtin ("__builtin_vsx_lxvd2x_v2di", v2di_ftype_long_pcvoid,
- VSX_BUILTIN_LXVD2X_V2DI);
- def_builtin ("__builtin_vsx_lxvw4x_v4sf", v4sf_ftype_long_pcvoid,
- VSX_BUILTIN_LXVW4X_V4SF);
- def_builtin ("__builtin_vsx_lxvw4x_v4si", v4si_ftype_long_pcvoid,
- VSX_BUILTIN_LXVW4X_V4SI);
- def_builtin ("__builtin_vsx_lxvw4x_v8hi", v8hi_ftype_long_pcvoid,
- VSX_BUILTIN_LXVW4X_V8HI);
- def_builtin ("__builtin_vsx_lxvw4x_v16qi", v16qi_ftype_long_pcvoid,
- VSX_BUILTIN_LXVW4X_V16QI);
- def_builtin ("__builtin_vsx_stxvd2x_v2df", void_ftype_v2df_long_pvoid,
- VSX_BUILTIN_STXVD2X_V2DF);
- def_builtin ("__builtin_vsx_stxvd2x_v2di", void_ftype_v2di_long_pvoid,
- VSX_BUILTIN_STXVD2X_V2DI);
- def_builtin ("__builtin_vsx_stxvw4x_v4sf", void_ftype_v4sf_long_pvoid,
- VSX_BUILTIN_STXVW4X_V4SF);
- def_builtin ("__builtin_vsx_stxvw4x_v4si", void_ftype_v4si_long_pvoid,
- VSX_BUILTIN_STXVW4X_V4SI);
- def_builtin ("__builtin_vsx_stxvw4x_v8hi", void_ftype_v8hi_long_pvoid,
- VSX_BUILTIN_STXVW4X_V8HI);
- def_builtin ("__builtin_vsx_stxvw4x_v16qi", void_ftype_v16qi_long_pvoid,
- VSX_BUILTIN_STXVW4X_V16QI);
-
- def_builtin ("__builtin_vsx_ld_elemrev_v2df", v2df_ftype_long_pcvoid,
- VSX_BUILTIN_LD_ELEMREV_V2DF);
- def_builtin ("__builtin_vsx_ld_elemrev_v2di", v2di_ftype_long_pcvoid,
- VSX_BUILTIN_LD_ELEMREV_V2DI);
- def_builtin ("__builtin_vsx_ld_elemrev_v4sf", v4sf_ftype_long_pcvoid,
- VSX_BUILTIN_LD_ELEMREV_V4SF);
- def_builtin ("__builtin_vsx_ld_elemrev_v4si", v4si_ftype_long_pcvoid,
- VSX_BUILTIN_LD_ELEMREV_V4SI);
- def_builtin ("__builtin_vsx_ld_elemrev_v8hi", v8hi_ftype_long_pcvoid,
- VSX_BUILTIN_LD_ELEMREV_V8HI);
- def_builtin ("__builtin_vsx_ld_elemrev_v16qi", v16qi_ftype_long_pcvoid,
- VSX_BUILTIN_LD_ELEMREV_V16QI);
- def_builtin ("__builtin_vsx_st_elemrev_v2df", void_ftype_v2df_long_pvoid,
- VSX_BUILTIN_ST_ELEMREV_V2DF);
- def_builtin ("__builtin_vsx_st_elemrev_v1ti", void_ftype_v1ti_long_pvoid,
- VSX_BUILTIN_ST_ELEMREV_V1TI);
- def_builtin ("__builtin_vsx_st_elemrev_v2di", void_ftype_v2di_long_pvoid,
- VSX_BUILTIN_ST_ELEMREV_V2DI);
- def_builtin ("__builtin_vsx_st_elemrev_v4sf", void_ftype_v4sf_long_pvoid,
- VSX_BUILTIN_ST_ELEMREV_V4SF);
- def_builtin ("__builtin_vsx_st_elemrev_v4si", void_ftype_v4si_long_pvoid,
- VSX_BUILTIN_ST_ELEMREV_V4SI);
- def_builtin ("__builtin_vsx_st_elemrev_v8hi", void_ftype_v8hi_long_pvoid,
- VSX_BUILTIN_ST_ELEMREV_V8HI);
- def_builtin ("__builtin_vsx_st_elemrev_v16qi", void_ftype_v16qi_long_pvoid,
- VSX_BUILTIN_ST_ELEMREV_V16QI);
-
- def_builtin ("__builtin_vec_vsx_ld", opaque_ftype_long_pcvoid,
- VSX_BUILTIN_VEC_LD);
- def_builtin ("__builtin_vec_vsx_st", void_ftype_opaque_long_pvoid,
- VSX_BUILTIN_VEC_ST);
- def_builtin ("__builtin_vec_xl", opaque_ftype_long_pcvoid,
- VSX_BUILTIN_VEC_XL);
- def_builtin ("__builtin_vec_xl_be", opaque_ftype_long_pcvoid,
- VSX_BUILTIN_VEC_XL_BE);
- def_builtin ("__builtin_vec_xst", void_ftype_opaque_long_pvoid,
- VSX_BUILTIN_VEC_XST);
- def_builtin ("__builtin_vec_xst_be", void_ftype_opaque_long_pvoid,
- VSX_BUILTIN_VEC_XST_BE);
-
- def_builtin ("__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
- def_builtin ("__builtin_vec_splats", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_SPLATS);
- def_builtin ("__builtin_vec_promote", opaque_ftype_opaque, ALTIVEC_BUILTIN_VEC_PROMOTE);
-
- def_builtin ("__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
- def_builtin ("__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
- def_builtin ("__builtin_vec_extract", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_EXTRACT);
- def_builtin ("__builtin_vec_insert", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_INSERT);
- def_builtin ("__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
- def_builtin ("__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
- def_builtin ("__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
- def_builtin ("__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
- def_builtin ("__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
- def_builtin ("__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
- def_builtin ("__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
- def_builtin ("__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
-
- def_builtin ("__builtin_vec_adde", opaque_ftype_opaque_opaque_opaque,
- ALTIVEC_BUILTIN_VEC_ADDE);
- def_builtin ("__builtin_vec_addec", opaque_ftype_opaque_opaque_opaque,
- ALTIVEC_BUILTIN_VEC_ADDEC);
- def_builtin ("__builtin_vec_cmpne", opaque_ftype_opaque_opaque,
- ALTIVEC_BUILTIN_VEC_CMPNE);
- def_builtin ("__builtin_vec_mul", opaque_ftype_opaque_opaque,
- ALTIVEC_BUILTIN_VEC_MUL);
- def_builtin ("__builtin_vec_sube", opaque_ftype_opaque_opaque_opaque,
- ALTIVEC_BUILTIN_VEC_SUBE);
- def_builtin ("__builtin_vec_subec", opaque_ftype_opaque_opaque_opaque,
- ALTIVEC_BUILTIN_VEC_SUBEC);
-
- /* Cell builtins. */
- def_builtin ("__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
- def_builtin ("__builtin_altivec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLXL);
- def_builtin ("__builtin_altivec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRX);
- def_builtin ("__builtin_altivec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVRXL);
-
- def_builtin ("__builtin_vec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLX);
- def_builtin ("__builtin_vec_lvlxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVLXL);
- def_builtin ("__builtin_vec_lvrx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRX);
- def_builtin ("__builtin_vec_lvrxl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVRXL);
-
- def_builtin ("__builtin_altivec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLX);
- def_builtin ("__builtin_altivec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVLXL);
- def_builtin ("__builtin_altivec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRX);
- def_builtin ("__builtin_altivec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVRXL);
-
- def_builtin ("__builtin_vec_stvlx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLX);
- def_builtin ("__builtin_vec_stvlxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVLXL);
- def_builtin ("__builtin_vec_stvrx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRX);
- def_builtin ("__builtin_vec_stvrxl", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_VEC_STVRXL);
-
- if (TARGET_P9_VECTOR)
- {
- def_builtin ("__builtin_altivec_stxvl", void_ftype_v16qi_pvoid_long,
- P9V_BUILTIN_STXVL);
- def_builtin ("__builtin_xst_len_r", void_ftype_v16qi_pvoid_long,
- P9V_BUILTIN_XST_LEN_R);
- }
-
- /* Add the DST variants. */
- d = bdesc_dst;
- for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
- {
- HOST_WIDE_INT mask = d->mask;
-
- /* It is expected that these dst built-in functions may have
- d->icode equal to CODE_FOR_nothing. */
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "altivec_init_builtins, skip dst %s\n",
- d->name);
- continue;
- }
- def_builtin (d->name, void_ftype_pcvoid_int_int, d->code);
- }
-
- /* Initialize the predicates. */
- d = bdesc_altivec_preds;
- for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, d++)
- {
- machine_mode mode1;
- tree type;
- HOST_WIDE_INT mask = d->mask;
-
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "altivec_init_builtins, skip predicate %s\n",
- d->name);
- continue;
- }
-
- if (rs6000_overloaded_builtin_p (d->code))
- mode1 = VOIDmode;
- else
- {
- /* Cannot define builtin if the instruction is disabled. */
- gcc_assert (d->icode != CODE_FOR_nothing);
- mode1 = insn_data[d->icode].operand[1].mode;
- }
-
- switch (mode1)
- {
- case E_VOIDmode:
- type = int_ftype_int_opaque_opaque;
- break;
- case E_V2DImode:
- type = int_ftype_int_v2di_v2di;
- break;
- case E_V4SImode:
- type = int_ftype_int_v4si_v4si;
- break;
- case E_V8HImode:
- type = int_ftype_int_v8hi_v8hi;
- break;
- case E_V16QImode:
- type = int_ftype_int_v16qi_v16qi;
- break;
- case E_V4SFmode:
- type = int_ftype_int_v4sf_v4sf;
- break;
- case E_V2DFmode:
- type = int_ftype_int_v2df_v2df;
- break;
- default:
- gcc_unreachable ();
- }
-
- def_builtin (d->name, type, d->code);
- }
-
- /* Initialize the abs* operators. */
- d = bdesc_abs;
- for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
- {
- machine_mode mode0;
- tree type;
- HOST_WIDE_INT mask = d->mask;
-
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "altivec_init_builtins, skip abs %s\n",
- d->name);
- continue;
- }
-
- /* Cannot define builtin if the instruction is disabled. */
- gcc_assert (d->icode != CODE_FOR_nothing);
- mode0 = insn_data[d->icode].operand[0].mode;
-
- switch (mode0)
- {
- case E_V2DImode:
- type = v2di_ftype_v2di;
- break;
- case E_V4SImode:
- type = v4si_ftype_v4si;
- break;
- case E_V8HImode:
- type = v8hi_ftype_v8hi;
- break;
- case E_V16QImode:
- type = v16qi_ftype_v16qi;
- break;
- case E_V4SFmode:
- type = v4sf_ftype_v4sf;
- break;
- case E_V2DFmode:
- type = v2df_ftype_v2df;
- break;
- default:
- gcc_unreachable ();
- }
-
- def_builtin (d->name, type, d->code);
- }
-
- /* Initialize target builtin that implements
- targetm.vectorize.builtin_mask_for_load. */
-
- decl = add_builtin_function ("__builtin_altivec_mask_for_load",
- v16qi_ftype_long_pcvoid,
- ALTIVEC_BUILTIN_MASK_FOR_LOAD,
- BUILT_IN_MD, NULL, NULL_TREE);
- TREE_READONLY (decl) = 1;
- /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
- altivec_builtin_mask_for_load = decl;
-
- /* Access to the vec_init patterns. */
- ftype = build_function_type_list (V4SI_type_node, integer_type_node,
- integer_type_node, integer_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_init_v4si", ftype, ALTIVEC_BUILTIN_VEC_INIT_V4SI);
-
- ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
- short_integer_type_node,
- short_integer_type_node,
- short_integer_type_node,
- short_integer_type_node,
- short_integer_type_node,
- short_integer_type_node,
- short_integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_init_v8hi", ftype, ALTIVEC_BUILTIN_VEC_INIT_V8HI);
-
- ftype = build_function_type_list (V16QI_type_node, char_type_node,
- char_type_node, char_type_node,
- char_type_node, char_type_node,
- char_type_node, char_type_node,
- char_type_node, char_type_node,
- char_type_node, char_type_node,
- char_type_node, char_type_node,
- char_type_node, char_type_node,
- char_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_init_v16qi", ftype,
- ALTIVEC_BUILTIN_VEC_INIT_V16QI);
-
- ftype = build_function_type_list (V4SF_type_node, float_type_node,
- float_type_node, float_type_node,
- float_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_init_v4sf", ftype, ALTIVEC_BUILTIN_VEC_INIT_V4SF);
-
- /* VSX builtins. */
- ftype = build_function_type_list (V2DF_type_node, double_type_node,
- double_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_init_v2df", ftype, VSX_BUILTIN_VEC_INIT_V2DF);
-
- ftype = build_function_type_list (V2DI_type_node, intDI_type_node,
- intDI_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_init_v2di", ftype, VSX_BUILTIN_VEC_INIT_V2DI);
-
- /* Access to the vec_set patterns. */
- ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
- intSI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_set_v4si", ftype, ALTIVEC_BUILTIN_VEC_SET_V4SI);
-
- ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
- intHI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_set_v8hi", ftype, ALTIVEC_BUILTIN_VEC_SET_V8HI);
-
- ftype = build_function_type_list (V16QI_type_node, V16QI_type_node,
- intQI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_set_v16qi", ftype, ALTIVEC_BUILTIN_VEC_SET_V16QI);
-
- ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
- float_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_set_v4sf", ftype, ALTIVEC_BUILTIN_VEC_SET_V4SF);
-
- ftype = build_function_type_list (V2DF_type_node, V2DF_type_node,
- double_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_set_v2df", ftype, VSX_BUILTIN_VEC_SET_V2DF);
-
- ftype = build_function_type_list (V2DI_type_node, V2DI_type_node,
- intDI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_set_v2di", ftype, VSX_BUILTIN_VEC_SET_V2DI);
-
- /* Access to the vec_extract patterns. */
- ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_ext_v4si", ftype, ALTIVEC_BUILTIN_VEC_EXT_V4SI);
-
- ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_ext_v8hi", ftype, ALTIVEC_BUILTIN_VEC_EXT_V8HI);
-
- ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_ext_v16qi", ftype, ALTIVEC_BUILTIN_VEC_EXT_V16QI);
-
- ftype = build_function_type_list (float_type_node, V4SF_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_ext_v4sf", ftype, ALTIVEC_BUILTIN_VEC_EXT_V4SF);
-
- ftype = build_function_type_list (double_type_node, V2DF_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_ext_v2df", ftype, VSX_BUILTIN_VEC_EXT_V2DF);
-
- ftype = build_function_type_list (intDI_type_node, V2DI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_ext_v2di", ftype, VSX_BUILTIN_VEC_EXT_V2DI);
-
-
- if (V1TI_type_node)
- {
- tree v1ti_ftype_long_pcvoid
- = build_function_type_list (V1TI_type_node,
- long_integer_type_node, pcvoid_type_node,
- NULL_TREE);
- tree void_ftype_v1ti_long_pvoid
- = build_function_type_list (void_type_node,
- V1TI_type_node, long_integer_type_node,
- pvoid_type_node, NULL_TREE);
- def_builtin ("__builtin_vsx_ld_elemrev_v1ti", v1ti_ftype_long_pcvoid,
- VSX_BUILTIN_LD_ELEMREV_V1TI);
- def_builtin ("__builtin_vsx_lxvd2x_v1ti", v1ti_ftype_long_pcvoid,
- VSX_BUILTIN_LXVD2X_V1TI);
- def_builtin ("__builtin_vsx_stxvd2x_v1ti", void_ftype_v1ti_long_pvoid,
- VSX_BUILTIN_STXVD2X_V1TI);
- ftype = build_function_type_list (V1TI_type_node, intTI_type_node,
- NULL_TREE, NULL_TREE);
- def_builtin ("__builtin_vec_init_v1ti", ftype, VSX_BUILTIN_VEC_INIT_V1TI);
- ftype = build_function_type_list (V1TI_type_node, V1TI_type_node,
- intTI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_set_v1ti", ftype, VSX_BUILTIN_VEC_SET_V1TI);
- ftype = build_function_type_list (intTI_type_node, V1TI_type_node,
- integer_type_node, NULL_TREE);
- def_builtin ("__builtin_vec_ext_v1ti", ftype, VSX_BUILTIN_VEC_EXT_V1TI);
- }
-
-}
-
-static void
-htm_init_builtins (void)
-{
- HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
- const struct builtin_description *d;
- size_t i;
-
- d = bdesc_htm;
- for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
- {
- tree op[MAX_HTM_OPERANDS], type;
- HOST_WIDE_INT mask = d->mask;
- unsigned attr = rs6000_builtin_info[d->code].attr;
- bool void_func = (attr & RS6000_BTC_VOID);
- int attr_args = (attr & RS6000_BTC_TYPE_MASK);
- int nopnds = 0;
- tree gpr_type_node;
- tree rettype;
- tree argtype;
-
- /* It is expected that these htm built-in functions may have
- d->icode equal to CODE_FOR_nothing. */
-
- if (TARGET_32BIT && TARGET_POWERPC64)
- gpr_type_node = long_long_unsigned_type_node;
- else
- gpr_type_node = long_unsigned_type_node;
-
- if (attr & RS6000_BTC_SPR)
- {
- rettype = gpr_type_node;
- argtype = gpr_type_node;
- }
- else if (d->code == HTM_BUILTIN_TABORTDC
- || d->code == HTM_BUILTIN_TABORTDCI)
- {
- rettype = unsigned_type_node;
- argtype = gpr_type_node;
- }
- else
- {
- rettype = unsigned_type_node;
- argtype = unsigned_type_node;
- }
-
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "htm_builtin, skip binary %s\n", d->name);
- continue;
- }
-
- if (d->name == 0)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "htm_builtin, bdesc_htm[%ld] no name\n",
- (long unsigned) i);
- continue;
- }
-
- op[nopnds++] = (void_func) ? void_type_node : rettype;
-
- if (attr_args == RS6000_BTC_UNARY)
- op[nopnds++] = argtype;
- else if (attr_args == RS6000_BTC_BINARY)
- {
- op[nopnds++] = argtype;
- op[nopnds++] = argtype;
- }
- else if (attr_args == RS6000_BTC_TERNARY)
- {
- op[nopnds++] = argtype;
- op[nopnds++] = argtype;
- op[nopnds++] = argtype;
- }
-
- switch (nopnds)
- {
- case 1:
- type = build_function_type_list (op[0], NULL_TREE);
- break;
- case 2:
- type = build_function_type_list (op[0], op[1], NULL_TREE);
- break;
- case 3:
- type = build_function_type_list (op[0], op[1], op[2], NULL_TREE);
- break;
- case 4:
- type = build_function_type_list (op[0], op[1], op[2], op[3],
- NULL_TREE);
- break;
- default:
- gcc_unreachable ();
- }
-
- def_builtin (d->name, type, d->code);
- }
-}
-
-/* Hash function for builtin functions with up to 3 arguments and a return
- type. */
-hashval_t
-builtin_hasher::hash (builtin_hash_struct *bh)
-{
- unsigned ret = 0;
- int i;
-
- for (i = 0; i < 4; i++)
- {
- ret = (ret * (unsigned)MAX_MACHINE_MODE) + ((unsigned)bh->mode[i]);
- ret = (ret * 2) + bh->uns_p[i];
- }
-
- return ret;
-}
-
-/* Compare builtin hash entries H1 and H2 for equivalence. */
-bool
-builtin_hasher::equal (builtin_hash_struct *p1, builtin_hash_struct *p2)
-{
- return ((p1->mode[0] == p2->mode[0])
- && (p1->mode[1] == p2->mode[1])
- && (p1->mode[2] == p2->mode[2])
- && (p1->mode[3] == p2->mode[3])
- && (p1->uns_p[0] == p2->uns_p[0])
- && (p1->uns_p[1] == p2->uns_p[1])
- && (p1->uns_p[2] == p2->uns_p[2])
- && (p1->uns_p[3] == p2->uns_p[3]));
-}
-
-/* Map types for builtin functions with an explicit return type and up to 3
- arguments. Functions with fewer than 3 arguments use VOIDmode as the type
- of the argument. */
-static tree
-builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
- machine_mode mode_arg1, machine_mode mode_arg2,
- enum rs6000_builtins builtin, const char *name)
-{
- struct builtin_hash_struct h;
- struct builtin_hash_struct *h2;
- int num_args = 3;
- int i;
- tree ret_type = NULL_TREE;
- tree arg_type[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
-
- /* Create builtin_hash_table. */
- if (builtin_hash_table == NULL)
- builtin_hash_table = hash_table<builtin_hasher>::create_ggc (1500);
-
- h.type = NULL_TREE;
- h.mode[0] = mode_ret;
- h.mode[1] = mode_arg0;
- h.mode[2] = mode_arg1;
- h.mode[3] = mode_arg2;
- h.uns_p[0] = 0;
- h.uns_p[1] = 0;
- h.uns_p[2] = 0;
- h.uns_p[3] = 0;
-
- /* If the builtin is a type that produces unsigned results or takes unsigned
- arguments, and it is returned as a decl for the vectorizer (such as
- widening multiplies, permute), make sure the arguments and return value
- are type correct. */
- switch (builtin)
- {
- /* unsigned 1 argument functions. */
- case CRYPTO_BUILTIN_VSBOX:
- case CRYPTO_BUILTIN_VSBOX_BE:
- case P8V_BUILTIN_VGBBD:
- case MISC_BUILTIN_CDTBCD:
- case MISC_BUILTIN_CBCDTD:
- h.uns_p[0] = 1;
- h.uns_p[1] = 1;
- break;
-
- /* unsigned 2 argument functions. */
- case ALTIVEC_BUILTIN_VMULEUB:
- case ALTIVEC_BUILTIN_VMULEUH:
- case P8V_BUILTIN_VMULEUW:
- case ALTIVEC_BUILTIN_VMULOUB:
- case ALTIVEC_BUILTIN_VMULOUH:
- case P8V_BUILTIN_VMULOUW:
- case CRYPTO_BUILTIN_VCIPHER:
- case CRYPTO_BUILTIN_VCIPHER_BE:
- case CRYPTO_BUILTIN_VCIPHERLAST:
- case CRYPTO_BUILTIN_VCIPHERLAST_BE:
- case CRYPTO_BUILTIN_VNCIPHER:
- case CRYPTO_BUILTIN_VNCIPHER_BE:
- case CRYPTO_BUILTIN_VNCIPHERLAST:
- case CRYPTO_BUILTIN_VNCIPHERLAST_BE:
- case CRYPTO_BUILTIN_VPMSUMB:
- case CRYPTO_BUILTIN_VPMSUMH:
- case CRYPTO_BUILTIN_VPMSUMW:
- case CRYPTO_BUILTIN_VPMSUMD:
- case CRYPTO_BUILTIN_VPMSUM:
- case MISC_BUILTIN_ADDG6S:
- case MISC_BUILTIN_DIVWEU:
- case MISC_BUILTIN_DIVDEU:
- case VSX_BUILTIN_UDIV_V2DI:
- case ALTIVEC_BUILTIN_VMAXUB:
- case ALTIVEC_BUILTIN_VMINUB:
- case ALTIVEC_BUILTIN_VMAXUH:
- case ALTIVEC_BUILTIN_VMINUH:
- case ALTIVEC_BUILTIN_VMAXUW:
- case ALTIVEC_BUILTIN_VMINUW:
- case P8V_BUILTIN_VMAXUD:
- case P8V_BUILTIN_VMINUD:
- h.uns_p[0] = 1;
- h.uns_p[1] = 1;
- h.uns_p[2] = 1;
- break;
-
- /* unsigned 3 argument functions. */
- case ALTIVEC_BUILTIN_VPERM_16QI_UNS:
- case ALTIVEC_BUILTIN_VPERM_8HI_UNS:
- case ALTIVEC_BUILTIN_VPERM_4SI_UNS:
- case ALTIVEC_BUILTIN_VPERM_2DI_UNS:
- case ALTIVEC_BUILTIN_VSEL_16QI_UNS:
- case ALTIVEC_BUILTIN_VSEL_8HI_UNS:
- case ALTIVEC_BUILTIN_VSEL_4SI_UNS:
- case ALTIVEC_BUILTIN_VSEL_2DI_UNS:
- case VSX_BUILTIN_VPERM_16QI_UNS:
- case VSX_BUILTIN_VPERM_8HI_UNS:
- case VSX_BUILTIN_VPERM_4SI_UNS:
- case VSX_BUILTIN_VPERM_2DI_UNS:
- case VSX_BUILTIN_XXSEL_16QI_UNS:
- case VSX_BUILTIN_XXSEL_8HI_UNS:
- case VSX_BUILTIN_XXSEL_4SI_UNS:
- case VSX_BUILTIN_XXSEL_2DI_UNS:
- case CRYPTO_BUILTIN_VPERMXOR:
- case CRYPTO_BUILTIN_VPERMXOR_V2DI:
- case CRYPTO_BUILTIN_VPERMXOR_V4SI:
- case CRYPTO_BUILTIN_VPERMXOR_V8HI:
- case CRYPTO_BUILTIN_VPERMXOR_V16QI:
- case CRYPTO_BUILTIN_VSHASIGMAW:
- case CRYPTO_BUILTIN_VSHASIGMAD:
- case CRYPTO_BUILTIN_VSHASIGMA:
- h.uns_p[0] = 1;
- h.uns_p[1] = 1;
- h.uns_p[2] = 1;
- h.uns_p[3] = 1;
- break;
-
- /* signed permute functions with unsigned char mask. */
- case ALTIVEC_BUILTIN_VPERM_16QI:
- case ALTIVEC_BUILTIN_VPERM_8HI:
- case ALTIVEC_BUILTIN_VPERM_4SI:
- case ALTIVEC_BUILTIN_VPERM_4SF:
- case ALTIVEC_BUILTIN_VPERM_2DI:
- case ALTIVEC_BUILTIN_VPERM_2DF:
- case VSX_BUILTIN_VPERM_16QI:
- case VSX_BUILTIN_VPERM_8HI:
- case VSX_BUILTIN_VPERM_4SI:
- case VSX_BUILTIN_VPERM_4SF:
- case VSX_BUILTIN_VPERM_2DI:
- case VSX_BUILTIN_VPERM_2DF:
- h.uns_p[3] = 1;
- break;
-
- /* unsigned args, signed return. */
- case VSX_BUILTIN_XVCVUXDSP:
- case VSX_BUILTIN_XVCVUXDDP_UNS:
- case ALTIVEC_BUILTIN_UNSFLOAT_V4SI_V4SF:
- h.uns_p[1] = 1;
- break;
-
- /* signed args, unsigned return. */
- case VSX_BUILTIN_XVCVDPUXDS_UNS:
- case ALTIVEC_BUILTIN_FIXUNS_V4SF_V4SI:
- case MISC_BUILTIN_UNPACK_TD:
- case MISC_BUILTIN_UNPACK_V1TI:
- h.uns_p[0] = 1;
- break;
-
- /* unsigned arguments, bool return (compares). */
- case ALTIVEC_BUILTIN_VCMPEQUB:
- case ALTIVEC_BUILTIN_VCMPEQUH:
- case ALTIVEC_BUILTIN_VCMPEQUW:
- case P8V_BUILTIN_VCMPEQUD:
- case VSX_BUILTIN_CMPGE_U16QI:
- case VSX_BUILTIN_CMPGE_U8HI:
- case VSX_BUILTIN_CMPGE_U4SI:
- case VSX_BUILTIN_CMPGE_U2DI:
- case ALTIVEC_BUILTIN_VCMPGTUB:
- case ALTIVEC_BUILTIN_VCMPGTUH:
- case ALTIVEC_BUILTIN_VCMPGTUW:
- case P8V_BUILTIN_VCMPGTUD:
- h.uns_p[1] = 1;
- h.uns_p[2] = 1;
- break;
-
- /* unsigned arguments for 128-bit pack instructions. */
- case MISC_BUILTIN_PACK_TD:
- case MISC_BUILTIN_PACK_V1TI:
- h.uns_p[1] = 1;
- h.uns_p[2] = 1;
- break;
-
- /* unsigned second arguments (vector shift right). */
- case ALTIVEC_BUILTIN_VSRB:
- case ALTIVEC_BUILTIN_VSRH:
- case ALTIVEC_BUILTIN_VSRW:
- case P8V_BUILTIN_VSRD:
- h.uns_p[2] = 1;
- break;
-
- default:
- break;
- }
-
- /* Figure out how many args are present. */
- while (num_args > 0 && h.mode[num_args] == VOIDmode)
- num_args--;
-
- ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
- if (!ret_type && h.uns_p[0])
- ret_type = builtin_mode_to_type[h.mode[0]][0];
-
- if (!ret_type)
- fatal_error (input_location,
- "internal error: builtin function %qs had an unexpected "
- "return type %qs", name, GET_MODE_NAME (h.mode[0]));
-
- for (i = 0; i < (int) ARRAY_SIZE (arg_type); i++)
- arg_type[i] = NULL_TREE;
-
- for (i = 0; i < num_args; i++)
- {
- int m = (int) h.mode[i+1];
- int uns_p = h.uns_p[i+1];
-
- arg_type[i] = builtin_mode_to_type[m][uns_p];
- if (!arg_type[i] && uns_p)
- arg_type[i] = builtin_mode_to_type[m][0];
-
- if (!arg_type[i])
- fatal_error (input_location,
- "internal error: builtin function %qs, argument %d "
- "had unexpected argument type %qs", name, i,
- GET_MODE_NAME (m));
- }
-
- builtin_hash_struct **found = builtin_hash_table->find_slot (&h, INSERT);
- if (*found == NULL)
- {
- h2 = ggc_alloc<builtin_hash_struct> ();
- *h2 = h;
- *found = h2;
-
- h2->type = build_function_type_list (ret_type, arg_type[0], arg_type[1],
- arg_type[2], NULL_TREE);
- }
-
- return (*found)->type;
-}
-
-static void
-rs6000_common_init_builtins (void)
-{
- const struct builtin_description *d;
- size_t i;
-
- tree opaque_ftype_opaque = NULL_TREE;
- tree opaque_ftype_opaque_opaque = NULL_TREE;
- tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
- HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
-
- /* Create Altivec and VSX builtins on machines with at least the
- general purpose extensions (970 and newer) to allow the use of
- the target attribute. */
-
- if (TARGET_EXTRA_BUILTINS)
- builtin_mask |= RS6000_BTM_COMMON;
-
- /* Add the ternary operators. */
- d = bdesc_3arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
- {
- tree type;
- HOST_WIDE_INT mask = d->mask;
-
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, skip ternary %s\n", d->name);
- continue;
- }
-
- if (rs6000_overloaded_builtin_p (d->code))
- {
- if (! (type = opaque_ftype_opaque_opaque_opaque))
- type = opaque_ftype_opaque_opaque_opaque
- = build_function_type_list (opaque_V4SI_type_node,
- opaque_V4SI_type_node,
- opaque_V4SI_type_node,
- opaque_V4SI_type_node,
- NULL_TREE);
- }
- else
- {
- enum insn_code icode = d->icode;
- if (d->name == 0)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, bdesc_3arg[%ld] no name\n",
- (long unsigned)i);
-
- continue;
- }
-
- if (icode == CODE_FOR_nothing)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, skip ternary %s (no code)\n",
- d->name);
-
- continue;
- }
-
- type = builtin_function_type (insn_data[icode].operand[0].mode,
- insn_data[icode].operand[1].mode,
- insn_data[icode].operand[2].mode,
- insn_data[icode].operand[3].mode,
- d->code, d->name);
- }
-
- def_builtin (d->name, type, d->code);
- }
-
- /* Add the binary operators. */
- d = bdesc_2arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
- {
- machine_mode mode0, mode1, mode2;
- tree type;
- HOST_WIDE_INT mask = d->mask;
-
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, skip binary %s\n", d->name);
- continue;
- }
-
- if (rs6000_overloaded_builtin_p (d->code))
- {
- if (! (type = opaque_ftype_opaque_opaque))
- type = opaque_ftype_opaque_opaque
- = build_function_type_list (opaque_V4SI_type_node,
- opaque_V4SI_type_node,
- opaque_V4SI_type_node,
- NULL_TREE);
- }
- else
- {
- enum insn_code icode = d->icode;
- if (d->name == 0)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, bdesc_2arg[%ld] no name\n",
- (long unsigned)i);
-
- continue;
- }
-
- if (icode == CODE_FOR_nothing)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, skip binary %s (no code)\n",
- d->name);
-
- continue;
- }
-
- mode0 = insn_data[icode].operand[0].mode;
- mode1 = insn_data[icode].operand[1].mode;
- mode2 = insn_data[icode].operand[2].mode;
-
- type = builtin_function_type (mode0, mode1, mode2, VOIDmode,
- d->code, d->name);
- }
-
- def_builtin (d->name, type, d->code);
- }
-
- /* Add the simple unary operators. */
- d = bdesc_1arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
- {
- machine_mode mode0, mode1;
- tree type;
- HOST_WIDE_INT mask = d->mask;
-
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, skip unary %s\n", d->name);
- continue;
- }
-
- if (rs6000_overloaded_builtin_p (d->code))
- {
- if (! (type = opaque_ftype_opaque))
- type = opaque_ftype_opaque
- = build_function_type_list (opaque_V4SI_type_node,
- opaque_V4SI_type_node,
- NULL_TREE);
- }
- else
- {
- enum insn_code icode = d->icode;
- if (d->name == 0)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, bdesc_1arg[%ld] no name\n",
- (long unsigned)i);
-
- continue;
- }
-
- if (icode == CODE_FOR_nothing)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, skip unary %s (no code)\n",
- d->name);
-
- continue;
- }
-
- mode0 = insn_data[icode].operand[0].mode;
- mode1 = insn_data[icode].operand[1].mode;
-
- type = builtin_function_type (mode0, mode1, VOIDmode, VOIDmode,
- d->code, d->name);
- }
-
- def_builtin (d->name, type, d->code);
- }
-
- /* Add the simple no-argument operators. */
- d = bdesc_0arg;
- for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
- {
- machine_mode mode0;
- tree type;
- HOST_WIDE_INT mask = d->mask;
-
- if ((mask & builtin_mask) != mask)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, skip no-argument %s\n", d->name);
- continue;
- }
- if (rs6000_overloaded_builtin_p (d->code))
- {
- if (!opaque_ftype_opaque)
- opaque_ftype_opaque
- = build_function_type_list (opaque_V4SI_type_node, NULL_TREE);
- type = opaque_ftype_opaque;
- }
- else
- {
- enum insn_code icode = d->icode;
- if (d->name == 0)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr, "rs6000_builtin, bdesc_0arg[%lu] no name\n",
- (long unsigned) i);
- continue;
- }
- if (icode == CODE_FOR_nothing)
- {
- if (TARGET_DEBUG_BUILTIN)
- fprintf (stderr,
- "rs6000_builtin, skip no-argument %s (no code)\n",
- d->name);
- continue;
- }
- mode0 = insn_data[icode].operand[0].mode;
- type = builtin_function_type (mode0, VOIDmode, VOIDmode, VOIDmode,
- d->code, d->name);
- }
- def_builtin (d->name, type, d->code);
- }
-}
/* Set up AIX/Darwin/64-bit Linux quad floating point routines. */
static void
@@ -21023,7 +13161,7 @@ print_operand_address (FILE *file, rtx x)
/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
-static bool
+bool
rs6000_output_addr_const_extra (FILE *file, rtx x)
{
if (GET_CODE (x) == UNSPEC)
@@ -21460,7 +13598,7 @@ mode_supports_prefixed_address_p (machine_mode mode)
mode MODE. */
bool
-rs6000_prefixed_address (rtx addr, machine_mode mode)
+rs6000_prefixed_address_mode_p (rtx addr, machine_mode mode)
{
if (!TARGET_PREFIXED_ADDR || !mode_supports_prefixed_address_p (mode))
return false;
@@ -21480,11 +13618,11 @@ rs6000_prefixed_address (rtx addr, machine_mode mode)
return false;
HOST_WIDE_INT value = INTVAL (op1);
- if (!SIGNED_34BIT_OFFSET_P (value, 0))
+ if (!SIGNED_34BIT_OFFSET_P (value))
return false;
/* Offset larger than 16-bits? */
- if (!SIGNED_16BIT_OFFSET_P (value, 0))
+ if (!SIGNED_16BIT_OFFSET_P (value))
return true;
/* DQ instruction (bottom 4 bits must be 0) for vectors. */
@@ -23693,183 +15831,35 @@ rs6000_split_multireg_move (rtx dst, rtx src)
}
}
-static GTY(()) alias_set_type set = -1;
+static GTY(()) alias_set_type TOC_alias_set = -1;
alias_set_type
get_TOC_alias_set (void)
{
- if (set == -1)
- set = new_alias_set ();
- return set;
-}
-
-/* Return the internal arg pointer used for function incoming
- arguments. When -fsplit-stack, the arg pointer is r12 so we need
- to copy it to a pseudo in order for it to be preserved over calls
- and suchlike. We'd really like to use a pseudo here for the
- internal arg pointer but data-flow analysis is not prepared to
- accept pseudos as live at the beginning of a function. */
-
-static rtx
-rs6000_internal_arg_pointer (void)
-{
- if (flag_split_stack
- && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl))
- == NULL))
-
- {
- if (cfun->machine->split_stack_arg_pointer == NULL_RTX)
- {
- rtx pat;
-
- cfun->machine->split_stack_arg_pointer = gen_reg_rtx (Pmode);
- REG_POINTER (cfun->machine->split_stack_arg_pointer) = 1;
-
- /* Put the pseudo initialization right after the note at the
- beginning of the function. */
- pat = gen_rtx_SET (cfun->machine->split_stack_arg_pointer,
- gen_rtx_REG (Pmode, 12));
- push_topmost_sequence ();
- emit_insn_after (pat, get_insns ());
- pop_topmost_sequence ();
- }
- rtx ret = plus_constant (Pmode, cfun->machine->split_stack_arg_pointer,
- FIRST_PARM_OFFSET (current_function_decl));
- return copy_to_reg (ret);
- }
- return virtual_incoming_args_rtx;
+ if (TOC_alias_set == -1)
+ TOC_alias_set = new_alias_set ();
+ return TOC_alias_set;
}
-/* We may have to tell the dataflow pass that the split stack prologue
- is initializing a register. */
+/* The mode the ABI uses for a word. This is not the same as word_mode
+ for -m32 -mpowerpc64. This is used to implement various target hooks. */
-static void
-rs6000_live_on_entry (bitmap regs)
+static scalar_int_mode
+rs6000_abi_word_mode (void)
{
- if (flag_split_stack)
- bitmap_set_bit (regs, 12);
+ return TARGET_32BIT ? SImode : DImode;
}
-
-/* A C compound statement that outputs the assembler code for a thunk
- function, used to implement C++ virtual function calls with
- multiple inheritance. The thunk acts as a wrapper around a virtual
- function, adjusting the implicit object parameter before handing
- control off to the real function.
-
- First, emit code to add the integer DELTA to the location that
- contains the incoming first argument. Assume that this argument
- contains a pointer, and is the one used to pass the `this' pointer
- in C++. This is the incoming argument *before* the function
- prologue, e.g. `%o0' on a sparc. The addition must preserve the
- values of all other incoming arguments.
-
- After the addition, emit code to jump to FUNCTION, which is a
- `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
- not touch the return address. Hence returning from FUNCTION will
- return to whoever called the current `thunk'.
-
- The effect must be as if FUNCTION had been called directly with the
- adjusted first argument. This macro is responsible for emitting
- all of the code for a thunk function; output_function_prologue()
- and output_function_epilogue() are not invoked.
-
- The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
- been extracted from it.) It might possibly be useful on some
- targets, but probably not.
-
- If you do not define this macro, the target-independent code in the
- C++ frontend will generate a less efficient heavyweight thunk that
- calls FUNCTION instead of jumping to it. The generic approach does
- not support varargs. */
-
-static void
-rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
- HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
- tree function)
+/* Implement the TARGET_OFFLOAD_OPTIONS hook. */
+static char *
+rs6000_offload_options (void)
{
- const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
- rtx this_rtx, funexp;
- rtx_insn *insn;
-
- reload_completed = 1;
- epilogue_completed = 1;
-
- /* Mark the end of the (empty) prologue. */
- emit_note (NOTE_INSN_PROLOGUE_END);
-
- /* Find the "this" pointer. If the function returns a structure,
- the structure return pointer is in r3. */
- if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
- this_rtx = gen_rtx_REG (Pmode, 4);
+ if (TARGET_64BIT)
+ return xstrdup ("-foffload-abi=lp64");
else
- this_rtx = gen_rtx_REG (Pmode, 3);
-
- /* Apply the constant offset, if required. */
- if (delta)
- emit_insn (gen_add3_insn (this_rtx, this_rtx, GEN_INT (delta)));
-
- /* Apply the offset from the vtable, if required. */
- if (vcall_offset)
- {
- rtx vcall_offset_rtx = GEN_INT (vcall_offset);
- rtx tmp = gen_rtx_REG (Pmode, 12);
-
- emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
- if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
- {
- emit_insn (gen_add3_insn (tmp, tmp, vcall_offset_rtx));
- emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
- }
- else
- {
- rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
-
- emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
- }
- emit_insn (gen_add3_insn (this_rtx, this_rtx, tmp));
- }
-
- /* Generate a tail call to the target function. */
- if (!TREE_USED (function))
- {
- assemble_external (function);
- TREE_USED (function) = 1;
- }
- funexp = XEXP (DECL_RTL (function), 0);
- funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
-
-#if TARGET_MACHO
- if (MACHOPIC_INDIRECT)
- funexp = machopic_indirect_call_target (funexp);
-#endif
-
- /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
- generate sibcall RTL explicitly. */
- insn = emit_call_insn (
- gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (3,
- gen_rtx_CALL (VOIDmode,
- funexp, const0_rtx),
- gen_rtx_USE (VOIDmode, const0_rtx),
- simple_return_rtx)));
- SIBLING_CALL_P (insn) = 1;
- emit_barrier ();
-
- /* Run just enough of rest_of_compilation to get the insns emitted.
- There's not really enough bulk here to make other passes such as
- instruction scheduling worth while. */
- insn = get_insns ();
- shorten_branches (insn);
- assemble_start_function (thunk_fndecl, fnname);
- final_start_function (insn, file, 1);
- final (insn, file, 1);
- final_end_function ();
- assemble_end_function (thunk_fndecl, fnname);
-
- reload_completed = 0;
- epilogue_completed = 0;
+ return xstrdup ("-foffload-abi=ilp32");
}
+
/* A quick summary of the various types of 'constant-pool tables'
under PowerPC:
@@ -24071,7 +16061,7 @@ output_toc (FILE *file, rtx x, int labelno, machine_mode mode)
rtx base = x;
HOST_WIDE_INT offset = 0;
- gcc_assert (!TARGET_NO_TOC);
+ gcc_assert (!TARGET_NO_TOC_OR_PCREL);
/* When the linker won't eliminate them, don't output duplicate
TOC entries (this happens on AIX if there is any kind of TOC,
@@ -30437,7 +22427,7 @@ rs6000_can_eliminate (const int from, const int to)
return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM
? ! frame_pointer_needed
: from == RS6000_PIC_OFFSET_TABLE_REGNUM
- ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC
+ ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC_OR_PCREL
|| constant_pool_empty_p ()
: true);
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9193d9e..70e0616 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -54,6 +54,13 @@
#define TARGET_AIX_OS 0
#endif
+/* Turn off TOC support if pc-relative addressing is used. */
+#define TARGET_TOC (TARGET_HAS_TOC && !TARGET_PCREL)
+
+/* On 32-bit systems without a TOC or pc-relative addressing, we need to use
+ ADDIS/ADDI to load up the address of a symbol. */
+#define TARGET_NO_TOC_OR_PCREL (!TARGET_HAS_TOC && !TARGET_PCREL)
+
/* Control whether function entry points use a "dot" symbol when
ABI_AIX. */
#define DOT_SYMBOLS 1
@@ -2526,16 +2533,27 @@ typedef struct GTY(()) machine_function
#pragma GCC poison TARGET_FLOAT128 OPTION_MASK_FLOAT128 MASK_FLOAT128
#endif
-/* Whether a given VALUE is a valid 16- or 34-bit signed offset. EXTRA is the
- amount that we can't touch at the high end of the range (typically if the
- address is split into smaller addresses, the extra covers the addresses
- which might be generated when the insn is split). */
-#define SIGNED_16BIT_OFFSET_P(VALUE, EXTRA) \
- IN_RANGE (VALUE, \
+/* Whether a given VALUE is a valid 16 or 34-bit signed offset. */
+#define SIGNED_16BIT_OFFSET_P(VALUE) \
+ IN_RANGE ((VALUE), \
+ -(HOST_WIDE_INT_1 << 15), \
+ (HOST_WIDE_INT_1 << 15) - 1)
+
+#define SIGNED_34BIT_OFFSET_P(VALUE) \
+ IN_RANGE ((VALUE), \
+ -(HOST_WIDE_INT_1 << 33), \
+ (HOST_WIDE_INT_1 << 33) - 1)
+
+/* Like SIGNED_16BIT_OFFSET_P and SIGNED_34BIT_OFFSET_P, but with an extra
+ argument that gives a length to validate a range of addresses, to allow for
+ splitting insns into several insns, each of which has an offsettable
+ address. */
+#define SIGNED_16BIT_OFFSET_EXTRA_P(VALUE, EXTRA) \
+ IN_RANGE ((VALUE), \
-(HOST_WIDE_INT_1 << 15), \
(HOST_WIDE_INT_1 << 15) - 1 - (EXTRA))
-#define SIGNED_34BIT_OFFSET_P(VALUE, EXTRA) \
- IN_RANGE (VALUE, \
+#define SIGNED_34BIT_OFFSET_EXTRA_P(VALUE, EXTRA) \
+ IN_RANGE ((VALUE), \
-(HOST_WIDE_INT_1 << 33), \
(HOST_WIDE_INT_1 << 33) - 1 - (EXTRA))
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 503f91a..4ef1993 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -545,7 +545,6 @@
(define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
; FRE/FRES support
-(define_mode_attr Ffre [(SF "fres") (DF "fre")])
(define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
; Conditional returns.
@@ -9312,14 +9311,14 @@
(set_attr "update" "yes")
(set_attr "indexed" "yes,no")])
-(define_insn "*mov<mode>_update1"
- [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<Ff>,<Ff>")
+(define_insn "*mov<SFDF:mode>_update1"
+ [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
(mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
(match_operand:P 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:P 0 "gpc_reg_operand" "=b,b")
(plus:P (match_dup 1) (match_dup 2)))]
"TARGET_HARD_FLOAT && TARGET_UPDATE
- && (!avoiding_indexed_address_p (<MODE>mode)
+ && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
|| !gpc_reg_operand (operands[2], Pmode))"
"@
lf<sd>ux %3,%0,%2
@@ -9327,16 +9326,16 @@
[(set_attr "type" "fpload")
(set_attr "update" "yes")
(set_attr "indexed" "yes,no")
- (set_attr "size" "<bits>")])
+ (set_attr "size" "<SFDF:bits>")])
-(define_insn "*mov<mode>_update2"
+(define_insn "*mov<SFDF:mode>_update2"
[(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
(match_operand:P 2 "reg_or_short_operand" "r,I")))
- (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,<Ff>"))
+ (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
(set (match_operand:P 0 "gpc_reg_operand" "=b,b")
(plus:P (match_dup 1) (match_dup 2)))]
"TARGET_HARD_FLOAT && TARGET_UPDATE
- && (!avoiding_indexed_address_p (<MODE>mode)
+ && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
|| !gpc_reg_operand (operands[2], Pmode))"
"@
stf<sd>ux %3,%0,%2
@@ -9344,7 +9343,7 @@
[(set_attr "type" "fpstore")
(set_attr "update" "yes")
(set_attr "indexed" "yes,no")
- (set_attr "size" "<bits>")])
+ (set_attr "size" "<SFDF:bits>")])
(define_insn "*movsf_update3"
[(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
@@ -11558,7 +11557,7 @@
[(set_attr "type" "fpcompare")
(set_attr "length" "12")])
-(define_insn_and_split "*cmp<mode>_internal2"
+(define_insn_and_split "*cmp<IBM128:mode>_internal2"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
(match_operand:IBM128 2 "gpc_reg_operand" "d")))
@@ -11571,7 +11570,7 @@
(clobber (match_scratch:DF 9 "=d"))
(clobber (match_scratch:DF 10 "=d"))
(clobber (match_scratch:GPR 11 "=b"))]
- "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
+ "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
&& TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
@@ -11595,10 +11594,14 @@
const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
- operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
- operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
- operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
- operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
+ operands[5] = simplify_gen_subreg (DFmode, operands[1],
+ <IBM128:MODE>mode, hi_word);
+ operands[6] = simplify_gen_subreg (DFmode, operands[1],
+ <IBM128:MODE>mode, lo_word);
+ operands[7] = simplify_gen_subreg (DFmode, operands[2],
+ <IBM128:MODE>mode, hi_word);
+ operands[8] = simplify_gen_subreg (DFmode, operands[2],
+ <IBM128:MODE>mode, lo_word);
operands[12] = gen_label_rtx ();
operands[13] = gen_label_rtx ();
real_inf (&rv);
@@ -13597,7 +13600,7 @@
new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
operands[4] = add_op1;
- operands[5] = change_address (mem, <MODE>mode, new_addr);
+ operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
})
;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
@@ -13633,7 +13636,7 @@
new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
operands[4] = add_op1;
- operands[5] = change_address (mem, <MODE>mode, new_addr);
+ operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
})
@@ -14073,7 +14076,7 @@
(any_fix:QHSI
(match_operand:IEEE128 1 "altivec_register_operand" "v")))
(clobber (match_scratch:QHSI 2 "=v"))]
- "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
"#"
"&& reload_completed"
[(set (match_dup 2)
diff --git a/gcc/config/rs6000/smmintrin.h b/gcc/config/rs6000/smmintrin.h
index 914dade..5ef0822 100644
--- a/gcc/config/rs6000/smmintrin.h
+++ b/gcc/config/rs6000/smmintrin.h
@@ -66,4 +66,24 @@ _mm_extract_ps (__m128 __X, const int __N)
return ((__v4si)__X)[__N & 3];
}
+extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_blend_epi16 (__m128i __A, __m128i __B, const int __imm8)
+{
+ __v16qi __charmask = vec_splats ((signed char) __imm8);
+ __charmask = vec_gb (__charmask);
+ __v8hu __shortmask = (__v8hu) vec_unpackh (__charmask);
+ #ifdef __BIG_ENDIAN__
+ __shortmask = vec_reve (__shortmask);
+ #endif
+ return (__m128i) vec_sel ((__v8hu) __A, (__v8hu) __B, __shortmask);
+}
+
+extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_blendv_epi8 (__m128i __A, __m128i __B, __m128i __mask)
+{
+ const __v16qu __seven = vec_splats ((unsigned char) 0x07);
+ __v16qu __lmask = vec_sra ((__v16qu) __mask, __seven);
+ return (__m128i) vec_sel ((__v16qu) __A, (__v16qu) __B, __lmask);
+}
+
#endif
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 3861efd..17fea80 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -41,7 +41,7 @@
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc"
-#define TARGET_TOC (TARGET_64BIT \
+#define TARGET_HAS_TOC (TARGET_64BIT \
|| (TARGET_MINIMAL_TOC \
&& flag_pic > 1) \
|| DEFAULT_ABI != ABI_V4)
@@ -50,7 +50,6 @@
#define TARGET_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN)
#define TARGET_PROTOTYPE target_prototype
#define TARGET_NO_PROTOTYPE (! TARGET_PROTOTYPE)
-#define TARGET_NO_TOC (! TARGET_TOC)
#define TARGET_NO_EABI (! TARGET_EABI)
#define TARGET_REGNAMES rs6000_regnames
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index c689d51..59a1424 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -43,6 +43,10 @@ rs6000-logue.o: $(srcdir)/config/rs6000/rs6000-logue.c
$(COMPILE) $<
$(POSTCOMPILE)
+rs6000-call.o: $(srcdir)/config/rs6000/rs6000-call.c
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
$(srcdir)/config/rs6000/rs6000-tables.opt: $(srcdir)/config/rs6000/genopt.sh \
$(srcdir)/config/rs6000/rs6000-cpus.def
$(SHELL) $(srcdir)/config/rs6000/genopt.sh $(srcdir)/config/rs6000 > \
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index c33b45a..7633171 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -3828,7 +3828,7 @@
{
operands[4] = gen_rtx_REG (DImode, REGNO (operands[3]));
}
- [(set_attr "isa" "<VSisa>")])
+ [(set_attr "isa" "<FL_CONV:VSisa>")])
(define_insn_and_split "*vsx_ext_<VSX_EXTRACT_I:VS_scalar>_ufl_<FL_CONV:mode>"
[(set (match_operand:FL_CONV 0 "gpc_reg_operand" "=wa")
@@ -3851,7 +3851,7 @@
{
operands[4] = gen_rtx_REG (DImode, REGNO (operands[3]));
}
- [(set_attr "isa" "<VSisa>")])
+ [(set_attr "isa" "<FL_CONV:VSisa>")])
;; V4SI/V8HI/V16QI set operation on ISA 3.0
(define_insn "vsx_set_<mode>_p9"
diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index 4055cbc..45d41ae 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -204,6 +204,18 @@
(match_test "s390_decompose_addrstyle_without_index (op, NULL, NULL)" ))
+;; Shift count operands are not necessarily legitimate addresses
+;; but the predicate shift_count_operand will only allow
+;; proper operands. If reload/lra need to change e.g. a spilled register
+;; they can still do so via the special handling of address constraints.
+;; To avoid further reloading (caused by a non-matching constraint) we
+;; always return true here as the predicate's checks are already sufficient.
+
+(define_address_constraint "jsc"
+ "Address style operand used as shift count."
+ (match_test "true" ))
+
+
;; N -- Multiple letter constraint followed by 4 parameter letters.
;; 0..9,x: number of the part counting from most to least significant
;; S,H,Q: mode of the part
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 92c602e..4d2f8b2 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -556,3 +556,32 @@
{
return memory_operand (op, mode) && !contains_symbol_ref_p (op);
})
+
+;; Check for a valid shift count operand with an implicit
+;; shift truncation mask of 63.
+
+(define_predicate "shift_count_operand"
+ (and (match_code "reg, subreg, and, plus, const_int")
+ (match_test "CONST_INT_P (op) || GET_MODE (op) == E_QImode"))
+{
+ return s390_valid_shift_count (op, 63);
+}
+)
+
+;; This is used as operand predicate. As we do not know
+;; the mode of the first operand here and the shift truncation
+;; mask depends on the mode, we cannot check the mask.
+;; This is supposed to happen in the insn condition which
+;; calls s390_valid_shift_count with the proper mode size.
+;; We need two separate predicates for non-vector and vector
+;; shifts since the (less restrictive) insn condition is checked
+;; after the more restrictive operand predicate which will
+;; disallow the operand before we can check the condition.
+
+(define_predicate "shift_count_operand_vec"
+ (and (match_code "reg, subreg, and, plus, const_int")
+ (match_test "CONST_INT_P (op) || GET_MODE (op) == E_QImode"))
+{
+ return s390_valid_shift_count (op, 0);
+}
+)
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index b162b26..ae70b2f 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -141,6 +141,7 @@ extern void s390_emit_tpf_eh_return (rtx);
extern bool s390_legitimate_address_without_index_p (rtx);
extern bool s390_decompose_addrstyle_without_index (rtx, rtx *,
HOST_WIDE_INT *);
+extern bool s390_valid_shift_count (rtx op, HOST_WIDE_INT required_mask = 63);
extern int s390_branch_condition_mask (rtx);
extern int s390_compare_and_branch_condition_mask (rtx);
extern bool s390_extzv_shift_ok (int, int, unsigned HOST_WIDE_INT);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 5ec26a059..75b0b5b 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -3131,6 +3131,49 @@ s390_decompose_addrstyle_without_index (rtx op, rtx *base,
return true;
}
+/* Check that OP is a valid shift count operand.
+ It should be of the following structure:
+ (subreg (and (plus (reg imm_op)) 2^k-1) 7)
+ where subreg, and and plus are optional.
+
+ If IMPLICIT_MASK is > 0 and OP contains and
+ (AND ... immediate)
+ it is checked whether IMPLICIT_MASK and the immediate match.
+ Otherwise, no checking is performed.
+ */
+bool
+s390_valid_shift_count (rtx op, HOST_WIDE_INT implicit_mask)
+{
+ /* Strip subreg. */
+ while (GET_CODE (op) == SUBREG && subreg_lowpart_p (op))
+ op = XEXP (op, 0);
+
+ /* Check for an and with proper constant. */
+ if (GET_CODE (op) == AND)
+ {
+ rtx op1 = XEXP (op, 0);
+ rtx imm = XEXP (op, 1);
+
+ if (GET_CODE (op1) == SUBREG && subreg_lowpart_p (op1))
+ op1 = XEXP (op1, 0);
+
+ if (!(register_operand (op1, GET_MODE (op1)) || GET_CODE (op1) == PLUS))
+ return false;
+
+ if (!immediate_operand (imm, GET_MODE (imm)))
+ return false;
+
+ HOST_WIDE_INT val = INTVAL (imm);
+ if (implicit_mask > 0
+ && (val & implicit_mask) != implicit_mask)
+ return false;
+
+ op = op1;
+ }
+
+ /* Check the rest. */
+ return s390_decompose_addrstyle_without_index (op, NULL, NULL);
+}
/* Return true if CODE is a valid address without index. */
@@ -7448,6 +7491,27 @@ print_addrstyle_operand (FILE *file, rtx op)
fprintf (file, "(%s)", reg_names[REGNO (base)]);
}
+/* Print the shift count operand OP to FILE.
+ OP is an address-style operand in a form which
+ s390_valid_shift_count permits. Subregs and no-op
+ and-masking of the operand are stripped. */
+
+static void
+print_shift_count_operand (FILE *file, rtx op)
+{
+ /* No checking of the and mask required here. */
+ if (!s390_valid_shift_count (op, 0))
+ gcc_unreachable ();
+
+ while (op && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ if (GET_CODE (op) == AND)
+ op = XEXP (op, 0);
+
+ print_addrstyle_operand (file, op);
+}
+
/* Assigns the number of NOP halfwords to be emitted before and after the
function label to *HW_BEFORE and *HW_AFTER. Both pointers must not be NULL.
If hotpatching is disabled for the function, the values are set to zero.
@@ -7912,7 +7976,7 @@ print_operand (FILE *file, rtx x, int code)
break;
case 'Y':
- print_addrstyle_operand (file, x);
+ print_shift_count_operand (file, x);
return;
}
@@ -16348,7 +16412,13 @@ s390_sched_dependencies_evaluation (rtx_insn *head, rtx_insn *tail)
add_dependence (r11_restore, r15_restore, REG_DEP_ANTI);
}
+/* Implement TARGET_SHIFT_TRUNCATION_MASK for integer shifts. */
+static unsigned HOST_WIDE_INT
+s390_shift_truncation_mask (machine_mode mode)
+{
+ return mode == DImode || mode == SImode ? 63 : 0;
+}
/* Initialize GCC target structure. */
@@ -16645,6 +16715,8 @@ s390_sched_dependencies_evaluation (rtx_insn *head, rtx_insn *tail)
#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \
s390_sched_dependencies_evaluation
+#undef TARGET_SHIFT_TRUNCATION_MASK
+#define TARGET_SHIFT_TRUNCATION_MASK s390_shift_truncation_mask
/* Use only short displacement, since long displacement is not available for
the floating point instructions. */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index d06aea9..94a7340 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8821,8 +8821,8 @@
; lndfr
(define_insn "*negabs<mode>2_nocc"
- [(set (match_operand:FP 0 "register_operand" "=f")
- (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
+ [(set (match_operand:FP 0 "register_operand" "=f")
+ (neg:FP (abs:FP (match_operand:FP 1 "register_operand" "<fT0>"))))]
"TARGET_DFP"
"lndfr\t%0,%1"
[(set_attr "op_type" "RRE")
@@ -8937,17 +8937,17 @@
(define_expand "rotl<mode>3"
[(set (match_operand:GPR 0 "register_operand" "")
(rotate:GPR (match_operand:GPR 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:QI 2 "shift_count_operand" "")))]
""
"")
; rll, rllg
-(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
+(define_insn "*rotl<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
- (match_operand:SI 2 "nonmemory_operand" "an")))]
+ (match_operand:QI 2 "shift_count_operand" "jsc")))]
""
- "rll<g>\t%0,%1,<addr_style_op_ops>"
+ "rll<g>\t%0,%1,%Y2"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")
(set_attr "z10prop" "z10_super_E1")])
@@ -8964,18 +8964,18 @@
(define_expand "<shift><mode>3"
[(set (match_operand:DSI 0 "register_operand" "")
(SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:QI 2 "shift_count_operand" "")))]
""
"")
; ESA 64 bit register pair shift with reg or imm shift count
; sldl, srdl
-(define_insn "*<shift>di3_31<addr_style_op><masked_op>"
+(define_insn "*<shift>di3_31"
[(set (match_operand:DI 0 "register_operand" "=d")
(SHIFT:DI (match_operand:DI 1 "register_operand" "0")
- (match_operand:SI 2 "nonmemory_operand" "an")))]
+ (match_operand:QI 2 "shift_count_operand" "jsc")))]
"!TARGET_ZARCH"
- "s<lr>dl\t%0,<addr_style_op_ops>"
+ "s<lr>dl\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")
(set_attr "z196prop" "z196_cracked")])
@@ -8983,19 +8983,20 @@
; 64 bit register shift with reg or imm shift count
; sll, srl, sllg, srlg, sllk, srlk
-(define_insn "*<shift><mode>3<addr_style_op><masked_op>"
+(define_insn "*<shift><mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d, d")
(SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
- (match_operand:SI 2 "nonmemory_operand" "an,an")))]
+ (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))]
""
"@
- s<lr>l<g>\t%0,<1><addr_style_op_ops>
- s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
+ s<lr>l<g>\t%0,<1>%Y2
+ s<lr>l<gk>\t%0,%1,%Y2"
[(set_attr "op_type" "RS<E>,RSY")
(set_attr "atype" "reg,reg")
(set_attr "cpu_facility" "*,z196")
(set_attr "z10prop" "z10_super_E1,*")])
+
;
; ashr(di|si)3 instruction pattern(s).
; Arithmetic right shifts
@@ -9004,7 +9005,7 @@
[(parallel
[(set (match_operand:DSI 0 "register_operand" "")
(ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))
+ (match_operand:QI 2 "shift_count_operand" "")))
(clobber (reg:CC CC_REGNUM))])]
""
"")
@@ -9013,29 +9014,29 @@
; number of 2 in the subst pattern for the (clobber (match_scratch...
; The right fix should be to support match_scratch in the output
; pattern of a define_subst.
-(define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
+(define_insn "*ashrdi3_31<setcc><cconly>"
[(set (match_operand:DI 0 "register_operand" "=d, d")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
- (match_operand:SI 2 "nonmemory_operand" "an,an")))
+ (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
(clobber (reg:CC CC_REGNUM))]
"!TARGET_ZARCH"
"@
- srda\t%0,<addr_style_op_cc_ops>
- srda\t%0,<addr_style_op_cc_ops>"
+ srda\t%0,%Y2
+ srda\t%0,%Y2"
[(set_attr "op_type" "RS")
(set_attr "atype" "reg")])
; sra, srag
-(define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
+(define_insn "*ashr<mode>3<setcc><cconly>"
[(set (match_operand:GPR 0 "register_operand" "=d, d")
(ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
- (match_operand:SI 2 "nonmemory_operand" "an,an")))
+ (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
(clobber (reg:CC CC_REGNUM))]
""
"@
- sra<g>\t%0,<1><addr_style_op_cc_ops>
- sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
+ sra<g>\t%0,<1>%Y2
+ sra<gk>\t%0,%1,%Y2"
[(set_attr "op_type" "RS<E>,RSY")
(set_attr "atype" "reg")
(set_attr "cpu_facility" "*,z196")
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
index 0518ed2..9c0c87a 100644
--- a/gcc/config/s390/subst.md
+++ b/gcc/config/s390/subst.md
@@ -22,78 +22,6 @@
(define_code_iterator SUBST [rotate ashift lshiftrt ashiftrt])
(define_mode_iterator DSI_VI [SI DI V2QI V4QI V8QI V16QI V2HI V4HI V8HI V2SI V4SI V2DI])
-; This expands an register/immediate operand to a register+immediate
-; operand to draw advantage of the address style operand format
-; providing a addition for free.
-(define_subst "addr_style_op_subst"
- [(set (match_operand:DSI_VI 0 "" "")
- (SUBST:DSI_VI (match_operand:DSI_VI 1 "" "")
- (match_operand:SI 2 "" "")))]
- ""
- [(set (match_dup 0)
- (SUBST:DSI_VI (match_dup 1)
- (plus:SI (match_operand:SI 2 "register_operand" "a")
- (match_operand 3 "const_int_operand" "n"))))])
-
-; Use this in the insn name.
-(define_subst_attr "addr_style_op" "addr_style_op_subst" "" "_plus")
-
-; In the subst pattern the additional const int operand will be used
-; as displacement. In the normal version %Y is able to print the
-; operand either as displacement or as base register.
-(define_subst_attr "addr_style_op_ops" "addr_style_op_subst" "%Y2" "%Y3(%2)")
-
-
-; This substitution adds an explicit AND operation to the second
-; operand. This way previous operations on the now masked out bits
-; might get optimized away.
-(define_subst "masked_op_subst"
- [(set (match_operand:DSI 0 "" "")
- (SUBST:DSI (match_operand:DSI 1 "" "")
- (match_operand:SI 2 "" "")))]
- ""
- [(set (match_dup 0)
- (SUBST:DSI (match_dup 1)
- (and:SI (match_dup 2)
- (match_operand:SI 3 "const_int_6bitset_operand" "jm6"))))])
-
-; Use this in the insn name.
-(define_subst_attr "masked_op" "masked_op_subst" "" "_and")
-
-
-
-; This is like the addr_style_op substitution above but with a CC clobber.
-(define_subst "addr_style_op_cc_subst"
- [(set (match_operand:DSI 0 "" "")
- (ashiftrt:DSI (match_operand:DSI 1 "" "")
- (match_operand:SI 2 "" "")))
- (clobber (reg:CC CC_REGNUM))]
- "REG_P (operands[2])"
- [(set (match_dup 0)
- (ashiftrt:DSI (match_dup 1)
- (plus:SI (match_dup 2)
- (match_operand 3 "const_int_operand" "n"))))
- (clobber (reg:CC CC_REGNUM))])
-
-(define_subst_attr "addr_style_op_cc" "addr_style_op_cc_subst" "" "_plus")
-(define_subst_attr "addr_style_op_cc_ops" "addr_style_op_cc_subst" "%Y2" "%Y3(%2)")
-
-
-; This is like the masked_op substitution but with a CC clobber.
-(define_subst "masked_op_cc_subst"
- [(set (match_operand:DSI 0 "" "")
- (ashiftrt:DSI (match_operand:DSI 1 "" "")
- (match_operand:SI 2 "" "")))
- (clobber (reg:CC CC_REGNUM))]
- ""
- [(set (match_dup 0)
- (ashiftrt:DSI (match_dup 1)
- (and:SI (match_dup 2)
- (match_operand:SI 3 "const_int_6bitset_operand" ""))))
- (clobber (reg:CC CC_REGNUM))])
-(define_subst_attr "masked_op_cc" "masked_op_cc_subst" "" "_and")
-
-
; This adds an explicit CC reg set to an operation while keeping the
; set for the operation result as well.
(define_subst "setcc_subst"
diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md
index 140ef47..0702e1d 100644
--- a/gcc/config/s390/vector.md
+++ b/gcc/config/s390/vector.md
@@ -969,21 +969,25 @@
(define_expand "<vec_shifts_name><mode>3"
[(set (match_operand:VI 0 "register_operand" "")
(VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:QI 2 "shift_count_operand" "")))]
"TARGET_VX")
; verllb, verllh, verllf, verllg
; veslb, veslh, veslf, veslg
; vesrab, vesrah, vesraf, vesrag
; vesrlb, vesrlh, vesrlf, vesrlg
-(define_insn "*<vec_shifts_name><mode>3<addr_style_op>"
+(define_insn "*<vec_shifts_name><mode>3"
[(set (match_operand:VI 0 "register_operand" "=v")
(VEC_SHIFTS:VI (match_operand:VI 1 "register_operand" "v")
- (match_operand:SI 2 "nonmemory_operand" "an")))]
- "TARGET_VX"
- "<vec_shifts_mnem><bhfgq>\t%v0,%v1,<addr_style_op_ops>"
+ (match_operand:QI 2 "shift_count_operand_vec" "jsc")))]
+ "TARGET_VX
+ && s390_valid_shift_count (operands[2],
+ GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) - 1)
+ "
+ "<vec_shifts_mnem><bhfgq>\t%v0,%v1,%Y2"
[(set_attr "op_type" "VRS")])
+
; Shift each element by corresponding vector element
; veslvb, veslvh, veslvf, veslvg
diff --git a/gcc/config/s390/vx-builtins.md b/gcc/config/s390/vx-builtins.md
index 3020bc9..c71aae0 100644
--- a/gcc/config/s390/vx-builtins.md
+++ b/gcc/config/s390/vx-builtins.md
@@ -2046,7 +2046,7 @@
;;
; vfcesbs, vfcedbs, wfcexbs, vfchsbs, vfchdbs, wfchxbs, vfchesbs, vfchedbs, wfchexbs
-(define_insn "*vec_cmp<insn_cmp><mode>_cconly"
+(define_insn "*vec_cmp<insn_cmp><VF_HW:mode>_cconly"
[(set (reg:VFCMP CC_REGNUM)
(compare:VFCMP (match_operand:VF_HW 0 "register_operand" "v")
(match_operand:VF_HW 1 "register_operand" "v")))
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 2f6b859..eac2f39 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -47,9 +47,9 @@ typedef int64_t gcov_type;
typedef uint64_t gcov_type_unsigned;
struct bitmap_obstack;
-struct bitmap_head;
-typedef struct bitmap_head *bitmap;
-typedef const struct bitmap_head *const_bitmap;
+class bitmap_head;
+typedef class bitmap_head *bitmap;
+typedef const class bitmap_head *const_bitmap;
struct simple_bitmap_def;
typedef struct simple_bitmap_def *sbitmap;
typedef const struct simple_bitmap_def *const_sbitmap;
@@ -65,7 +65,7 @@ template<typename> class opt_mode;
typedef opt_mode<scalar_mode> opt_scalar_mode;
typedef opt_mode<scalar_int_mode> opt_scalar_int_mode;
typedef opt_mode<scalar_float_mode> opt_scalar_float_mode;
-template<typename> class pod_mode;
+template<typename> struct pod_mode;
typedef pod_mode<scalar_mode> scalar_mode_pod;
typedef pod_mode<scalar_int_mode> scalar_int_mode_pod;
typedef pod_mode<fixed_size_mode> fixed_size_mode_pod;
@@ -73,19 +73,19 @@ typedef pod_mode<fixed_size_mode> fixed_size_mode_pod;
/* Subclasses of rtx_def, using indentation to show the class
hierarchy, along with the relevant invariant.
Where possible, keep this list in the same order as in rtl.def. */
-class rtx_def;
- class rtx_expr_list; /* GET_CODE (X) == EXPR_LIST */
- class rtx_insn_list; /* GET_CODE (X) == INSN_LIST */
- class rtx_sequence; /* GET_CODE (X) == SEQUENCE */
- class rtx_insn;
- class rtx_debug_insn; /* DEBUG_INSN_P (X) */
- class rtx_nonjump_insn; /* NONJUMP_INSN_P (X) */
- class rtx_jump_insn; /* JUMP_P (X) */
- class rtx_call_insn; /* CALL_P (X) */
- class rtx_jump_table_data; /* JUMP_TABLE_DATA_P (X) */
- class rtx_barrier; /* BARRIER_P (X) */
- class rtx_code_label; /* LABEL_P (X) */
- class rtx_note; /* NOTE_P (X) */
+struct rtx_def;
+ struct rtx_expr_list; /* GET_CODE (X) == EXPR_LIST */
+ struct rtx_insn_list; /* GET_CODE (X) == INSN_LIST */
+ struct rtx_sequence; /* GET_CODE (X) == SEQUENCE */
+ struct rtx_insn;
+ struct rtx_debug_insn; /* DEBUG_INSN_P (X) */
+ struct rtx_nonjump_insn; /* NONJUMP_INSN_P (X) */
+ struct rtx_jump_insn; /* JUMP_P (X) */
+ struct rtx_call_insn; /* CALL_P (X) */
+ struct rtx_jump_table_data; /* JUMP_TABLE_DATA_P (X) */
+ struct rtx_barrier; /* BARRIER_P (X) */
+ struct rtx_code_label; /* LABEL_P (X) */
+ struct rtx_note; /* NOTE_P (X) */
struct rtvec_def;
typedef struct rtvec_def *rtvec;
@@ -138,9 +138,9 @@ struct gomp_teams;
/* Subclasses of symtab_node, using indentation to show the class
hierarchy. */
-class symtab_node;
+struct symtab_node;
struct cgraph_node;
- class varpool_node;
+ struct varpool_node;
union section;
typedef union section section;
@@ -151,7 +151,7 @@ struct cl_option;
struct cl_decoded_option;
struct cl_option_handlers;
struct diagnostic_context;
-struct pretty_printer;
+class pretty_printer;
/* Address space number for named address space support. */
typedef unsigned char addr_space_t;
@@ -298,9 +298,9 @@ enum warn_strict_overflow_code
set yet). */
typedef int alias_set_type;
-struct edge_def;
-typedef struct edge_def *edge;
-typedef const struct edge_def *const_edge;
+class edge_def;
+typedef class edge_def *edge;
+typedef const class edge_def *const_edge;
struct basic_block_def;
typedef struct basic_block_def *basic_block;
typedef const struct basic_block_def *const_basic_block;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7031d8d..d645cde 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,142 @@
+2019-07-20 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (ovl_iterator::using_p): A USING_DECL by itself was also
+ introduced by a using-declaration.
+
+2019-07-20 Jason Merrill <jason@redhat.com>
+
+ Reduce memory consumption for push/pop_access_scope.
+ * name-lookup.c (leave_scope): Do add class levels other than
+ previous_class_level to free_binding_level.
+ (invalidate_class_lookup_cache): Move from class.c, add to
+ free_binding_level.
+ * pt.c (saved_access_scope): Change from list to vec.
+
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (OMP_FOR_GIMPLIFYING_P): Use OMP_LOOPING_CHECK
+ instead of OMP_LOOP_CHECK.
+ * parser.c (cp_parser_omp_clause_name): Handle bind clause.
+ (cp_parser_omp_clause_bind): New function.
+ (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_BIND.
+ (OMP_LOOP_CLAUSE_MASK): Define.
+ (cp_parser_omp_loop): New function.
+ (cp_parser_omp_parallel, cp_parser_omp_teams): Handle parsing of
+ loop combined with parallel or teams.
+ (cp_parser_omp_construct): Handle PRAGMA_OMP_LOOP.
+ (cp_parser_pragma): Likewise.
+ * pt.c (tsubst_expr): Handle OMP_LOOP.
+ * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_BIND.
+
+2019-07-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/90101 - dependent class non-type parameter.
+ * pt.c (invalid_nontype_parm_type_p): Check for dependent class type.
+
+2019-07-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/90098 - partial specialization and class non-type parms.
+ PR c++/90099
+ PR c++/90101
+ * call.c (build_converted_constant_expr_internal): Don't copy.
+ * pt.c (process_partial_specialization): Allow VIEW_CONVERT_EXPR
+ around class non-type parameter.
+ (unify) [TEMPLATE_PARM_INDEX]: Ignore cv-quals.
+
+2019-07-16 Jason Merrill <jason@redhat.com>
+
+ * parser.c (make_location): Add overload taking cp_lexer* as last
+ parameter.
+
+ * parser.c (cp_parser_simple_type_specifier): Separate tentative
+ parses for optional type-spec and CTAD.
+
+ * parser.c (cp_parser_nested_name_specifier_opt): If the token is
+ already CPP_NESTED_NAME_SPECIFIER, leave it alone.
+
+2019-07-12 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_clause_name): Handle order clause.
+ (cp_parser_omp_clause_order): New function.
+ (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_ORDER.
+ (OMP_SIMD_CLAUSE_MASK, OMP_FOR_CLAUSE_MASK): Add
+ PRAGMA_OMP_CLAUSE_ORDER.
+ * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_ORDER.
+ * pt.c (tsubst_omp_clauses): Likewise.
+
+2019-07-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (get_type_quals,
+ smallest_type_location (const cp_decl_specifier_seq*)): New.
+ (check_tag_decl): Use smallest_type_location in error_at about
+ multiple types in one declaration.
+ (grokdeclarator): Use locations[ds_complex] in error_at about
+ complex invalid; use locations[ds_storage_class] in error_at
+ about static cdtor; use id_loc in error_at about flexible
+ array member in union; use get_type_quals.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * cp-tree.h: Change class-key of PODs to struct and others to class.
+ * search.c: Same.
+ * semantics.c (finalize_nrv_r): Same.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * constexpr.c (cxx_eval_call_expression): Change class-key from class
+ to struct and vice versa to match convention and avoid -Wclass-is-pod
+ and -Wstruct-no-pod.
+ * constraint.cc (get_concept_definition): Same.
+ * cp-tree.h: Same.
+ * cxx-pretty-print.h: Same.
+ * error.c: Same.
+ * logic.cc (term_list::replace): Same.
+ * name-lookup.c (find_local_binding): Same.
+ * pt.c (tsubst_binary_right_fold): Same.
+ * search.c (field_accessor_p): Same.
+ * semantics.c (expand_or_defer_fn): Same.
+
+2019-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/91110
+ * decl2.c (cp_omp_mappable_type_1): Don't emit any note for
+ error_mark_node type.
+
+2019-07-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/67184
+ PR c++/69445
+ * call.c (build_new_method_call_1): Remove set but not used variable
+ binfo.
+
+2019-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/67184 (again)
+ PR c++/69445
+ * call.c (build_over_call): Devirtualize user-defined operators
+ coming from a base too.
+ (build_new_method_call_1): Do not devirtualize here.
+
+2019-07-04 Marek Polacek <polacek@redhat.com>
+
+ DR 1813
+ PR c++/83374 - __is_standard_layout wrong for a class with repeated
+ bases.
+ * class.c (check_bases): Set CLASSTYPE_NON_STD_LAYOUT for a class if
+ CLASSTYPE_REPEATED_BASE_P is true.
+
+2019-07-04 Andrew Stubbs <ams@codesourcery.com>
+
+ * cp-tree.h (cp_omp_emit_unmappable_type_notes): New prototype.
+ * decl.c (cp_finish_decl): Call cp_omp_emit_unmappable_type_notes.
+ * decl2.c (cp_omp_mappable_type): Move contents to ...
+ (cp_omp_mappable_type_1): ... here and add note output.
+ (cp_omp_emit_unmappable_type_notes): New function.
+ * semantics.c (finish_omp_clauses): Call
+ cp_omp_emit_unmappable_type_notes in four places.
+
2019-07-03 Martin Liska <mliska@suse.cz>
* call.c (build_new_op_1): Remove
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 0709325..38d229b 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4278,6 +4278,11 @@ build_converted_constant_expr_internal (tree type, tree expr,
if (conv)
{
+ /* Don't copy a class in a template. */
+ if (CLASS_TYPE_P (type) && conv->kind == ck_rvalue
+ && processing_template_decl)
+ conv = next_conversion (conv);
+
conv->check_narrowing = true;
conv->check_narrowing_const_only = true;
expr = convert_like (conv, expr, complain);
@@ -8241,10 +8246,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
return error_mark_node;
}
- /* See if the function member or the whole class type is declared
- final and the call can be devirtualized. */
+ /* Optimize away vtable lookup if we know that this
+ function can't be overridden. We need to check if
+ the context and the type where we found fn are the same,
+ actually FN might be defined in a different class
+ type because of a using-declaration. In this case, we
+ do not want to perform a non-virtual call. Note that
+ resolves_to_fixed_type_p checks CLASSTYPE_FINAL too. */
if (DECL_FINAL_P (fn)
- || CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn))))
+ || (resolves_to_fixed_type_p (arg, 0)
+ && same_type_ignoring_top_level_qualifiers_p
+ (DECL_CONTEXT (fn), BINFO_TYPE (cand->conversion_path))))
flags |= LOOKUP_NONVIRTUAL;
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
@@ -9557,7 +9569,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
struct z_candidate *candidates = 0, *cand;
tree explicit_targs = NULL_TREE;
tree basetype = NULL_TREE;
- tree access_binfo, binfo;
+ tree access_binfo;
tree optype;
tree first_mem_arg = NULL_TREE;
tree name;
@@ -9596,7 +9608,6 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (!conversion_path)
conversion_path = BASELINK_BINFO (fns);
access_binfo = BASELINK_ACCESS_BINFO (fns);
- binfo = BASELINK_BINFO (fns);
optype = BASELINK_OPTYPE (fns);
fns = BASELINK_FUNCTIONS (fns);
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
@@ -9845,17 +9856,6 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (call != error_mark_node)
{
- /* Optimize away vtable lookup if we know that this
- function can't be overridden. We need to check if
- the context and the type where we found fn are the same,
- actually FN might be defined in a different class
- type because of a using-declaration. In this case, we
- do not want to perform a non-virtual call. */
- if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL)
- && same_type_ignoring_top_level_qualifiers_p
- (DECL_CONTEXT (fn), BINFO_TYPE (binfo))
- && resolves_to_fixed_type_p (instance, 0))
- flags |= LOOKUP_NONVIRTUAL;
if (explicit_targs)
flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
/* Now we know what function is being called. */
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 73291b3..b61152c 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1715,11 +1715,15 @@ check_bases (tree t,
&& (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (field), basetype)))
CLASSTYPE_NON_STD_LAYOUT (t) = 1;
+ /* DR 1813:
+ ...has at most one base class subobject of any given type... */
+ else if (CLASSTYPE_REPEATED_BASE_P (t))
+ CLASSTYPE_NON_STD_LAYOUT (t) = 1;
else
/* ...either has no non-static data members in the most-derived
class and at most one base class with non-static data
members, or has no base classes with non-static data
- members */
+ members. FIXME This was reworded in DR 1813. */
for (basefield = TYPE_FIELDS (basetype); basefield;
basefield = DECL_CHAIN (basefield))
if (TREE_CODE (basefield) == FIELD_DECL
@@ -7584,16 +7588,6 @@ pushclass (tree type)
restore_class_cache ();
}
-/* When we exit a toplevel class scope, we save its binding level so
- that we can restore it quickly. Here, we've entered some other
- class, so we must invalidate our cache. */
-
-void
-invalidate_class_lookup_cache (void)
-{
- previous_class_level = NULL;
-}
-
/* Get out of the current class scope. If we were in a class scope
previously, that is the one popped to. */
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index d11e7af..c1b8b9b 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1753,8 +1753,9 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
/* We build up the bindings list before we know whether we already have this
call cached. If we don't end up saving these bindings, ggc_free them when
this function exits. */
- struct free_bindings
+ class free_bindings
{
+ public:
tree &bindings;
bool do_free;
free_bindings (tree &b): bindings (b), do_free(true) { }
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index ed39ecc..cc578bb 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -517,8 +517,9 @@ get_concept_definition (tree decl)
int expansion_level = 0;
-struct expanding_concept_sentinel
+class expanding_concept_sentinel
{
+public:
expanding_concept_sentinel ()
{
++expansion_level;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a1849f6..688924c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -774,7 +774,8 @@ class ovl_iterator
/* Whether this overload was introduced by a using decl. */
bool using_p () const
{
- return TREE_CODE (ovl) == OVERLOAD && OVL_USING_P (ovl);
+ return (TREE_CODE (ovl) == USING_DECL
+ || (TREE_CODE (ovl) == OVERLOAD && OVL_USING_P (ovl)));
}
bool hidden_p () const
{
@@ -873,8 +874,9 @@ struct named_decl_hash : ggc_remove <tree>
/* Simplified unique_ptr clone to release a tree vec on exit. */
-struct releasing_vec
+class releasing_vec
{
+public:
typedef vec<tree, va_gc> vec_t;
releasing_vec (vec_t *v): v(v) { }
@@ -1728,8 +1730,9 @@ extern GTY(()) struct saved_scope *scope_chain;
/* RAII sentinel to handle clearing processing_template_decl and restoring
it when done. */
-struct processing_template_decl_sentinel
+class processing_template_decl_sentinel
{
+public:
int saved;
processing_template_decl_sentinel (bool reset = true)
: saved (processing_template_decl)
@@ -1746,8 +1749,9 @@ struct processing_template_decl_sentinel
/* RAII sentinel to disable certain warnings during template substitution
and elsewhere. */
-struct warning_sentinel
+class warning_sentinel
{
+public:
int &flag;
int val;
warning_sentinel(int& flag, bool suppress=true)
@@ -4920,7 +4924,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
/* Used while gimplifying continue statements bound to OMP_FOR nodes. */
#define OMP_FOR_GIMPLIFYING_P(NODE) \
- (TREE_LANG_FLAG_0 (OMP_LOOP_CHECK (NODE)))
+ (TREE_LANG_FLAG_0 (OMP_LOOPING_CHECK (NODE)))
/* A language-specific token attached to the OpenMP data clauses to
hold code (or code fragments) related to ctors, dtors, and op=.
@@ -5267,8 +5271,9 @@ extern int cp_unevaluated_operand;
/* RAII class used to inhibit the evaluation of operands during parsing
and template instantiation. Evaluation warnings are also inhibited. */
-struct cp_unevaluated
+class cp_unevaluated
{
+public:
cp_unevaluated ();
~cp_unevaluated ();
};
@@ -5276,8 +5281,9 @@ struct cp_unevaluated
/* The reverse: an RAII class used for nested contexts that are evaluated even
if the enclosing context is not. */
-struct cp_evaluated
+class cp_evaluated
{
+public:
int uneval;
int inhibit;
cp_evaluated ()
@@ -5304,8 +5310,9 @@ enum unification_kind_t {
// specializations. When the stack goes out of scope, the
// previous pointer map is restored.
enum lss_policy { lss_blank, lss_copy };
-struct local_specialization_stack
+class local_specialization_stack
{
+public:
local_specialization_stack (lss_policy = lss_blank);
~local_specialization_stack ();
@@ -6536,6 +6543,7 @@ extern int parm_index (tree);
extern tree vtv_start_verification_constructor_init_function (void);
extern tree vtv_finish_verification_constructor_init_function (tree);
extern bool cp_omp_mappable_type (tree);
+extern bool cp_omp_emit_unmappable_type_notes (tree);
extern void cp_check_const_attributes (tree);
/* in error.c */
@@ -6972,8 +6980,9 @@ extern bool perform_or_defer_access_check (tree, tree, tree,
/* RAII sentinel to ensures that deferred access checks are popped before
a function returns. */
-struct deferring_access_check_sentinel
+class deferring_access_check_sentinel
{
+public:
deferring_access_check_sentinel (enum deferring_kind kind = dk_deferred)
{
push_deferring_access_checks (kind);
diff --git a/gcc/cp/cxx-pretty-print.h b/gcc/cp/cxx-pretty-print.h
index aba3e84..347811f 100644
--- a/gcc/cp/cxx-pretty-print.h
+++ b/gcc/cp/cxx-pretty-print.h
@@ -29,8 +29,9 @@ enum cxx_pretty_printer_flags
pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
};
-struct cxx_pretty_printer : c_pretty_printer
+class cxx_pretty_printer : public c_pretty_printer
{
+public:
cxx_pretty_printer ();
void constant (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index bb9d19a..dbcf681 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -100,6 +100,7 @@ static tree build_cp_library_fn (tree, enum tree_code, tree, int);
static void store_parm_decls (tree);
static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree);
+static location_t smallest_type_location (const cp_decl_specifier_seq*);
/* The following symbols are subsumed in the cp_global_trees array, and
listed here individually for documentation purposes.
@@ -4802,6 +4803,24 @@ warn_misplaced_attr_for_class_type (location_t location,
class_type, class_key_or_enum_as_string (class_type));
}
+/* Returns the cv-qualifiers that apply to the type specified
+ by the DECLSPECS. */
+
+static int
+get_type_quals (const cp_decl_specifier_seq *declspecs)
+{
+ int type_quals = TYPE_UNQUALIFIED;
+
+ if (decl_spec_seq_has_spec_p (declspecs, ds_const))
+ type_quals |= TYPE_QUAL_CONST;
+ if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
+ type_quals |= TYPE_QUAL_VOLATILE;
+ if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
+ type_quals |= TYPE_QUAL_RESTRICT;
+
+ return type_quals;
+}
+
/* Make sure that a declaration with no declarator is well-formed, i.e.
just declares a tagged type or anonymous union.
@@ -4821,7 +4840,8 @@ check_tag_decl (cp_decl_specifier_seq *declspecs,
bool error_p = false;
if (declspecs->multiple_types_p)
- error ("multiple types in one declaration");
+ error_at (smallest_type_location (declspecs),
+ "multiple types in one declaration");
else if (declspecs->redefined_builtin_type)
{
if (!in_system_header_at (input_location))
@@ -7433,8 +7453,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
DECL_ATTRIBUTES (decl));
complete_type (TREE_TYPE (decl));
if (!cp_omp_mappable_type (TREE_TYPE (decl)))
- error ("%q+D in declare target directive does not have mappable type",
- decl);
+ {
+ error ("%q+D in declare target directive does not have mappable"
+ " type", decl);
+ cp_omp_emit_unmappable_type_notes (TREE_TYPE (decl));
+ }
else if (!lookup_attribute ("omp declare target",
DECL_ATTRIBUTES (decl))
&& !lookup_attribute ("omp declare target link",
@@ -10139,6 +10162,13 @@ smallest_type_location (int type_quals, const location_t* locations)
return min_location (loc, locations[ds_type_spec]);
}
+static location_t
+smallest_type_location (const cp_decl_specifier_seq *declspecs)
+{
+ int type_quals = get_type_quals (declspecs);
+ return smallest_type_location (type_quals, declspecs->locations);
+}
+
/* Check that it's OK to declare a function with the indicated TYPE
and TYPE_QUALS. SFK indicates the kind of special function (if any)
that this function is. OPTYPE is the type given in a conversion
@@ -10404,7 +10434,7 @@ grokdeclarator (const cp_declarator *declarator,
a member function. */
cp_ref_qualifier rqual = REF_QUAL_NONE;
/* cv-qualifiers that apply to the type specified by the DECLSPECS. */
- int type_quals = TYPE_UNQUALIFIED;
+ int type_quals = get_type_quals (declspecs);
tree raises = NULL_TREE;
int template_count = 0;
tree returned_attrs = NULL_TREE;
@@ -10451,13 +10481,6 @@ grokdeclarator (const cp_declarator *declarator,
if (concept_p)
constexpr_p = true;
- if (decl_spec_seq_has_spec_p (declspecs, ds_const))
- type_quals |= TYPE_QUAL_CONST;
- if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
- type_quals |= TYPE_QUAL_VOLATILE;
- if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
- type_quals |= TYPE_QUAL_RESTRICT;
-
if (decl_context == FUNCDEF)
funcdef_flag = true, decl_context = NORMAL;
else if (decl_context == MEMFUNCDEF)
@@ -10996,7 +11019,8 @@ grokdeclarator (const cp_declarator *declarator,
if (decl_spec_seq_has_spec_p (declspecs, ds_complex))
{
if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
- error ("complex invalid for %qs", name);
+ error_at (declspecs->locations[ds_complex],
+ "complex invalid for %qs", name);
/* If a modifier is specified, the resulting complex is the complex
form of TYPE. E.g, "complex short" is "complex short int". */
else if (type == integer_type_node)
@@ -11575,9 +11599,12 @@ grokdeclarator (const cp_declarator *declarator,
virtual. A constructor may not be static.
A constructor may not be declared with ref-qualifier. */
if (staticp == 2)
- error ((flags == DTOR_FLAG)
- ? G_("destructor cannot be static member function")
- : G_("constructor cannot be static member function"));
+ error_at (declspecs->locations[ds_storage_class],
+ (flags == DTOR_FLAG)
+ ? G_("destructor cannot be static member "
+ "function")
+ : G_("constructor cannot be static member "
+ "function"));
if (memfn_quals)
{
error ((flags == DTOR_FLAG)
@@ -12435,7 +12462,7 @@ grokdeclarator (const cp_declarator *declarator,
&& (TREE_CODE (ctype) == UNION_TYPE
|| TREE_CODE (ctype) == QUAL_UNION_TYPE))
{
- error ("flexible array member in union");
+ error_at (id_loc, "flexible array member in union");
type = error_mark_node;
}
else
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 206f04c..3aba194 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1406,32 +1406,68 @@ cp_check_const_attributes (tree attributes)
}
}
-/* Return true if TYPE is an OpenMP mappable type. */
-bool
-cp_omp_mappable_type (tree type)
+/* Return true if TYPE is an OpenMP mappable type.
+ If NOTES is non-zero, emit a note message for each problem. */
+static bool
+cp_omp_mappable_type_1 (tree type, bool notes)
{
+ bool result = true;
+
/* Mappable type has to be complete. */
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
- return false;
+ {
+ if (notes && type != error_mark_node)
+ {
+ tree decl = TYPE_MAIN_DECL (type);
+ inform ((decl ? DECL_SOURCE_LOCATION (decl) : input_location),
+ "incomplete type %qT is not mappable", type);
+ }
+ result = false;
+ }
/* Arrays have mappable type if the elements have mappable type. */
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
/* A mappable type cannot contain virtual members. */
if (CLASS_TYPE_P (type) && CLASSTYPE_VTABLES (type))
- return false;
+ {
+ if (notes)
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+ "type %qT with virtual members is not mappable", type);
+ result = false;
+ }
/* All data members must be non-static. */
if (CLASS_TYPE_P (type))
{
tree field;
for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
if (VAR_P (field))
- return false;
+ {
+ if (notes)
+ inform (DECL_SOURCE_LOCATION (field),
+ "static field %qD is not mappable", field);
+ result = false;
+ }
/* All fields must have mappable types. */
else if (TREE_CODE (field) == FIELD_DECL
- && !cp_omp_mappable_type (TREE_TYPE (field)))
- return false;
+ && !cp_omp_mappable_type_1 (TREE_TYPE (field), notes))
+ result = false;
}
- return true;
+ return result;
+}
+
+/* Return true if TYPE is an OpenMP mappable type. */
+bool
+cp_omp_mappable_type (tree type)
+{
+ return cp_omp_mappable_type_1 (type, false);
+}
+
+/* Return true if TYPE is an OpenMP mappable type.
+ Emit an error messages if not. */
+bool
+cp_omp_emit_unmappable_type_notes (tree type)
+{
+ return cp_omp_mappable_type_1 (type, true);
}
/* Return the last pushed declaration for the symbol DECL or NULL
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index baeba7e..5943762 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -107,8 +107,9 @@ static bool cp_printer (pretty_printer *, text_info *, const char *,
/* Struct for handling %H or %I, which require delaying printing the
type until a postprocessing stage. */
-struct deferred_printed_type
+class deferred_printed_type
{
+public:
deferred_printed_type ()
: m_tree (NULL_TREE), m_buffer_ptr (NULL), m_verbose (false), m_quote (false)
{}
diff --git a/gcc/cp/logic.cc b/gcc/cp/logic.cc
index 2ace8c3..13cc321 100644
--- a/gcc/cp/logic.cc
+++ b/gcc/cp/logic.cc
@@ -104,8 +104,9 @@ struct term_hasher : ggc_ptr_hash<term_entry>
Each term list maintains an iterator that refers to the current
term. This can be used by various tactics to support iteration
and stateful manipulation of the list. */
-struct term_list
+class term_list
{
+public:
typedef std::list<tree>::iterator iterator;
term_list ();
@@ -220,8 +221,9 @@ term_list::replace (iterator iter, tree t1, tree t2)
conclusions written as propositions in the constraint
language (i.e., lists of trees). */
-struct proof_goal
+class proof_goal
{
+public:
term_list assumptions;
term_list conclusions;
};
@@ -230,8 +232,9 @@ struct proof_goal
current sub-goal. The class also provides facilities
for managing subgoals and constructing term lists. */
-struct proof_state : std::list<proof_goal>
+class proof_state : public std::list<proof_goal>
{
+public:
proof_state ();
iterator branch (iterator i);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index f4c34ed..9f27822 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -157,7 +157,7 @@ find_local_binding (cp_binding_level *b, tree name)
return NULL;
}
-struct name_lookup
+class name_lookup
{
public:
typedef std::pair<tree, tree> using_pair;
@@ -3392,7 +3392,7 @@ leave_scope (void)
namespace. For classes, we cache some binding levels. For other
scopes, we just make the structure available for reuse. */
if (scope->kind != sk_namespace
- && scope->kind != sk_class)
+ && scope != previous_class_level)
{
scope->level_chain = free_binding_level;
gcc_assert (!ENABLE_SCOPE_CHECKING
@@ -3420,6 +3420,18 @@ leave_scope (void)
return current_binding_level;
}
+/* When we exit a toplevel class scope, we save its binding level so
+ that we can restore it quickly. Here, we've entered some other
+ class, so we must invalidate our cache. */
+
+void
+invalidate_class_lookup_cache (void)
+{
+ previous_class_level->level_chain = free_binding_level;
+ free_binding_level = previous_class_level;
+ previous_class_level = NULL;
+}
+
static void
resume_scope (cp_binding_level* b)
{
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 1281410..5c379aa 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -773,6 +773,16 @@ cp_lexer_previous_token (cp_lexer *lexer)
return cp_lexer_token_at (lexer, tp);
}
+/* Overload for make_location, taking the lexer to mean the location of the
+ previous token. */
+
+static inline location_t
+make_location (location_t caret, location_t start, cp_lexer *lexer)
+{
+ cp_token *t = cp_lexer_previous_token (lexer);
+ return make_location (caret, start, t->location);
+}
+
/* nonzero if we are presently saving tokens. */
static inline int
@@ -6275,7 +6285,8 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
cp_token *token;
/* Remember where the nested-name-specifier starts. */
- if (cp_parser_uncommitted_to_tentative_parse_p (parser))
+ if (cp_parser_uncommitted_to_tentative_parse_p (parser)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_NESTED_NAME_SPECIFIER))
{
start = cp_lexer_token_position (parser->lexer, false);
push_deferring_access_checks (dk_deferred);
@@ -7773,10 +7784,8 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
~~~^~~~~~~~~~~~~
where the caret is at the deref token, ranging from
the start of postfix_expression to the end of the access expr. */
- location_t end_loc
- = get_finish (cp_lexer_previous_token (parser->lexer)->location);
location_t combined_loc
- = make_location (input_location, start_loc, end_loc);
+ = make_location (input_location, start_loc, parser->lexer);
protected_set_expr_location (postfix_expression, combined_loc);
}
}
@@ -8186,10 +8195,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
^~~~~~~~~~~~~~
with start == caret at the start of the "alignof"/"sizeof"
token, with the endpoint at the final closing paren. */
- location_t finish_loc
- = cp_lexer_previous_token (parser->lexer)->location;
location_t compound_loc
- = make_location (start_loc, start_loc, finish_loc);
+ = make_location (start_loc, start_loc, parser->lexer);
cp_expr ret_expr (ret);
ret_expr.set_location (compound_loc);
@@ -8290,8 +8297,6 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
parser->type_definition_forbidden_message = saved_message;
- location_t finish_loc
- = cp_lexer_peek_token (parser->lexer)->location;
parens.require_close (parser);
/* Construct a location of the form:
@@ -8299,7 +8304,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
^~~~~~~~~~~~~~~
with start == caret, finishing at the close-paren. */
location_t noexcept_loc
- = make_location (start_loc, start_loc, finish_loc);
+ = make_location (start_loc, start_loc, parser->lexer);
return cp_expr (finish_noexcept_expr (expr, tf_warning_or_error),
noexcept_loc);
@@ -8350,15 +8355,13 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
/* Consume the '&&' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the identifier. */
- location_t finish_loc
- = get_finish (cp_lexer_peek_token (parser->lexer)->location);
identifier = cp_parser_identifier (parser);
/* Construct a location of the form:
&&label
^~~~~~~
with caret==start at the "&&", finish at the end of the label. */
location_t combined_loc
- = make_location (start_loc, start_loc, finish_loc);
+ = make_location (start_loc, start_loc, parser->lexer);
/* Create an expression representing the address. */
expression = finish_label_address_expr (identifier, combined_loc);
if (cp_parser_non_integral_constant_expression (parser,
@@ -8606,10 +8609,8 @@ cp_parser_has_attribute_expression (cp_parser *parser)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
with start == caret at the start of the built-in token,
and with the endpoint at the final closing paren. */
- location_t finish_loc
- = cp_lexer_previous_token (parser->lexer)->location;
location_t compound_loc
- = make_location (start_loc, start_loc, finish_loc);
+ = make_location (start_loc, start_loc, parser->lexer);
cp_expr ret_expr (ret ? boolean_true_node : boolean_false_node);
ret_expr.set_location (compound_loc);
@@ -8731,9 +8732,8 @@ cp_parser_new_expression (cp_parser* parser)
^~~~~~~~~~~~
with caret == start at the start of the "new" token, and the end
at the end of the final token we consumed. */
- cp_token *end_tok = cp_lexer_previous_token (parser->lexer);
- location_t end_loc = get_finish (end_tok->location);
- location_t combined_loc = make_location (start_loc, start_loc, end_loc);
+ location_t combined_loc = make_location (start_loc, start_loc,
+ parser->lexer);
/* Create a representation of the new-expression. */
ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
@@ -9679,7 +9679,7 @@ cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
if (cp_parser_allow_gnu_extensions_p (parser)
&& token->type == CPP_COLON)
{
- pedwarn (token->location, OPT_Wpedantic,
+ pedwarn (token->location, OPT_Wpedantic,
"ISO C++ does not allow %<?:%> with omitted middle operand");
/* Implicit true clause. */
expr = NULL_TREE;
@@ -10500,10 +10500,9 @@ cp_parser_lambda_expression (cp_parser* parser)
insert_pending_capture_proxies ();
/* Update the lambda expression to a range. */
- cp_token *end_tok = cp_lexer_previous_token (parser->lexer);
LAMBDA_EXPR_LOCATION (lambda_expr) = make_location (token->location,
token->location,
- end_tok->location);
+ parser->lexer);
if (ok)
lambda_expr = build_lambda_object (lambda_expr);
@@ -11146,11 +11145,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
cp_parser_parse_tentatively (parser);
std_attrs = cp_parser_std_attribute_spec_seq (parser);
if (std_attrs)
- {
- location_t end_loc
- = cp_lexer_previous_token (parser->lexer)->location;
- attrs_loc = make_location (attrs_loc, attrs_loc, end_loc);
- }
+ attrs_loc = make_location (attrs_loc, attrs_loc, parser->lexer);
if (c_dialect_objc ())
{
if (!cp_parser_parse_definitely (parser))
@@ -15528,10 +15523,8 @@ cp_parser_operator (cp_parser* parser, location_t start_loc)
^~~~~~~~~~~~~~~~~~~~~
with caret == start at the start token, finish at the end of the
suffix identifier. */
- location_t finish_loc
- = get_finish (cp_lexer_previous_token (parser->lexer)->location);
location_t combined_loc
- = make_location (start_loc, start_loc, finish_loc);
+ = make_location (start_loc, start_loc, parser->lexer);
return cp_expr (id, combined_loc);
}
@@ -16453,10 +16446,8 @@ cp_parser_template_id (cp_parser *parser,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
with caret == start at the start of the template-name,
ranging until the closing '>'. */
- location_t finish_loc
- = get_finish (cp_lexer_previous_token (parser->lexer)->location);
location_t combined_loc
- = make_location (token->location, token->location, finish_loc);
+ = make_location (token->location, token->location, parser->lexer);
/* Check for concepts autos where they don't belong. We could
identify types in some cases of idnetifier TEMPL, looking ahead
@@ -17832,7 +17823,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
/* Don't gobble tokens or issue error messages if this is an
optional type-specifier. */
- if ((flags & CP_PARSER_FLAGS_OPTIONAL) || cxx_dialect >= cxx17)
+ if (flags & CP_PARSER_FLAGS_OPTIONAL)
cp_parser_parse_tentatively (parser);
token = cp_lexer_peek_token (parser->lexer);
@@ -17872,37 +17863,26 @@ cp_parser_simple_type_specifier (cp_parser* parser,
else
{
cp_parser_error (parser, "expected template-id for type");
- type = NULL_TREE;
+ type = error_mark_node;
}
}
}
- /* Otherwise, look for a type-name. */
- else
- type = cp_parser_type_name (parser, (qualified_p && typename_p));
- /* Keep track of all name-lookups performed in class scopes. */
- if (type
- && !global_p
- && !qualified_p
- && TREE_CODE (type) == TYPE_DECL
- && identifier_p (DECL_NAME (type)))
- maybe_note_name_used_in_class (DECL_NAME (type), type);
- /* If it didn't work out, we don't have a TYPE. */
- if (((flags & CP_PARSER_FLAGS_OPTIONAL) || cxx_dialect >= cxx17)
- && !cp_parser_parse_definitely (parser))
- type = NULL_TREE;
- if (!type && cxx_dialect >= cxx17)
+ /* Otherwise, look for a type-name. */
+ if (!type)
{
- if (flags & CP_PARSER_FLAGS_OPTIONAL)
+ if (cxx_dialect >= cxx17)
cp_parser_parse_tentatively (parser);
- cp_parser_global_scope_opt (parser,
- /*current_scope_valid_p=*/false);
- cp_parser_nested_name_specifier_opt (parser,
- /*typename_keyword_p=*/false,
- /*check_dependency_p=*/true,
- /*type_p=*/false,
- /*is_declaration=*/false);
+ type = cp_parser_type_name (parser, (qualified_p && typename_p));
+
+ if (cxx_dialect >= cxx17 && !cp_parser_parse_definitely (parser))
+ type = NULL_TREE;
+ }
+
+ if (!type && cxx_dialect >= cxx17)
+ {
+ /* Try class template argument deduction. */
tree name = cp_parser_identifier (parser);
if (name && TREE_CODE (name) == IDENTIFIER_NODE
&& parser->scope != error_mark_node)
@@ -17928,11 +17908,21 @@ cp_parser_simple_type_specifier (cp_parser* parser,
}
else
type = error_mark_node;
-
- if ((flags & CP_PARSER_FLAGS_OPTIONAL)
- && !cp_parser_parse_definitely (parser))
- type = NULL_TREE;
}
+
+ /* If it didn't work out, we don't have a TYPE. */
+ if ((flags & CP_PARSER_FLAGS_OPTIONAL)
+ && !cp_parser_parse_definitely (parser))
+ type = NULL_TREE;
+
+ /* Keep track of all name-lookups performed in class scopes. */
+ if (type
+ && !global_p
+ && !qualified_p
+ && TREE_CODE (type) == TYPE_DECL
+ && identifier_p (DECL_NAME (type)))
+ maybe_note_name_used_in_class (DECL_NAME (type), type);
+
if (type && decl_specs)
cp_parser_set_decl_spec_type (decl_specs, type,
token,
@@ -28567,10 +28557,8 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
^~~~~~~~~~~~~~~
with caret == start at the start of the type name,
finishing at the closing brace. */
- location_t finish_loc
- = get_finish (cp_lexer_previous_token (parser->lexer)->location);
location_t combined_loc = make_location (start_loc, start_loc,
- finish_loc);
+ parser->lexer);
cast.set_location (combined_loc);
return cast;
}
@@ -28605,9 +28593,7 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
^~~~~~~~
with caret == start at the start of the type name,
finishing at the closing paren. */
- location_t finish_loc
- = get_finish (cp_lexer_previous_token (parser->lexer)->location);
- location_t combined_loc = make_location (start_loc, start_loc, finish_loc);
+ location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
cast.set_location (combined_loc);
return cast;
}
@@ -30652,9 +30638,7 @@ cp_parser_objc_encode_expression (cp_parser* parser)
@encode(int)
^~~~~~~~~~~~
with caret==start at the @ token, finishing at the close paren. */
- location_t combined_loc
- = make_location (start_loc, start_loc,
- cp_lexer_previous_token (parser->lexer)->location);
+ location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
return cp_expr (objc_build_encode_expr (type), combined_loc);
}
@@ -30698,9 +30682,7 @@ cp_parser_objc_protocol_expression (cp_parser* parser)
@protocol(prot)
^~~~~~~~~~~~~~~
with caret==start at the @ token, finishing at the close paren. */
- location_t combined_loc
- = make_location (start_loc, start_loc,
- cp_lexer_previous_token (parser->lexer)->location);
+ location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
tree result = objc_build_protocol_expr (proto);
protected_set_expr_location (result, combined_loc);
return result;
@@ -30785,9 +30767,7 @@ cp_parser_objc_selector_expression (cp_parser* parser)
@selector(func)
^~~~~~~~~~~~~~~
with caret==start at the @ token, finishing at the close paren. */
- location_t combined_loc
- = make_location (loc, loc,
- cp_lexer_previous_token (parser->lexer)->location);
+ location_t combined_loc = make_location (loc, loc, parser->lexer);
tree result = objc_build_selector_expr (combined_loc, sel_seq);
/* TODO: objc_build_selector_expr doesn't always honor the location. */
protected_set_expr_location (result, combined_loc);
@@ -32429,6 +32409,10 @@ cp_parser_omp_clause_name (cp_parser *parser)
else if (!strcmp ("async", p))
result = PRAGMA_OACC_CLAUSE_ASYNC;
break;
+ case 'b':
+ if (!strcmp ("bind", p))
+ result = PRAGMA_OMP_CLAUSE_BIND;
+ break;
case 'c':
if (!strcmp ("collapse", p))
result = PRAGMA_OMP_CLAUSE_COLLAPSE;
@@ -32528,6 +32512,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
case 'o':
if (!strcmp ("ordered", p))
result = PRAGMA_OMP_CLAUSE_ORDERED;
+ else if (!strcmp ("order", p))
+ result = PRAGMA_OMP_CLAUSE_ORDER;
break;
case 'p':
if (!strcmp ("parallel", p))
@@ -33919,6 +33905,100 @@ cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
return list;
}
+/* OpenMP 5.0:
+ order ( concurrent ) */
+
+static tree
+cp_parser_omp_clause_order (cp_parser *parser, tree list, location_t location)
+{
+ tree c, id;
+ const char *p;
+
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ cp_parser_error (parser, "expected %<concurrent%>");
+ goto out_err;
+ }
+ else
+ {
+ id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+ if (strcmp (p, "concurrent") != 0)
+ {
+ cp_parser_error (parser, "expected %<concurrent%>");
+ goto out_err;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ if (!parens.require_close (parser))
+ goto out_err;
+
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order", location); */
+ c = build_omp_clause (location, OMP_CLAUSE_ORDER);
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ out_err:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
+/* OpenMP 5.0:
+ bind ( teams | parallel | thread ) */
+
+static tree
+cp_parser_omp_clause_bind (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree c;
+ const char *p;
+ enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
+
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ invalid:
+ cp_parser_error (parser,
+ "expected %<teams%>, %<parallel%> or %<thread%>");
+ goto out_err;
+ }
+ else
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ p = IDENTIFIER_POINTER (id);
+ }
+ if (strcmp (p, "teams") == 0)
+ kind = OMP_CLAUSE_BIND_TEAMS;
+ else if (strcmp (p, "parallel") == 0)
+ kind = OMP_CLAUSE_BIND_PARALLEL;
+ else if (strcmp (p, "thread") != 0)
+ goto invalid;
+ cp_lexer_consume_token (parser->lexer);
+ if (!parens.require_close (parser))
+ goto out_err;
+
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind", location); */
+ c = build_omp_clause (location, OMP_CLAUSE_BIND);
+ OMP_CLAUSE_BIND_KIND (c) = kind;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ out_err:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
/* OpenMP 2.5:
ordered
@@ -35436,6 +35516,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
switch (c_kind)
{
+ case PRAGMA_OMP_CLAUSE_BIND:
+ clauses = cp_parser_omp_clause_bind (parser, clauses,
+ token->location);
+ c_name = "bind";
+ break;
case PRAGMA_OMP_CLAUSE_COLLAPSE:
clauses = cp_parser_omp_clause_collapse (parser, clauses,
token->location);
@@ -35510,7 +35595,8 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
c_name = "mergeable";
break;
case PRAGMA_OMP_CLAUSE_NOWAIT:
- clauses = cp_parser_omp_clause_nowait (parser, clauses, token->location);
+ clauses = cp_parser_omp_clause_nowait (parser, clauses,
+ token->location);
c_name = "nowait";
break;
case PRAGMA_OMP_CLAUSE_NUM_TASKS:
@@ -35523,6 +35609,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
token->location);
c_name = "num_threads";
break;
+ case PRAGMA_OMP_CLAUSE_ORDER:
+ clauses = cp_parser_omp_clause_order (parser, clauses,
+ token->location);
+ c_name = "order";
+ break;
case PRAGMA_OMP_CLAUSE_ORDERED:
clauses = cp_parser_omp_clause_ordered (parser, clauses,
token->location);
@@ -37546,6 +37637,50 @@ cp_omp_split_clauses (location_t loc, enum tree_code code,
cclauses[i] = finish_omp_clauses (cclauses[i], C_ORT_OMP);
}
+/* OpenMP 5.0:
+ #pragma omp loop loop-clause[optseq] new-line
+ for-loop */
+
+#define OMP_LOOP_CLAUSE_MASK \
+ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
+
+static tree
+cp_parser_omp_loop (cp_parser *parser, cp_token *pragma_tok,
+ char *p_name, omp_clause_mask mask, tree *cclauses,
+ bool *if_p)
+{
+ tree clauses, sb, ret;
+ unsigned int save;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+
+ strcat (p_name, " loop");
+ mask |= OMP_LOOP_CLAUSE_MASK;
+
+ clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
+ cclauses == NULL);
+ if (cclauses)
+ {
+ cp_omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
+ }
+
+ keep_next_level (true);
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+
+ ret = cp_parser_omp_for_loop (parser, OMP_LOOP, clauses, cclauses, if_p);
+
+ cp_parser_end_omp_structured_block (parser, save);
+ add_stmt (finish_omp_for_block (finish_omp_structured_block (sb), ret));
+
+ return ret;
+}
+
/* OpenMP 4.0:
#pragma omp simd simd-clause[optseq] new-line
for-loop */
@@ -37560,7 +37695,8 @@ cp_omp_split_clauses (location_t loc, enum tree_code code,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
static tree
cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
@@ -37620,7 +37756,8 @@ cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
static tree
cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
@@ -38004,11 +38141,11 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return NULL_TREE;
}
- else if (cclauses == NULL && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
- if (strcmp (p, "master") == 0)
+ if (cclauses == NULL && strcmp (p, "master") == 0)
{
tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
cclauses = cclauses_buf;
@@ -38026,12 +38163,34 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
return ret;
return stmt;
}
+ else if (strcmp (p, "loop") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+ cclauses, if_p);
+ block = begin_omp_parallel ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ tree ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+ cclauses, if_p);
+ cp_parser_end_omp_structured_block (parser, save);
+ stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
+ block);
+ if (ret == NULL_TREE)
+ return ret;
+ OMP_PARALLEL_COMBINED (stmt) = 1;
+ return stmt;
+ }
else if (!flag_openmp) /* flag_openmp_simd */
{
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
return NULL_TREE;
}
- else if (strcmp (p, "sections") == 0)
+ else if (cclauses == NULL && strcmp (p, "sections") == 0)
{
tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
cclauses = cclauses_buf;
@@ -38426,6 +38585,34 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
SET_EXPR_LOCATION (ret, loc);
return add_stmt (ret);
}
+ else if (strcmp (p, "loop") == 0)
+ {
+ tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
+ if (cclauses == NULL)
+ cclauses = cclauses_buf;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!flag_openmp) /* flag_openmp_simd */
+ return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+ cclauses, if_p);
+ keep_next_level (true);
+ sb = begin_omp_structured_block ();
+ save = cp_parser_begin_omp_structured_block (parser);
+ ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
+ cclauses, if_p);
+ cp_parser_end_omp_structured_block (parser, save);
+ tree body = finish_omp_structured_block (sb);
+ if (ret == NULL)
+ return ret;
+ clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
+ ret = make_node (OMP_TEAMS);
+ TREE_TYPE (ret) = void_type_node;
+ OMP_TEAMS_CLAUSES (ret) = clauses;
+ OMP_TEAMS_BODY (ret) = body;
+ OMP_TEAMS_COMBINED (ret) = 1;
+ SET_EXPR_LOCATION (ret, loc);
+ return add_stmt (ret);
+ }
}
if (!flag_openmp) /* flag_openmp_simd */
{
@@ -40682,6 +40869,11 @@ cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
stmt = cp_parser_omp_for (parser, pragma_tok, p_name, mask, NULL,
if_p);
break;
+ case PRAGMA_OMP_LOOP:
+ strcpy (p_name, "#pragma omp");
+ stmt = cp_parser_omp_loop (parser, pragma_tok, p_name, mask, NULL,
+ if_p);
+ break;
case PRAGMA_OMP_MASTER:
strcpy (p_name, "#pragma omp");
stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
@@ -41318,6 +41510,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
case PRAGMA_OMP_CRITICAL:
case PRAGMA_OMP_DISTRIBUTE:
case PRAGMA_OMP_FOR:
+ case PRAGMA_OMP_LOOP:
case PRAGMA_OMP_MASTER:
case PRAGMA_OMP_PARALLEL:
case PRAGMA_OMP_SECTIONS:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c5161a7..deaac57 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -67,7 +67,7 @@ static vec<int> inline_parm_levels;
static GTY(()) struct tinst_level *current_tinst_level;
-static GTY(()) tree saved_access_scope;
+static GTY(()) vec<tree, va_gc> *saved_access_scope;
/* Live only within one (recursive) call to tsubst_expr. We use
this to pass the statement expression node from the STMT_EXPR
@@ -247,8 +247,7 @@ push_access_scope (tree t)
if (TREE_CODE (t) == FUNCTION_DECL)
{
- saved_access_scope = tree_cons
- (NULL_TREE, current_function_decl, saved_access_scope);
+ vec_safe_push (saved_access_scope, current_function_decl);
current_function_decl = t;
}
}
@@ -260,10 +259,7 @@ static void
pop_access_scope (tree t)
{
if (TREE_CODE (t) == FUNCTION_DECL)
- {
- current_function_decl = TREE_VALUE (saved_access_scope);
- saved_access_scope = TREE_CHAIN (saved_access_scope);
- }
+ current_function_decl = saved_access_scope->pop();
if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
pop_nested_class ();
@@ -4954,7 +4950,8 @@ process_partial_specialization (tree decl)
simple identifier' condition and also the `specialized
non-type argument' bit. */
&& TREE_CODE (arg) != TEMPLATE_PARM_INDEX
- && !(REFERENCE_REF_P (arg)
+ && !((REFERENCE_REF_P (arg)
+ || TREE_CODE (arg) == VIEW_CONVERT_EXPR)
&& TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_PARM_INDEX))
{
if ((!packed_args && tpd.arg_uses_template_parms[i])
@@ -12032,8 +12029,9 @@ tsubst_binary_right_fold (tree t, tree args, tsubst_flags_t complain,
/* Walk through the pattern of a pack expansion, adding everything in
local_specializations to a list. */
-struct el_data
+class el_data
{
+public:
hash_set<tree> internal;
tree extra;
tsubst_flags_t complain;
@@ -16421,6 +16419,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
@@ -17550,6 +17549,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
break;
case OMP_FOR:
+ case OMP_LOOP:
case OMP_SIMD:
case OMP_DISTRIBUTE:
case OMP_TASKLOOP:
@@ -22369,9 +22369,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
/* Template-parameter dependent expression. Just accept it for now.
It will later be processed in convert_template_argument. */
;
- else if (same_type_p (non_reference (TREE_TYPE (arg)),
- non_reference (tparm)))
- /* OK */;
+ else if (same_type_ignoring_top_level_qualifiers_p
+ (non_reference (TREE_TYPE (arg)),
+ non_reference (tparm)))
+ /* OK. Ignore top-level quals here because a class-type template
+ parameter object is const. */;
else if ((strict & UNIFY_ALLOW_INTEGER)
&& CP_INTEGRAL_TYPE_P (tparm))
/* Convert the ARG to the type of PARM; the deduced non-type
@@ -25223,6 +25225,8 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
"with %<-std=c++2a%> or %<-std=gnu++2a%>");
return true;
}
+ if (dependent_type_p (type))
+ return false;
if (!complete_type_or_else (type, NULL_TREE))
return true;
if (!literal_type_p (type))
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 372c442..b441af8 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1275,7 +1275,7 @@ tree
lookup_member_fuzzy (tree xbasetype, tree name, bool want_type_p)
{
tree type = NULL_TREE, basetype_path = NULL_TREE;
- struct lookup_field_fuzzy_info lffi (want_type_p);
+ class lookup_field_fuzzy_info lffi (want_type_p);
/* rval_binfo is the binfo associated with the found member, note,
this can be set with useful information, even when rval is not
@@ -1803,8 +1803,9 @@ field_accessor_p (tree fn, tree field_decl, bool const_p)
/* Callback data for dfs_locate_field_accessor_pre. */
-struct locate_field_data
+class locate_field_data
{
+public:
locate_field_data (tree field_decl_, bool const_p_)
: field_decl (field_decl_), const_p (const_p_) {}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4f71ac7..269092d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4380,8 +4380,9 @@ expand_or_defer_fn (tree fn)
}
}
-struct nrv_data
+class nrv_data
{
+public:
nrv_data () : visited (37) {}
tree var;
@@ -4394,7 +4395,7 @@ struct nrv_data
static tree
finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
{
- struct nrv_data *dp = (struct nrv_data *)data;
+ class nrv_data *dp = (class nrv_data *)data;
tree_node **slot;
/* No need to walk into types. There wouldn't be any need to walk into
@@ -4452,7 +4453,7 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
void
finalize_nrv (tree *tp, tree var, tree result)
{
- struct nrv_data data;
+ class nrv_data data;
/* Copy name from VAR to RESULT. */
DECL_NAME (result) = DECL_NAME (var);
@@ -6126,6 +6127,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
bool branch_seen = false;
bool copyprivate_seen = false;
bool ordered_seen = false;
+ bool order_seen = false;
bool schedule_seen = false;
bool oacc_async = false;
tree last_iterators = NULL_TREE;
@@ -7090,6 +7092,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
"array section does not have mappable type "
"in %qs clause",
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
remove = true;
}
while (TREE_CODE (t) == ARRAY_REF)
@@ -7158,6 +7161,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
error_at (OMP_CLAUSE_LOCATION (c),
"%qE does not have a mappable type in %qs clause",
t, omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
remove = true;
}
while (TREE_CODE (t) == COMPONENT_REF)
@@ -7236,6 +7240,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
error_at (OMP_CLAUSE_LOCATION (c),
"%qD does not have a mappable type in %qs clause", t,
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
remove = true;
}
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
@@ -7384,6 +7389,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
error_at (OMP_CLAUSE_LOCATION (c),
"%qD does not have a mappable type in %qs clause", t,
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ cp_omp_emit_unmappable_type_notes (TREE_TYPE (t));
remove = true;
}
if (remove)
@@ -7544,6 +7550,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_SEQ:
@@ -7595,6 +7602,13 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
ordered_seen = true;
break;
+ case OMP_CLAUSE_ORDER:
+ if (order_seen)
+ remove = true;
+ else
+ order_seen = true;
+ break;
+
case OMP_CLAUSE_INBRANCH:
case OMP_CLAUSE_NOTINBRANCH:
if (branch_seen)
@@ -7770,6 +7784,17 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
"%<reduction%> clause", "ordered");
pc = &OMP_CLAUSE_CHAIN (c);
continue;
+ case OMP_CLAUSE_ORDER:
+ if (ordered_seen)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%<order%> clause must not be used together "
+ "with %<ordered%>");
+ *pc = OMP_CLAUSE_CHAIN (c);
+ continue;
+ }
+ pc = &OMP_CLAUSE_CHAIN (c);
+ continue;
case OMP_CLAUSE_NOWAIT:
if (copyprivate_seen)
{
diff --git a/gcc/data-streamer-in.c b/gcc/data-streamer-in.c
index 9c79e1d..11ad084 100644
--- a/gcc/data-streamer-in.c
+++ b/gcc/data-streamer-in.c
@@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see
IB. Write the length to RLEN. */
static const char *
-string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen)
+string_for_index (class data_in *data_in, unsigned int loc, unsigned int *rlen)
{
unsigned int len;
const char *result;
@@ -62,8 +62,8 @@ string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen)
IB. Write the length to RLEN. */
const char *
-streamer_read_indexed_string (struct data_in *data_in,
- struct lto_input_block *ib, unsigned int *rlen)
+streamer_read_indexed_string (class data_in *data_in,
+ class lto_input_block *ib, unsigned int *rlen)
{
return string_for_index (data_in, streamer_read_uhwi (ib), rlen);
}
@@ -72,7 +72,7 @@ streamer_read_indexed_string (struct data_in *data_in,
/* Read a NULL terminated string from the string table in DATA_IN. */
const char *
-streamer_read_string (struct data_in *data_in, struct lto_input_block *ib)
+streamer_read_string (class data_in *data_in, class lto_input_block *ib)
{
unsigned int len;
const char *ptr;
@@ -91,7 +91,7 @@ streamer_read_string (struct data_in *data_in, struct lto_input_block *ib)
Write the length to RLEN. */
const char *
-bp_unpack_indexed_string (struct data_in *data_in,
+bp_unpack_indexed_string (class data_in *data_in,
struct bitpack_d *bp, unsigned int *rlen)
{
return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
@@ -101,7 +101,7 @@ bp_unpack_indexed_string (struct data_in *data_in,
/* Read a NULL terminated string from the string table in DATA_IN. */
const char *
-bp_unpack_string (struct data_in *data_in, struct bitpack_d *bp)
+bp_unpack_string (class data_in *data_in, struct bitpack_d *bp)
{
unsigned int len;
const char *ptr;
@@ -119,7 +119,7 @@ bp_unpack_string (struct data_in *data_in, struct bitpack_d *bp)
/* Read an unsigned HOST_WIDE_INT number from IB. */
unsigned HOST_WIDE_INT
-streamer_read_uhwi (struct lto_input_block *ib)
+streamer_read_uhwi (class lto_input_block *ib)
{
unsigned HOST_WIDE_INT result;
int shift;
@@ -154,7 +154,7 @@ streamer_read_uhwi (struct lto_input_block *ib)
/* Read a HOST_WIDE_INT number from IB. */
HOST_WIDE_INT
-streamer_read_hwi (struct lto_input_block *ib)
+streamer_read_hwi (class lto_input_block *ib)
{
HOST_WIDE_INT result = 0;
int shift = 0;
@@ -178,7 +178,7 @@ streamer_read_hwi (struct lto_input_block *ib)
/* Read gcov_type value from IB. */
gcov_type
-streamer_read_gcov_count (struct lto_input_block *ib)
+streamer_read_gcov_count (class lto_input_block *ib)
{
gcov_type ret = streamer_read_hwi (ib);
return ret;
@@ -188,7 +188,7 @@ streamer_read_gcov_count (struct lto_input_block *ib)
input block IB. */
wide_int
-streamer_read_wide_int (struct lto_input_block *ib)
+streamer_read_wide_int (class lto_input_block *ib)
{
HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
int i;
@@ -203,7 +203,7 @@ streamer_read_wide_int (struct lto_input_block *ib)
input block IB. */
widest_int
-streamer_read_widest_int (struct lto_input_block *ib)
+streamer_read_widest_int (class lto_input_block *ib)
{
HOST_WIDE_INT a[WIDE_INT_MAX_ELTS];
int i;
diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h
index cb3efc1..c8bfd9a 100644
--- a/gcc/data-streamer.h
+++ b/gcc/data-streamer.h
@@ -73,18 +73,18 @@ void streamer_write_wide_int (struct output_block *, const wide_int &);
void streamer_write_widest_int (struct output_block *, const widest_int &);
/* In data-streamer-in.c */
-const char *streamer_read_string (struct data_in *, struct lto_input_block *);
-const char *streamer_read_indexed_string (struct data_in *,
- struct lto_input_block *,
+const char *streamer_read_string (class data_in *, class lto_input_block *);
+const char *streamer_read_indexed_string (class data_in *,
+ class lto_input_block *,
unsigned int *);
-const char *bp_unpack_indexed_string (struct data_in *, struct bitpack_d *,
+const char *bp_unpack_indexed_string (class data_in *, struct bitpack_d *,
unsigned int *);
-const char *bp_unpack_string (struct data_in *, struct bitpack_d *);
-unsigned HOST_WIDE_INT streamer_read_uhwi (struct lto_input_block *);
-HOST_WIDE_INT streamer_read_hwi (struct lto_input_block *);
-gcov_type streamer_read_gcov_count (struct lto_input_block *);
-wide_int streamer_read_wide_int (struct lto_input_block *);
-widest_int streamer_read_widest_int (struct lto_input_block *);
+const char *bp_unpack_string (class data_in *, struct bitpack_d *);
+unsigned HOST_WIDE_INT streamer_read_uhwi (class lto_input_block *);
+HOST_WIDE_INT streamer_read_hwi (class lto_input_block *);
+gcov_type streamer_read_gcov_count (class lto_input_block *);
+wide_int streamer_read_wide_int (class lto_input_block *);
+widest_int streamer_read_widest_int (class lto_input_block *);
/* Returns a new bit-packing context for bit-packing into S. */
static inline struct bitpack_d
@@ -149,7 +149,7 @@ streamer_write_bitpack (struct bitpack_d *bp)
/* Returns a new bit-packing context for bit-unpacking from IB. */
static inline struct bitpack_d
-streamer_read_bitpack (struct lto_input_block *ib)
+streamer_read_bitpack (class lto_input_block *ib)
{
struct bitpack_d bp;
bp.word = streamer_read_uhwi (ib);
@@ -174,7 +174,7 @@ bp_unpack_value (struct bitpack_d *bp, unsigned nbits)
if (pos + nbits > BITS_PER_BITPACK_WORD)
{
bp->word = val
- = streamer_read_uhwi ((struct lto_input_block *)bp->stream);
+ = streamer_read_uhwi ((class lto_input_block *)bp->stream);
bp->pos = nbits;
return val & mask;
}
@@ -218,7 +218,7 @@ streamer_write_char_stream (struct lto_output_stream *obs, char c)
/* Read byte from the input block. */
static inline unsigned char
-streamer_read_uchar (struct lto_input_block *ib)
+streamer_read_uchar (class lto_input_block *ib)
{
if (ib->p >= ib->len)
lto_section_overrun (ib);
@@ -248,7 +248,7 @@ streamer_write_hwi_in_range (struct lto_output_stream *obs,
to be compile time constant. PURPOSE is used for error reporting. */
static inline HOST_WIDE_INT
-streamer_read_hwi_in_range (struct lto_input_block *ib,
+streamer_read_hwi_in_range (class lto_input_block *ib,
const char *purpose,
HOST_WIDE_INT min,
HOST_WIDE_INT max)
@@ -337,7 +337,7 @@ streamer_write_record_start (struct output_block *ob, enum LTO_tags tag)
/* Return the next tag in the input block IB. */
static inline enum LTO_tags
-streamer_read_record_start (struct lto_input_block *ib)
+streamer_read_record_start (class lto_input_block *ib)
{
return streamer_read_enum (ib, LTO_tags, LTO_NUM_TAGS);
}
diff --git a/gcc/ddg.c b/gcc/ddg.c
index 82554ed..28b2be9 100644
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -215,7 +215,7 @@ create_ddg_dep_from_intra_loop_link (ddg_ptr g, ddg_node_ptr src_node,
{
int regno = REGNO (SET_DEST (set));
df_ref first_def;
- struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb);
+ class df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb);
first_def = df_bb_regno_first_def_find (g->bb, regno);
gcc_assert (first_def);
@@ -288,7 +288,7 @@ add_cross_iteration_register_deps (ddg_ptr g, df_ref last_def)
if (flag_checking && DF_REF_ID (last_def) != DF_REF_ID (first_def))
{
- struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb);
+ class df_rd_bb_info *bb_info = DF_RD_BB_INFO (g->bb);
gcc_assert (!bitmap_bit_p (&bb_info->gen, DF_REF_ID (first_def)));
}
@@ -369,7 +369,7 @@ static void
build_inter_loop_deps (ddg_ptr g)
{
unsigned rd_num;
- struct df_rd_bb_info *rd_bb_info;
+ class df_rd_bb_info *rd_bb_info;
bitmap_iterator bi;
rd_bb_info = DF_RD_BB_INFO (g->bb);
@@ -475,7 +475,7 @@ build_intra_loop_deps (ddg_ptr g)
{
int i;
/* Hold the dependency analysis state during dependency calculations. */
- struct deps_desc tmp_deps;
+ class deps_desc tmp_deps;
rtx_insn *head, *tail;
/* Build the dependence information, using the sched_analyze function. */
diff --git a/gcc/df-core.c b/gcc/df-core.c
index 7299bfd..be19aba 100644
--- a/gcc/df-core.c
+++ b/gcc/df-core.c
@@ -298,12 +298,12 @@ There are 4 ways to obtain access to refs:
Artificial defs and uses occur both at the beginning and ends of blocks.
- For blocks that area at the destination of eh edges, the
+ For blocks that are at the destination of eh edges, the
artificial uses and defs occur at the beginning. The defs relate
to the registers specified in EH_RETURN_DATA_REGNO and the uses
- relate to the registers specified in ED_USES. Logically these
+ relate to the registers specified in EH_USES. Logically these
defs and uses should really occur along the eh edge, but there is
- no convenient way to do this. Artificial edges that occur at the
+ no convenient way to do this. Artificial defs that occur at the
beginning of the block have the DF_REF_AT_TOP flag set.
Artificial uses occur at the end of all blocks. These arise from
@@ -407,7 +407,7 @@ bitmap_obstack df_bitmap_obstack;
Functions to create, destroy and manipulate an instance of df.
----------------------------------------------------------------------------*/
-struct df_d *df;
+class df_d *df;
/* Add PROBLEM (and any dependent problems) to the DF instance. */
@@ -684,7 +684,7 @@ static unsigned int
rest_of_handle_df_initialize (void)
{
gcc_assert (!df);
- df = XCNEW (struct df_d);
+ df = XCNEW (class df_d);
df->changeable_flags = 0;
bitmap_obstack_initialize (&df_bitmap_obstack);
@@ -1293,7 +1293,7 @@ df_analyze (void)
Returns the number of blocks which is always loop->num_nodes. */
static int
-loop_post_order_compute (int *post_order, struct loop *loop)
+loop_post_order_compute (int *post_order, class loop *loop)
{
edge_iterator *stack;
int sp;
@@ -1354,7 +1354,7 @@ loop_post_order_compute (int *post_order, struct loop *loop)
by LOOP. Returns the number of blocks which is always loop->num_nodes. */
static void
-loop_inverted_post_order_compute (vec<int> *post_order, struct loop *loop)
+loop_inverted_post_order_compute (vec<int> *post_order, class loop *loop)
{
basic_block bb;
edge_iterator *stack;
@@ -1419,7 +1419,7 @@ loop_inverted_post_order_compute (vec<int> *post_order, struct loop *loop)
/* Analyze dataflow info for the basic blocks contained in LOOP. */
void
-df_analyze_loop (struct loop *loop)
+df_analyze_loop (class loop *loop)
{
free (df->postorder);
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index a9dfa62..d32c688 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -144,8 +144,9 @@ df_print_bb_index (basic_block bb, FILE *file)
/* Private data used to compute the solution for this problem. These
data structures are not accessible outside of this module. */
-struct df_rd_problem_data
+class df_rd_problem_data
{
+public:
/* The set of defs to regs invalidated by call. */
bitmap_head sparse_invalidated_by_call;
/* The set of defs to regs invalidate by call for rd. */
@@ -161,7 +162,7 @@ static void
df_rd_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
void *vbb_info)
{
- struct df_rd_bb_info *bb_info = (struct df_rd_bb_info *) vbb_info;
+ class df_rd_bb_info *bb_info = (class df_rd_bb_info *) vbb_info;
if (bb_info)
{
bitmap_clear (&bb_info->kill);
@@ -181,17 +182,17 @@ df_rd_alloc (bitmap all_blocks)
{
unsigned int bb_index;
bitmap_iterator bi;
- struct df_rd_problem_data *problem_data;
+ class df_rd_problem_data *problem_data;
if (df_rd->problem_data)
{
- problem_data = (struct df_rd_problem_data *) df_rd->problem_data;
+ problem_data = (class df_rd_problem_data *) df_rd->problem_data;
bitmap_clear (&problem_data->sparse_invalidated_by_call);
bitmap_clear (&problem_data->dense_invalidated_by_call);
}
else
{
- problem_data = XNEW (struct df_rd_problem_data);
+ problem_data = XNEW (class df_rd_problem_data);
df_rd->problem_data = problem_data;
bitmap_obstack_initialize (&problem_data->rd_bitmaps);
@@ -208,7 +209,7 @@ df_rd_alloc (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
/* When bitmaps are already initialized, just clear them. */
if (bb_info->kill.obstack)
@@ -282,7 +283,7 @@ df_rd_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx_insn *insn,
of kill sets. */
static void
-df_rd_bb_local_compute_process_def (struct df_rd_bb_info *bb_info,
+df_rd_bb_local_compute_process_def (class df_rd_bb_info *bb_info,
df_ref def,
int top_flag)
{
@@ -339,7 +340,7 @@ static void
df_rd_bb_local_compute (unsigned int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
rtx_insn *insn;
bitmap_clear (&seen_in_block);
@@ -389,8 +390,8 @@ df_rd_local_compute (bitmap all_blocks)
unsigned int bb_index;
bitmap_iterator bi;
unsigned int regno;
- struct df_rd_problem_data *problem_data
- = (struct df_rd_problem_data *) df_rd->problem_data;
+ class df_rd_problem_data *problem_data
+ = (class df_rd_problem_data *) df_rd->problem_data;
bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_call;
bitmap dense_invalidated = &problem_data->dense_invalidated_by_call;
@@ -434,7 +435,7 @@ df_rd_init_solution (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
bitmap_copy (&bb_info->out, &bb_info->gen);
bitmap_clear (&bb_info->in);
@@ -455,8 +456,8 @@ df_rd_confluence_n (edge e)
if (e->flags & EDGE_EH)
{
- struct df_rd_problem_data *problem_data
- = (struct df_rd_problem_data *) df_rd->problem_data;
+ class df_rd_problem_data *problem_data
+ = (class df_rd_problem_data *) df_rd->problem_data;
bitmap sparse_invalidated = &problem_data->sparse_invalidated_by_call;
bitmap dense_invalidated = &problem_data->dense_invalidated_by_call;
bitmap_iterator bi;
@@ -484,7 +485,7 @@ df_rd_confluence_n (edge e)
static bool
df_rd_transfer_function (int bb_index)
{
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
unsigned int regno;
bitmap_iterator bi;
bitmap in = &bb_info->in;
@@ -498,12 +499,12 @@ df_rd_transfer_function (int bb_index)
changed = bitmap_ior_and_compl (out, gen, in, kill);
else
{
- struct df_rd_problem_data *problem_data;
+ class df_rd_problem_data *problem_data;
bitmap_head tmp;
/* Note that TMP is _not_ a temporary bitmap if we end up replacing
OUT with TMP. Therefore, allocate TMP in the RD bitmaps obstack. */
- problem_data = (struct df_rd_problem_data *) df_rd->problem_data;
+ problem_data = (class df_rd_problem_data *) df_rd->problem_data;
bitmap_initialize (&tmp, &problem_data->rd_bitmaps);
bitmap_and_compl (&tmp, in, kill);
@@ -527,7 +528,7 @@ df_rd_transfer_function (int bb_index)
basic block, and mask out DEFs of registers that are not live.
Computing the mask looks costly, but the benefit of the pruning
outweighs the cost. */
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
bitmap regs_live_out = &df_lr_get_bb_info (bb_index)->out;
bitmap live_defs = BITMAP_ALLOC (&df_bitmap_obstack);
unsigned int regno;
@@ -549,8 +550,8 @@ df_rd_transfer_function (int bb_index)
static void
df_rd_free (void)
{
- struct df_rd_problem_data *problem_data
- = (struct df_rd_problem_data *) df_rd->problem_data;
+ class df_rd_problem_data *problem_data
+ = (class df_rd_problem_data *) df_rd->problem_data;
if (problem_data)
{
@@ -570,8 +571,8 @@ df_rd_free (void)
static void
df_rd_start_dump (FILE *file)
{
- struct df_rd_problem_data *problem_data
- = (struct df_rd_problem_data *) df_rd->problem_data;
+ class df_rd_problem_data *problem_data
+ = (class df_rd_problem_data *) df_rd->problem_data;
unsigned int m = DF_REG_SIZE (df);
unsigned int regno;
@@ -643,7 +644,7 @@ df_rd_dump_defs_set (bitmap defs_set, const char *prefix, FILE *file)
static void
df_rd_top_dump (basic_block bb, FILE *file)
{
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -658,7 +659,7 @@ df_rd_top_dump (basic_block bb, FILE *file)
static void
df_rd_bottom_dump (basic_block bb, FILE *file)
{
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -691,7 +692,7 @@ static const struct df_problem problem_RD =
NULL, /* Incremental solution verify start. */
NULL, /* Incremental solution verify end. */
NULL, /* Dependent problem. */
- sizeof (struct df_rd_bb_info),/* Size of entry of block_info array. */
+ sizeof (class df_rd_bb_info),/* Size of entry of block_info array. */
TV_DF_RD, /* Timing variable. */
true /* Reset blocks on dropping out of blocks_to_analyze. */
};
@@ -733,7 +734,7 @@ static void
df_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
void *vbb_info)
{
- struct df_lr_bb_info *bb_info = (struct df_lr_bb_info *) vbb_info;
+ class df_lr_bb_info *bb_info = (class df_lr_bb_info *) vbb_info;
if (bb_info)
{
bitmap_clear (&bb_info->use);
@@ -769,7 +770,7 @@ df_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
/* When bitmaps are already initialized, just clear them. */
if (bb_info->use.obstack)
@@ -800,7 +801,7 @@ df_lr_reset (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
gcc_assert (bb_info);
bitmap_clear (&bb_info->in);
bitmap_clear (&bb_info->out);
@@ -814,7 +815,7 @@ static void
df_lr_bb_local_compute (unsigned int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
rtx_insn *insn;
df_ref def, use;
@@ -929,7 +930,7 @@ df_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
{
/* The exit block is special for this problem and its bits are
computed from thin air. */
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (EXIT_BLOCK);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (EXIT_BLOCK);
bitmap_copy (&bb_info->use, df->exit_block_uses);
}
else
@@ -950,7 +951,7 @@ df_lr_init (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
bitmap_copy (&bb_info->in, &bb_info->use);
bitmap_clear (&bb_info->out);
}
@@ -996,7 +997,7 @@ df_lr_confluence_n (edge e)
static bool
df_lr_transfer_function (int bb_index)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
bitmap in = &bb_info->in;
bitmap out = &bb_info->out;
bitmap use = &bb_info->use;
@@ -1068,7 +1069,7 @@ df_lr_free (void)
static void
df_lr_top_dump (basic_block bb, FILE *file)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
struct df_lr_problem_data *problem_data;
if (!bb_info)
return;
@@ -1096,7 +1097,7 @@ df_lr_top_dump (basic_block bb, FILE *file)
static void
df_lr_bottom_dump (basic_block bb, FILE *file)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
struct df_lr_problem_data *problem_data;
if (!bb_info)
return;
@@ -1213,7 +1214,7 @@ static const struct df_problem problem_LR =
df_lr_verify_solution_start,/* Incremental solution verify start. */
df_lr_verify_solution_end, /* Incremental solution verify end. */
NULL, /* Dependent problem. */
- sizeof (struct df_lr_bb_info),/* Size of entry of block_info array. */
+ sizeof (class df_lr_bb_info),/* Size of entry of block_info array. */
TV_DF_LR, /* Timing variable. */
false /* Reset blocks on dropping out of blocks_to_analyze. */
};
@@ -1253,7 +1254,7 @@ df_lr_verify_transfer_functions (void)
FOR_ALL_BB_FN (bb, cfun)
{
- struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
+ class df_lr_bb_info *bb_info = df_lr_get_bb_info (bb->index);
bitmap_set_bit (&all_blocks, bb->index);
if (bb_info)
@@ -1339,7 +1340,7 @@ static void
df_live_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
void *vbb_info)
{
- struct df_live_bb_info *bb_info = (struct df_live_bb_info *) vbb_info;
+ class df_live_bb_info *bb_info = (class df_live_bb_info *) vbb_info;
if (bb_info)
{
bitmap_clear (&bb_info->gen);
@@ -1377,7 +1378,7 @@ df_live_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
EXECUTE_IF_SET_IN_BITMAP (df_live->out_of_date_transfer_functions, 0, bb_index, bi)
{
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
/* When bitmaps are already initialized, just clear them. */
if (bb_info->kill.obstack)
@@ -1407,7 +1408,7 @@ df_live_reset (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
gcc_assert (bb_info);
bitmap_clear (&bb_info->in);
bitmap_clear (&bb_info->out);
@@ -1421,7 +1422,7 @@ static void
df_live_bb_local_compute (unsigned int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
rtx_insn *insn;
df_ref def;
int luid = 0;
@@ -1497,8 +1498,8 @@ df_live_init (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
- struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
/* No register may reach a location where it is not used. Thus
we trim the rr result to the places where it is used. */
@@ -1527,8 +1528,8 @@ df_live_confluence_n (edge e)
static bool
df_live_transfer_function (int bb_index)
{
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
- struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
bitmap in = &bb_info->in;
bitmap out = &bb_info->out;
bitmap gen = &bb_info->gen;
@@ -1559,8 +1560,8 @@ df_live_finalize (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
- struct df_live_bb_info *bb_live_info = df_live_get_bb_info (bb_index);
+ class df_lr_bb_info *bb_lr_info = df_lr_get_bb_info (bb_index);
+ class df_live_bb_info *bb_live_info = df_live_get_bb_info (bb_index);
/* No register may reach a location where it is not used. Thus
we trim the rr result to the places where it is used. */
@@ -1600,7 +1601,7 @@ df_live_free (void)
static void
df_live_top_dump (basic_block bb, FILE *file)
{
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
struct df_live_problem_data *problem_data;
if (!bb_info)
@@ -1629,7 +1630,7 @@ df_live_top_dump (basic_block bb, FILE *file)
static void
df_live_bottom_dump (basic_block bb, FILE *file)
{
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
struct df_live_problem_data *problem_data;
if (!bb_info)
@@ -1741,7 +1742,7 @@ static const struct df_problem problem_LIVE =
df_live_verify_solution_start,/* Incremental solution verify start. */
df_live_verify_solution_end, /* Incremental solution verify end. */
&problem_LR, /* Dependent problem. */
- sizeof (struct df_live_bb_info),/* Size of entry of block_info array. */
+ sizeof (class df_live_bb_info),/* Size of entry of block_info array. */
TV_DF_LIVE, /* Timing variable. */
false /* Reset blocks on dropping out of blocks_to_analyze. */
};
@@ -1796,7 +1797,7 @@ df_live_verify_transfer_functions (void)
FOR_ALL_BB_FN (bb, cfun)
{
- struct df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
+ class df_live_bb_info *bb_info = df_live_get_bb_info (bb->index);
bitmap_set_bit (&all_blocks, bb->index);
if (bb_info)
@@ -1858,7 +1859,7 @@ static void
df_mir_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
void *vbb_info)
{
- struct df_mir_bb_info *bb_info = (struct df_mir_bb_info *) vbb_info;
+ class df_mir_bb_info *bb_info = (class df_mir_bb_info *) vbb_info;
if (bb_info)
{
bitmap_clear (&bb_info->gen);
@@ -1895,7 +1896,7 @@ df_mir_alloc (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
+ class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
/* When bitmaps are already initialized, just clear them. */
if (bb_info->kill.obstack)
@@ -1928,7 +1929,7 @@ df_mir_reset (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
+ class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
gcc_assert (bb_info);
@@ -1946,7 +1947,7 @@ static void
df_mir_bb_local_compute (unsigned int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
+ class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
rtx_insn *insn;
int luid = 0;
@@ -2010,7 +2011,7 @@ df_mir_init (bitmap all_blocks)
static void
df_mir_confluence_0 (basic_block bb)
{
- struct df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
+ class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
bitmap_clear (&bb_info->in);
}
@@ -2038,7 +2039,7 @@ df_mir_confluence_n (edge e)
static bool
df_mir_transfer_function (int bb_index)
{
- struct df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
+ class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb_index);
bitmap in = &bb_info->in;
bitmap out = &bb_info->out;
bitmap gen = &bb_info->gen;
@@ -2073,7 +2074,7 @@ df_mir_free (void)
static void
df_mir_top_dump (basic_block bb, FILE *file)
{
- struct df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
+ class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -2091,7 +2092,7 @@ df_mir_top_dump (basic_block bb, FILE *file)
static void
df_mir_bottom_dump (basic_block bb, FILE *file)
{
- struct df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
+ class df_mir_bb_info *bb_info = df_mir_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -2192,7 +2193,7 @@ static const struct df_problem problem_MIR =
df_mir_verify_solution_start, /* Incremental solution verify start. */
df_mir_verify_solution_end, /* Incremental solution verify end. */
NULL, /* Dependent problem. */
- sizeof (struct df_mir_bb_info),/* Size of entry of block_info array. */
+ sizeof (class df_mir_bb_info),/* Size of entry of block_info array. */
TV_DF_MIR, /* Timing variable. */
false /* Reset blocks on dropping out of blocks_to_analyze. */
};
@@ -2455,7 +2456,7 @@ static void
df_chain_create_bb (unsigned int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
+ class df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
rtx_insn *insn;
bitmap_head cpy;
@@ -2710,7 +2711,7 @@ static void
df_word_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
void *vbb_info)
{
- struct df_word_lr_bb_info *bb_info = (struct df_word_lr_bb_info *) vbb_info;
+ class df_word_lr_bb_info *bb_info = (class df_word_lr_bb_info *) vbb_info;
if (bb_info)
{
bitmap_clear (&bb_info->use);
@@ -2753,7 +2754,7 @@ df_word_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)
{
- struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
+ class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
/* When bitmaps are already initialized, just clear them. */
if (bb_info->use.obstack)
@@ -2784,7 +2785,7 @@ df_word_lr_reset (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
+ class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
gcc_assert (bb_info);
bitmap_clear (&bb_info->in);
bitmap_clear (&bb_info->out);
@@ -2850,7 +2851,7 @@ static void
df_word_lr_bb_local_compute (unsigned int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
+ class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
rtx_insn *insn;
df_ref def, use;
@@ -2917,7 +2918,7 @@ df_word_lr_init (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
+ class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
bitmap_copy (&bb_info->in, &bb_info->use);
bitmap_clear (&bb_info->out);
}
@@ -2941,7 +2942,7 @@ df_word_lr_confluence_n (edge e)
static bool
df_word_lr_transfer_function (int bb_index)
{
- struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
+ class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
bitmap in = &bb_info->in;
bitmap out = &bb_info->out;
bitmap use = &bb_info->use;
@@ -2978,7 +2979,7 @@ df_word_lr_free (void)
static void
df_word_lr_top_dump (basic_block bb, FILE *file)
{
- struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
+ class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -2996,7 +2997,7 @@ df_word_lr_top_dump (basic_block bb, FILE *file)
static void
df_word_lr_bottom_dump (basic_block bb, FILE *file)
{
- struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
+ class df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -3031,7 +3032,7 @@ static const struct df_problem problem_WORD_LR =
NULL, /* Incremental solution verify start. */
NULL, /* Incremental solution verify end. */
NULL, /* Dependent problem. */
- sizeof (struct df_word_lr_bb_info),/* Size of entry of block_info array. */
+ sizeof (class df_word_lr_bb_info),/* Size of entry of block_info array. */
TV_DF_WORD_LR, /* Timing variable. */
false /* Reset blocks on dropping out of blocks_to_analyze. */
};
@@ -4347,7 +4348,7 @@ static void
df_md_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
void *vbb_info)
{
- struct df_md_bb_info *bb_info = (struct df_md_bb_info *) vbb_info;
+ class df_md_bb_info *bb_info = (class df_md_bb_info *) vbb_info;
if (bb_info)
{
bitmap_clear (&bb_info->kill);
@@ -4382,7 +4383,7 @@ df_md_alloc (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
/* When bitmaps are already initialized, just clear them. */
if (bb_info->init.obstack)
{
@@ -4451,7 +4452,7 @@ df_md_simulate_one_insn (basic_block bb ATTRIBUTE_UNUSED, rtx_insn *insn,
}
static void
-df_md_bb_local_compute_process_def (struct df_md_bb_info *bb_info,
+df_md_bb_local_compute_process_def (class df_md_bb_info *bb_info,
df_ref def,
int top_flag)
{
@@ -4492,7 +4493,7 @@ static void
df_md_bb_local_compute (unsigned int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
rtx_insn *insn;
/* Artificials are only hard regs. */
@@ -4570,7 +4571,7 @@ df_md_reset (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
gcc_assert (bb_info);
bitmap_clear (&bb_info->in);
bitmap_clear (&bb_info->out);
@@ -4581,7 +4582,7 @@ static bool
df_md_transfer_function (int bb_index)
{
basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
bitmap in = &bb_info->in;
bitmap out = &bb_info->out;
bitmap gen = &bb_info->gen;
@@ -4609,7 +4610,7 @@ df_md_init (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
bitmap_copy (&bb_info->in, &bb_info->init);
df_md_transfer_function (bb_index);
@@ -4619,7 +4620,7 @@ df_md_init (bitmap all_blocks)
static void
df_md_confluence_0 (basic_block bb)
{
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
bitmap_copy (&bb_info->in, &bb_info->init);
}
@@ -4666,7 +4667,7 @@ df_md_free (void)
static void
df_md_top_dump (basic_block bb, FILE *file)
{
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -4685,7 +4686,7 @@ df_md_top_dump (basic_block bb, FILE *file)
static void
df_md_bottom_dump (basic_block bb, FILE *file)
{
- struct df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
+ class df_md_bb_info *bb_info = df_md_get_bb_info (bb->index);
if (!bb_info)
return;
@@ -4717,7 +4718,7 @@ static const struct df_problem problem_MD =
NULL, /* Incremental solution verify start. */
NULL, /* Incremental solution verify end. */
NULL, /* Dependent problem. */
- sizeof (struct df_md_bb_info),/* Size of entry of block_info array. */
+ sizeof (class df_md_bb_info),/* Size of entry of block_info array. */
TV_DF_MD, /* Timing variable. */
false /* Reset blocks on dropping out of blocks_to_analyze. */
};
diff --git a/gcc/df-scan.c b/gcc/df-scan.c
index 81e221e..03294a8 100644
--- a/gcc/df-scan.c
+++ b/gcc/df-scan.c
@@ -44,33 +44,34 @@ static HARD_REG_SET elim_reg_set;
/* Initialize ur_in and ur_out as if all hard registers were partially
available. */
-struct df_collection_rec
+class df_collection_rec
{
+public:
auto_vec<df_ref, 128> def_vec;
auto_vec<df_ref, 32> use_vec;
auto_vec<df_ref, 32> eq_use_vec;
auto_vec<df_mw_hardreg *, 32> mw_vec;
};
-static void df_ref_record (enum df_ref_class, struct df_collection_rec *,
+static void df_ref_record (enum df_ref_class, class df_collection_rec *,
rtx, rtx *,
basic_block, struct df_insn_info *,
enum df_ref_type, int ref_flags);
-static void df_def_record_1 (struct df_collection_rec *, rtx *,
+static void df_def_record_1 (class df_collection_rec *, rtx *,
basic_block, struct df_insn_info *,
int ref_flags);
-static void df_defs_record (struct df_collection_rec *, rtx,
+static void df_defs_record (class df_collection_rec *, rtx,
basic_block, struct df_insn_info *,
int ref_flags);
-static void df_uses_record (struct df_collection_rec *,
+static void df_uses_record (class df_collection_rec *,
rtx *, enum df_ref_type,
basic_block, struct df_insn_info *,
int ref_flags);
static void df_install_ref_incremental (df_ref);
-static void df_insn_refs_collect (struct df_collection_rec*,
+static void df_insn_refs_collect (class df_collection_rec*,
basic_block, struct df_insn_info *);
-static void df_canonize_collection_rec (struct df_collection_rec *);
+static void df_canonize_collection_rec (class df_collection_rec *);
static void df_get_regular_block_artificial_uses (bitmap);
static void df_get_eh_block_artificial_uses (bitmap);
@@ -83,13 +84,13 @@ static void df_grow_ref_info (struct df_ref_info *, unsigned int);
static void df_ref_chain_delete_du_chain (df_ref);
static void df_ref_chain_delete (df_ref);
-static void df_refs_add_to_chains (struct df_collection_rec *,
+static void df_refs_add_to_chains (class df_collection_rec *,
basic_block, rtx_insn *, unsigned int);
-static bool df_insn_refs_verify (struct df_collection_rec *, basic_block,
+static bool df_insn_refs_verify (class df_collection_rec *, basic_block,
rtx_insn *, bool);
-static void df_entry_block_defs_collect (struct df_collection_rec *, bitmap);
-static void df_exit_block_uses_collect (struct df_collection_rec *, bitmap);
+static void df_entry_block_defs_collect (class df_collection_rec *, bitmap);
+static void df_exit_block_uses_collect (class df_collection_rec *, bitmap);
static void df_install_ref (df_ref, struct df_reg_info *,
struct df_ref_info *, bool);
@@ -982,7 +983,7 @@ df_insn_delete (rtx_insn *insn)
/* Free all of the refs and the mw_hardregs in COLLECTION_REC. */
static void
-df_free_collection_rec (struct df_collection_rec *collection_rec)
+df_free_collection_rec (class df_collection_rec *collection_rec)
{
unsigned int ix;
struct df_scan_problem_data *problem_data
@@ -1013,7 +1014,7 @@ df_insn_rescan (rtx_insn *insn)
unsigned int uid = INSN_UID (insn);
struct df_insn_info *insn_info = NULL;
basic_block bb = BLOCK_FOR_INSN (insn);
- struct df_collection_rec collection_rec;
+ class df_collection_rec collection_rec;
if ((!df) || (!INSN_P (insn)))
return false;
@@ -1975,7 +1976,7 @@ df_notes_rescan (rtx_insn *insn)
{
basic_block bb = BLOCK_FOR_INSN (insn);
rtx note;
- struct df_collection_rec collection_rec;
+ class df_collection_rec collection_rec;
unsigned int i;
df_mw_hardreg_chain_delete_eq_uses (insn_info);
@@ -2268,7 +2269,7 @@ df_sort_and_compress_mws (vec<df_mw_hardreg *, va_heap> *mw_vec)
/* Sort and remove duplicates from the COLLECTION_REC. */
static void
-df_canonize_collection_rec (struct df_collection_rec *collection_rec)
+df_canonize_collection_rec (class df_collection_rec *collection_rec)
{
df_sort_and_compress_refs (&collection_rec->def_vec);
df_sort_and_compress_refs (&collection_rec->use_vec);
@@ -2404,7 +2405,7 @@ df_install_mws (const vec<df_mw_hardreg *, va_heap> *old_vec)
chains and update other necessary information. */
static void
-df_refs_add_to_chains (struct df_collection_rec *collection_rec,
+df_refs_add_to_chains (class df_collection_rec *collection_rec,
basic_block bb, rtx_insn *insn, unsigned int flags)
{
if (insn)
@@ -2466,7 +2467,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
static df_ref
df_ref_create_structure (enum df_ref_class cl,
- struct df_collection_rec *collection_rec,
+ class df_collection_rec *collection_rec,
rtx reg, rtx *loc,
basic_block bb, struct df_insn_info *info,
enum df_ref_type ref_type,
@@ -2552,7 +2553,7 @@ df_ref_create_structure (enum df_ref_class cl,
static void
df_ref_record (enum df_ref_class cl,
- struct df_collection_rec *collection_rec,
+ class df_collection_rec *collection_rec,
rtx reg, rtx *loc,
basic_block bb, struct df_insn_info *insn_info,
enum df_ref_type ref_type,
@@ -2624,7 +2625,7 @@ df_ref_record (enum df_ref_class cl,
Any change here has to be matched in df_find_hard_reg_defs_1. */
static void
-df_def_record_1 (struct df_collection_rec *collection_rec,
+df_def_record_1 (class df_collection_rec *collection_rec,
rtx *loc, basic_block bb, struct df_insn_info *insn_info,
int flags)
{
@@ -2689,7 +2690,7 @@ df_def_record_1 (struct df_collection_rec *collection_rec,
here has to be matched in df_find_hard_reg_defs. */
static void
-df_defs_record (struct df_collection_rec *collection_rec,
+df_defs_record (class df_collection_rec *collection_rec,
rtx x, basic_block bb, struct df_insn_info *insn_info,
int flags)
{
@@ -2795,7 +2796,7 @@ df_find_hard_reg_defs (rtx x, HARD_REG_SET *defs)
/* Process all the registers used in the rtx at address LOC. */
static void
-df_uses_record (struct df_collection_rec *collection_rec,
+df_uses_record (class df_collection_rec *collection_rec,
rtx *loc, enum df_ref_type ref_type,
basic_block bb, struct df_insn_info *insn_info,
int flags)
@@ -3054,7 +3055,7 @@ df_uses_record (struct df_collection_rec *collection_rec,
/* For all DF_REF_CONDITIONAL defs, add a corresponding uses. */
static void
-df_get_conditional_uses (struct df_collection_rec *collection_rec)
+df_get_conditional_uses (class df_collection_rec *collection_rec)
{
unsigned int ix;
df_ref ref;
@@ -3078,7 +3079,7 @@ df_get_conditional_uses (struct df_collection_rec *collection_rec)
/* Get call's extra defs and uses (track caller-saved registers). */
static void
-df_get_call_refs (struct df_collection_rec *collection_rec,
+df_get_call_refs (class df_collection_rec *collection_rec,
basic_block bb,
struct df_insn_info *insn_info,
int flags)
@@ -3161,7 +3162,7 @@ df_get_call_refs (struct df_collection_rec *collection_rec,
and reg chains. */
static void
-df_insn_refs_collect (struct df_collection_rec *collection_rec,
+df_insn_refs_collect (class df_collection_rec *collection_rec,
basic_block bb, struct df_insn_info *insn_info)
{
rtx note;
@@ -3257,7 +3258,7 @@ df_recompute_luids (basic_block bb)
to COLLECTION_REC. */
static void
-df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
+df_bb_refs_collect (class df_collection_rec *collection_rec, basic_block bb)
{
collection_rec->def_vec.truncate (0);
collection_rec->use_vec.truncate (0);
@@ -3557,7 +3558,7 @@ df_get_entry_block_def_set (bitmap entry_block_defs)
reference to include. */
static void
-df_entry_block_defs_collect (struct df_collection_rec *collection_rec,
+df_entry_block_defs_collect (class df_collection_rec *collection_rec,
bitmap entry_block_defs)
{
unsigned int i;
@@ -3579,7 +3580,7 @@ df_entry_block_defs_collect (struct df_collection_rec *collection_rec,
static void
df_record_entry_block_defs (bitmap entry_block_defs)
{
- struct df_collection_rec collection_rec;
+ class df_collection_rec collection_rec;
df_entry_block_defs_collect (&collection_rec, entry_block_defs);
/* Process bb_refs chain */
@@ -3714,7 +3715,7 @@ df_get_exit_block_use_set (bitmap exit_block_uses)
It uses df->exit_block_uses to determine register to include. */
static void
-df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exit_block_uses)
+df_exit_block_uses_collect (class df_collection_rec *collection_rec, bitmap exit_block_uses)
{
unsigned int i;
bitmap_iterator bi;
@@ -3743,7 +3744,7 @@ df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exi
static void
df_record_exit_block_uses (bitmap exit_block_uses)
{
- struct df_collection_rec collection_rec;
+ class df_collection_rec collection_rec;
df_exit_block_uses_collect (&collection_rec, exit_block_uses);
/* Process bb_refs chain */
@@ -4051,7 +4052,7 @@ df_mws_verify (const vec<df_mw_hardreg *, va_heap> *new_rec,
If ABORT_IF_FAIL is set, this function never returns false. */
static bool
-df_insn_refs_verify (struct df_collection_rec *collection_rec,
+df_insn_refs_verify (class df_collection_rec *collection_rec,
basic_block bb,
rtx_insn *insn,
bool abort_if_fail)
@@ -4092,7 +4093,7 @@ df_bb_verify (basic_block bb)
{
rtx_insn *insn;
struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
- struct df_collection_rec collection_rec;
+ class df_collection_rec collection_rec;
gcc_assert (bb_info);
diff --git a/gcc/df.h b/gcc/df.h
index d76d31b..2e3b825 100644
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
struct dataflow;
-struct df_d;
+class df_d;
struct df_problem;
struct df_link;
struct df_insn_info;
@@ -524,8 +524,9 @@ struct df_reg_info
used by owners of the problem.
----------------------------------------------------------------------------*/
-struct df_d
+class df_d
{
+public:
/* The set of problems to be solved is stored in two arrays. In
PROBLEMS_IN_ORDER, the problems are stored in the order that they
@@ -830,8 +831,9 @@ struct df_scan_bb_info
the ref except sparse_kill which is indexed by regno. For the
LR&RD problem, the kill set is not complete: It does not contain
DEFs killed because the set register has died in the LR set. */
-struct df_rd_bb_info
+class df_rd_bb_info
{
+public:
/* Local sets to describe the basic blocks. */
bitmap_head kill;
bitmap_head sparse_kill;
@@ -846,8 +848,9 @@ struct df_rd_bb_info
/* Multiple reaching definitions. All bitmaps are referenced by the
register number. */
-struct df_md_bb_info
+class df_md_bb_info
{
+public:
/* Local sets to describe the basic blocks. */
bitmap_head gen; /* Partial/conditional definitions live at BB out. */
bitmap_head kill; /* Other definitions that are live at BB out. */
@@ -862,8 +865,9 @@ struct df_md_bb_info
/* Live registers, a backwards dataflow problem. All bitmaps are
referenced by the register number. */
-struct df_lr_bb_info
+class df_lr_bb_info
{
+public:
/* Local sets to describe the basic blocks. */
bitmap_head def; /* The set of registers set in this block
- except artificial defs at the top. */
@@ -879,8 +883,9 @@ struct df_lr_bb_info
register number. Anded results of the forwards and backward live
info. Note that the forwards live information is not available
separately. */
-struct df_live_bb_info
+class df_live_bb_info
{
+public:
/* Local sets to describe the basic blocks. */
bitmap_head kill; /* The set of registers unset in this block. Calls,
for instance, unset registers. */
@@ -897,8 +902,9 @@ struct df_live_bb_info
pseudo. Only pseudos that have a size of 2 * UNITS_PER_WORD are
meaningfully tracked. */
-struct df_word_lr_bb_info
+class df_word_lr_bb_info
{
+public:
/* Local sets to describe the basic blocks. */
bitmap_head def; /* The set of registers set in this block
- except artificial defs at the top. */
@@ -911,8 +917,9 @@ struct df_word_lr_bb_info
/* Must-initialized registers. All bitmaps are referenced by the
register number. */
-struct df_mir_bb_info
+class df_mir_bb_info
{
+public:
/* Local sets to describe the basic blocks. */
bitmap_head kill; /* The set of registers unset in this block. Calls,
for instance, unset registers. */
@@ -928,7 +935,7 @@ struct df_mir_bb_info
/* This is used for debugging and for the dumpers to find the latest
instance so that the df info can be added to the dumps. This
should not be used by regular code. */
-extern struct df_d *df;
+extern class df_d *df;
#define df_scan (df->problems_by_index[DF_SCAN])
#define df_rd (df->problems_by_index[DF_RD])
#define df_lr (df->problems_by_index[DF_LR])
@@ -961,7 +968,7 @@ extern void df_remove_problem (struct dataflow *);
extern void df_finish_pass (bool);
extern void df_analyze_problem (struct dataflow *, bitmap, int *, int);
extern void df_analyze ();
-extern void df_analyze_loop (struct loop *);
+extern void df_analyze_loop (class loop *);
extern int df_get_n_blocks (enum df_flow_dir);
extern int *df_get_postorder (enum df_flow_dir);
extern void df_simple_dataflow (enum df_flow_dir, df_init_function,
@@ -1096,56 +1103,56 @@ df_scan_get_bb_info (unsigned int index)
return NULL;
}
-static inline struct df_rd_bb_info *
+static inline class df_rd_bb_info *
df_rd_get_bb_info (unsigned int index)
{
if (index < df_rd->block_info_size)
- return &((struct df_rd_bb_info *) df_rd->block_info)[index];
+ return &((class df_rd_bb_info *) df_rd->block_info)[index];
else
return NULL;
}
-static inline struct df_lr_bb_info *
+static inline class df_lr_bb_info *
df_lr_get_bb_info (unsigned int index)
{
if (index < df_lr->block_info_size)
- return &((struct df_lr_bb_info *) df_lr->block_info)[index];
+ return &((class df_lr_bb_info *) df_lr->block_info)[index];
else
return NULL;
}
-static inline struct df_md_bb_info *
+static inline class df_md_bb_info *
df_md_get_bb_info (unsigned int index)
{
if (index < df_md->block_info_size)
- return &((struct df_md_bb_info *) df_md->block_info)[index];
+ return &((class df_md_bb_info *) df_md->block_info)[index];
else
return NULL;
}
-static inline struct df_live_bb_info *
+static inline class df_live_bb_info *
df_live_get_bb_info (unsigned int index)
{
if (index < df_live->block_info_size)
- return &((struct df_live_bb_info *) df_live->block_info)[index];
+ return &((class df_live_bb_info *) df_live->block_info)[index];
else
return NULL;
}
-static inline struct df_word_lr_bb_info *
+static inline class df_word_lr_bb_info *
df_word_lr_get_bb_info (unsigned int index)
{
if (index < df_word_lr->block_info_size)
- return &((struct df_word_lr_bb_info *) df_word_lr->block_info)[index];
+ return &((class df_word_lr_bb_info *) df_word_lr->block_info)[index];
else
return NULL;
}
-static inline struct df_mir_bb_info *
+static inline class df_mir_bb_info *
df_mir_get_bb_info (unsigned int index)
{
if (index < df_mir->block_info_size)
- return &((struct df_mir_bb_info *) df_mir->block_info)[index];
+ return &((class df_mir_bb_info *) df_mir->block_info)[index];
else
return NULL;
}
@@ -1222,7 +1229,7 @@ df_single_use (const df_insn_info *info)
/* web */
-class web_entry_base
+struct web_entry_base
{
private:
/* Reference to the parent in the union/find tree. */
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index 89074be..4d563dd 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -164,8 +164,9 @@ struct line_bounds
splits the pertinent source lines into a list of disjoint line_span
instances (e.g. lines 5-10, lines 15-20, line 23). */
-struct line_span
+class line_span
{
+public:
line_span (linenum_type first_line, linenum_type last_line)
: m_first_line (first_line), m_last_line (last_line)
{
@@ -1409,8 +1410,9 @@ layout::print_annotation_line (linenum_type row, const line_bounds lbounds)
A label within the given row of source. */
-struct line_label
+class line_label
{
+public:
line_label (int state_idx, int column, label_text text)
: m_state_idx (state_idx), m_column (column),
m_text (text), m_length (strlen (text.m_buffer)),
@@ -1723,8 +1725,9 @@ layout::annotation_line_showed_range_p (linenum_type line, int start_column,
/* A range of columns within a line. */
-struct column_range
+class column_range
{
+public:
column_range (int start_, int finish_) : start (start_), finish (finish_)
{
/* We must have either a range, or an insertion. */
@@ -1776,8 +1779,9 @@ get_printed_columns (const fixit_hint *hint)
instances that affected the line, potentially consolidating hints
into corrections to make the result easier for the user to read. */
-struct correction
+class correction
{
+public:
correction (column_range affected_columns,
column_range printed_columns,
const char *new_text, size_t new_text_len)
@@ -1854,8 +1858,9 @@ correction::ensure_terminated ()
This is used by layout::print_trailing_fixits for planning
how to print the fix-it hints affecting the line. */
-struct line_corrections
+class line_corrections
{
+public:
line_corrections (const char *filename, linenum_type row)
: m_filename (filename), m_row (row)
{}
@@ -1881,8 +1886,9 @@ line_corrections::~line_corrections ()
/* A struct wrapping a particular source line, allowing
run-time bounds-checking of accesses in a checked build. */
-struct source_line
+class source_line
{
+public:
source_line (const char *filename, int line);
char_span as_span () { return char_span (chars, width); }
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index f2619e1..14b232b 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -13045,8 +13045,11 @@ when testing pointer or floating-point values.
For the purposes of branch prediction optimizations, the probability that
a @code{__builtin_expect} expression is @code{true} is controlled by GCC's
@code{builtin-expect-probability} parameter, which defaults to 90%.
+
You can also use @code{__builtin_expect_with_probability} to explicitly
-assign a probability value to individual expressions.
+assign a probability value to individual expressions. If the built-in
+is used in a loop construct, the provided probability will influence
+the expected number of iterations made by loop optimizations.
@end deftypefn
@deftypefn {Built-in Function} long __builtin_expect_with_probability
@@ -16845,6 +16848,7 @@ unsigned long __builtin_ppc_mftb ();
double __builtin_unpack_ibm128 (__ibm128, int);
__ibm128 __builtin_pack_ibm128 (double, double);
double __builtin_mffs (void);
+double __builtin_mtfsf (const int, double);
void __builtin_mtfsb0 (const int);
void __builtin_mtfsb1 (const int);
void __builtin_set_fpscr_rn (int);
@@ -16860,7 +16864,10 @@ the most significant word on 32-bit environments. The @code{__builtin_mffs}
return the value of the FPSCR register. Note, ISA 3.0 supports the
@code{__builtin_mffsl()} which permits software to read the control and
non-sticky status bits in the FSPCR without the higher latency associated with
-accessing the sticky status bits. The
+accessing the sticky status bits. The @code{__builtin_mtfsf} takes a constant
+8-bit integer field mask and a double precision floating point argument
+and generates the @code{mtfsf} (extended mnemonic) instruction to write new
+values to selected fields of the FPSCR. The
@code{__builtin_mtfsb0} and @code{__builtin_mtfsb1} take the bit to change
as an argument. The valid bit range is between 0 and 31. The builtins map to
the @code{mtfsb0} and @code{mtfsb1} instructions which take the argument and
diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi
index 67f7ad5..8901d5f 100644
--- a/gcc/doc/generic.texi
+++ b/gcc/doc/generic.texi
@@ -2180,6 +2180,11 @@ After the second sequence is executed, if it completes normally by
falling off the end, execution continues wherever the first sequence
would have continued, by falling off the end, or doing a goto, etc.
+If the second sequence is an @code{EH_ELSE_EXPR} selector, then the
+sequence in its first operand is used when the first sequence completes
+normally, and that in its second operand is used for exceptional
+cleanups, i.e., when an exception propagates out of the first sequence.
+
@code{TRY_FINALLY_EXPR} complicates the flow graph, since the cleanup
needs to appear on every edge out of the controlled block; this
reduces the freedom to move code across these edges. Therefore, the
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 852aa8f..2598713 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -2535,6 +2535,7 @@ Removes any @option{-O}-started option from @code{BOOT_CFLAGS}, and adds
@samp{BOOT_CFLAGS='-g -O1'}.
@item @samp{bootstrap-O3}
+@itemx @samp{bootstrap-Og}
Analogous to @code{bootstrap-O1}.
@item @samp{bootstrap-lto}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 73d16b5..77a2d56 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -467,7 +467,7 @@ Objective-C and Objective-C++ Dialects}.
-fsignaling-nans @gol
-fsingle-precision-constant -fsplit-ivs-in-unroller -fsplit-loops@gol
-fsplit-paths @gol
--fsplit-wide-types -fssa-backprop -fssa-phiopt @gol
+-fsplit-wide-types -fsplit-wide-types-early -fssa-backprop -fssa-phiopt @gol
-fstdarg-opt -fstore-merging -fstrict-aliasing @gol
-fthread-jumps -ftracer -ftree-bit-ccp @gol
-ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol
@@ -1034,7 +1034,8 @@ Objective-C and Objective-C++ Dialects}.
@emph{OpenRISC Options}
@gccoptlist{-mboard=@var{name} -mnewlib -mhard-mul -mhard-div @gol
-msoft-mul -msoft-div @gol
--mcmov -mror -msext -msfimm -mshftimm}
+-msoft-float -mhard-float -mdouble-float -munordered-float @gol
+-mcmov -mror -mrori -msext -msfimm -mshftimm}
@emph{PDP-11 Options}
@gccoptlist{-mfpu -msoft-float -mac0 -mno-ac0 -m40 -m45 -m10 @gol
@@ -1067,7 +1068,8 @@ See RS/6000 and PowerPC Options.
-mcmodel=medlow -mcmodel=medany @gol
-mexplicit-relocs -mno-explicit-relocs @gol
-mrelax -mno-relax @gol
--mriscv-attribute -mmo-riscv-attribute}
+-mriscv-attribute -mmo-riscv-attribute @gol
+-malign-data=@var{type}}
@emph{RL78 Options}
@gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol
@@ -8731,6 +8733,13 @@ but may make debugging more difficult.
Enabled at levels @option{-O}, @option{-O2}, @option{-O3},
@option{-Os}.
+@item -fsplit-wide-types-early
+@opindex fsplit-wide-types-early
+Fully split wide types early, instead of very late.
+This option has no effect unless @option{-fsplit-wide-types} is turned on.
+
+This is the default on some targets.
+
@item -fcse-follow-jumps
@opindex fcse-follow-jumps
In common subexpression elimination (CSE), scan through jump instructions
@@ -11888,12 +11897,6 @@ of iterations of a loop known, it adds a bonus of
@option{ipa-cp-loop-hint-bonus} to the profitability score of
the candidate.
-@item ipa-cp-array-index-hint-bonus
-When IPA-CP determines that a cloning candidate would make the index of
-an array access known, it adds a bonus of
-@option{ipa-cp-array-index-hint-bonus} to the profitability
-score of the candidate.
-
@item ipa-max-aa-steps
During its analysis of function bodies, IPA-CP employs alias analysis
in order to track values pointed to by function parameters. In order
@@ -12218,6 +12221,13 @@ before the loop versioning pass considers it too big to copy,
discounting any instructions in inner loops that directly benefit
from versioning.
+@item ssa-name-def-chain-limit
+The maximum number of SSA_NAME assignments to follow in determining
+a property of a variable such as its value. This limits the number
+of iterations or recursive calls GCC performs when optimizing certain
+statements or when determining their validity prior to issuing
+diagnostics.
+
@end table
@end table
@@ -12369,7 +12379,7 @@ profile data file appears in the same directory as the object file.
In order to prevent the file name clashing, if the object file name is
not an absolute path, we mangle the absolute path of the
@file{@var{sourcename}.gcda} file and use it as the file name of a
-@file{.gcda} file.
+@file{.gcda} file. See similar option @option{-fprofile-note}.
When an executable is run in a massive parallel environment, it is recommended
to save profile to different folders. That can be done with variables
@@ -12407,7 +12417,9 @@ To optimize the program based on the collected profile information, use
@item -fprofile-note=@var{path}
@opindex fprofile-note
-If @var{path} is specified, GCC saves gcno filename into @var{path} location.
+If @var{path} is specified, GCC saves @file{.gcno} file into @var{path}
+location. If you combine the option with multiple source files,
+the @file{.gcno} file will be overwritten.
@item -fprofile-update=@var{method}
@opindex fprofile-update
@@ -16073,7 +16085,7 @@ not affect code generation. This option is enabled by default for
@item sve2
Enable the Armv8-a Scalable Vector Extension 2. This also enables SVE
instructions.
-@item bitperm
+@item sve2-bitperm
Enable SVE2 bitperm instructions. This also enables SVE2 instructions.
@item sve2-sm4
Enable SVE2 sm4 instructions. This also enables SVE2 instructions.
@@ -23639,50 +23651,76 @@ newlib board library linking. The default is @code{or1ksim}.
@item -mnewlib
@opindex mnewlib
-For compatibility, it's always newlib for elf now.
+This option is ignored; it is for compatibility purposes only. This used to
+select linker and preprocessor options for use with newlib.
-@item -mhard-div
+@item -msoft-div
+@itemx -mhard-div
+@opindex msoft-div
@opindex mhard-div
-Generate code for hardware which supports divide instructions. This is the
-default.
+Select software or hardware divide (@code{l.div}, @code{l.divu}) instructions.
+This default is hardware divide.
-@item -mhard-mul
+@item -msoft-mul
+@itemx -mhard-mul
+@opindex msoft-mul
@opindex mhard-mul
-Generate code for hardware which supports multiply instructions. This is the
-default.
+Select software or hardware multiply (@code{l.mul}, @code{l.muli}) instructions.
+This default is hardware multiply.
+
+@item -msoft-float
+@itemx -mhard-float
+@opindex msoft-float
+@opindex mhard-float
+Select software or hardware for floating point operations.
+The default is software.
+
+@item -mdouble-float
+@opindex mdouble-float
+When @option{-mhard-float} is selected, enables generation of double-precision
+floating point instructions. By default functions from @file{libgcc} are used
+to perform double-precision floating point operations.
+
+@item -munordered-float
+@opindex munordered-float
+When @option{-mhard-float} is selected, enables generation of unordered
+floating point compare and set flag (@code{lf.sfun*}) instructions. By default
+functions from @file{libgcc} are used to perform unordered floating point
+compare and set flag operations.
@item -mcmov
@opindex mcmov
-Generate code for hardware which supports the conditional move (@code{l.cmov})
-instruction.
+Enable generation of conditional move (@code{l.cmov}) instructions. By
+default the equivalent will be generated using using set and branch.
@item -mror
@opindex mror
-Generate code for hardware which supports rotate right instructions.
+Enable generation of rotate right (@code{l.ror}) instructions. By default
+functions from @file{libgcc} are used to perform rotate right operations.
+
+@item -mrori
+@opindex mrori
+Enable generation of rotate right with immediate (@code{l.rori}) instructions.
+By default functions from @file{libgcc} are used to perform rotate right with
+immediate operations.
@item -msext
@opindex msext
-Generate code for hardware which supports sign-extension instructions.
+Enable generation of sign extension (@code{l.ext*}) instructions. By default
+memory loads are used to perform sign extension.
@item -msfimm
@opindex msfimm
-Generate code for hardware which supports set flag immediate (@code{l.sf*i})
-instructions.
+Enable generation of compare and set flag with immediate (@code{l.sf*i})
+instructions. By default extra instructions will be generated to store the
+immediate to a register first.
@item -mshftimm
@opindex mshftimm
-Generate code for hardware which supports shift immediate related instructions
-(i.e. @code{l.srai}, @code{l.srli}, @code{l.slli}, @code{1.rori}). Note, to
-enable generation of the @code{l.rori} instruction the @option{-mror} flag must
-also be specified.
+Enable generation of shift with immediate (@code{l.srai}, @code{l.srli},
+@code{l.slli}) instructions. By default extra instructions will be generated
+to store the immediate to a register first.
-@item -msoft-div
-@opindex msoft-div
-Generate code for hardware which requires divide instruction emulation.
-
-@item -msoft-mul
-@opindex msoft-mul
-Generate code for hardware which requires multiply instruction emulation.
@end table
@@ -24002,6 +24040,13 @@ linker relaxations.
@itemx -mno-emit-attribute
Emit (do not emit) RISC-V attribute to record extra information into ELF
objects. This feature requires at least binutils 2.32.
+
+@item -malign-data=@var{type}
+@opindex malign-data
+Control how GCC aligns variables and constants of array, structure, or union
+types. Supported values for @var{type} are @samp{xlen} which uses x register
+width as the alignment value, and @samp{natural} which uses natural alignment.
+@samp{xlen} is the default.
@end table
@node RL78 Options
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index b1fcc38..af216da 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -11381,4 +11381,13 @@ name and same types of iterator. For example:
would produce a single set of functions that handles both
@code{INTEGER_MODES} and @code{FLOAT_MODES}.
+It is also possible for these @samp{@@} patterns to have different
+numbers of operands from each other. For example, patterns with
+a binary rtl code might take three operands (one output and two inputs)
+while patterns with a ternary rtl code might take four operands (one
+output and three inputs). This combination would produce separate
+@samp{maybe_gen_@var{name}} and @samp{gen_@var{name}} functions for
+each operand count, but it would still produce a single
+@samp{maybe_code_for_@var{name}} and a single @samp{code_for_@var{name}}.
+
@end ifset
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 14c1ea6..8e5b01c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4301,7 +4301,7 @@ with machine mode @var{mode}. The default version of this
hook returns true for both @code{ptr_mode} and @code{Pmode}.
@end deftypefn
-@deftypefn {Target Hook} bool TARGET_REF_MAY_ALIAS_ERRNO (struct ao_ref *@var{ref})
+@deftypefn {Target Hook} bool TARGET_REF_MAY_ALIAS_ERRNO (ao_ref *@var{ref})
Define this to return nonzero if the memory reference @var{ref} may alias with the system C library errno location. The default version of this hook assumes the system C library errno location is either a declaration of type int or accessed by dereferencing a pointer to int.
@end deftypefn
@@ -6052,11 +6052,11 @@ type @code{internal_fn}) should be considered expensive when the mask is
all zeros. GCC can then try to branch around the instruction instead.
@end deftypefn
-@deftypefn {Target Hook} {void *} TARGET_VECTORIZE_INIT_COST (struct loop *@var{loop_info})
+@deftypefn {Target Hook} {void *} TARGET_VECTORIZE_INIT_COST (class loop *@var{loop_info})
This hook should initialize target-specific data structures in preparation for modeling the costs of vectorizing a loop or basic block. The default allocates three unsigned integers for accumulating costs for the prologue, body, and epilogue of the loop or basic block. If @var{loop_info} is non-NULL, it identifies the loop being vectorized; otherwise a single block is being vectorized.
@end deftypefn
-@deftypefn {Target Hook} unsigned TARGET_VECTORIZE_ADD_STMT_COST (void *@var{data}, int @var{count}, enum vect_cost_for_stmt @var{kind}, struct _stmt_vec_info *@var{stmt_info}, int @var{misalign}, enum vect_cost_model_location @var{where})
+@deftypefn {Target Hook} unsigned TARGET_VECTORIZE_ADD_STMT_COST (void *@var{data}, int @var{count}, enum vect_cost_for_stmt @var{kind}, class _stmt_vec_info *@var{stmt_info}, int @var{misalign}, enum vect_cost_model_location @var{where})
This hook should update the target-specific @var{data} in response to adding @var{count} copies of the given @var{kind} of statement to a loop or basic block. The default adds the builtin vectorizer cost for the copies of the statement to the accumulator specified by @var{where}, (the prologue, body, or epilogue) and returns the amount added. The return value should be viewed as a tentative cost that may later be revised.
@end deftypefn
@@ -11610,7 +11610,7 @@ function version at run-time for a given set of function versions.
body must be generated.
@end deftypefn
-@deftypefn {Target Hook} bool TARGET_PREDICT_DOLOOP_P (struct loop *@var{loop})
+@deftypefn {Target Hook} bool TARGET_PREDICT_DOLOOP_P (class loop *@var{loop})
Return true if we can predict it is possible to use a low-overhead loop
for a particular loop. The parameter @var{loop} is a pointer to the loop.
This target hook is required only when the target supports low-overhead
@@ -11815,7 +11815,7 @@ This function prepares to emit a conditional comparison within a sequence
@var{bit_code} is @code{AND} or @code{IOR}, which is the op on the compares.
@end deftypefn
-@deftypefn {Target Hook} unsigned TARGET_LOOP_UNROLL_ADJUST (unsigned @var{nunroll}, struct loop *@var{loop})
+@deftypefn {Target Hook} unsigned TARGET_LOOP_UNROLL_ADJUST (unsigned @var{nunroll}, class loop *@var{loop})
This target hook returns a new value for the number of times @var{loop}
should be unrolled. The parameter @var{nunroll} is the number of times
the loop is to be unrolled. The parameter @var{loop} is a pointer to
diff --git a/gcc/dojump.h b/gcc/dojump.h
index ad01929..f4dbc11 100644
--- a/gcc/dojump.h
+++ b/gcc/dojump.h
@@ -37,8 +37,9 @@ extern void do_pending_stack_adjust (void);
/* Struct for saving/restoring of pending_stack_adjust/stack_pointer_delta
values. */
-struct saved_pending_stack_adjust
+class saved_pending_stack_adjust
{
+public:
/* Saved value of pending_stack_adjust. */
poly_int64 x_pending_stack_adjust;
diff --git a/gcc/dse.c b/gcc/dse.c
index 6f6f768..8d7358d 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -220,8 +220,9 @@ static bitmap scratch = NULL;
struct insn_info_type;
/* This structure holds information about a candidate store. */
-struct store_info
+class store_info
{
+public:
/* False means this is a clobber. */
bool is_set;
@@ -277,7 +278,7 @@ struct store_info
} positions_needed;
/* The next store info for this insn. */
- struct store_info *next;
+ class store_info *next;
/* The right hand side of the store. This is used if there is a
subsequent reload of the mems address somewhere later in the
@@ -309,8 +310,9 @@ static object_allocator<store_info> rtx_store_info_pool ("rtx_store_info_pool");
/* This structure holds information about a load. These are only
built for rtx bases. */
-struct read_info_type
+class read_info_type
{
+public:
/* The id of the mem group of the base address. */
int group_id;
@@ -324,9 +326,9 @@ struct read_info_type
rtx mem;
/* The next read_info for this insn. */
- struct read_info_type *next;
+ class read_info_type *next;
};
-typedef struct read_info_type *read_info_t;
+typedef class read_info_type *read_info_t;
static object_allocator<read_info_type> read_info_type_pool ("read_info_pool");
@@ -1507,7 +1509,7 @@ record_store (rtx body, bb_info_t bb_info)
while (ptr)
{
insn_info_t next = ptr->next_local_store;
- struct store_info *s_info = ptr->store_rec;
+ class store_info *s_info = ptr->store_rec;
bool del = true;
/* Skip the clobbers. We delete the active insn if this insn
@@ -3619,7 +3621,10 @@ rest_of_handle_dse (void)
if ((locally_deleted || globally_deleted)
&& cfun->can_throw_non_call_exceptions
&& purge_all_dead_edges ())
- cleanup_cfg (0);
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ cleanup_cfg (0);
+ }
return 0;
}
diff --git a/gcc/dump-context.h b/gcc/dump-context.h
index b17b86a..bb856c6 100644
--- a/gcc/dump-context.h
+++ b/gcc/dump-context.h
@@ -166,8 +166,9 @@ public:
private:
/* Information on an optinfo_item that was generated during phase 2 of
formatting. */
- struct stashed_item
+ class stashed_item
{
+ public:
stashed_item (const char **buffer_ptr_, optinfo_item *item_)
: buffer_ptr (buffer_ptr_), item (item_) {}
const char **buffer_ptr;
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index 9bcaa25..ad8bcb2 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -367,8 +367,9 @@ class dump_user_location_t
/* A class for identifying where in the compiler's own source
(or a plugin) that a dump message is being emitted from. */
-struct dump_impl_location_t
+class dump_impl_location_t
{
+public:
dump_impl_location_t (
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
const char *file = __builtin_FILE (),
@@ -647,7 +648,7 @@ extern void dump_combine_total_stats (FILE *);
/* In cfghooks.c */
extern void dump_bb (FILE *, basic_block, int, dump_flags_t);
-struct opt_pass;
+class opt_pass;
namespace gcc {
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 2c4cc6c..aa7fd7e 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3104,7 +3104,8 @@ die_node;
/* Set to TRUE while dwarf2out_early_global_decl is running. */
static bool early_dwarf;
static bool early_dwarf_finished;
-struct set_early_dwarf {
+class set_early_dwarf {
+public:
bool saved;
set_early_dwarf () : saved(early_dwarf)
{
@@ -24459,6 +24460,13 @@ gen_producer_string (void)
case OPT_fchecking_:
/* Ignore these. */
continue;
+ case OPT_flto_:
+ {
+ const char *lto_canonical = "-flto";
+ switches.safe_push (lto_canonical);
+ len += strlen (lto_canonical) + 1;
+ break;
+ }
default:
if (cl_options[save_decoded_options[j].opt_index].flags
& CL_NO_DWARF_RECORD)
diff --git a/gcc/edit-context.c b/gcc/edit-context.c
index 93d1066..4cd26c9 100644
--- a/gcc/edit-context.c
+++ b/gcc/edit-context.c
@@ -48,8 +48,9 @@ class line_event;
/* A struct to hold the params of a print_diff call. */
-struct diff
+class diff
{
+public:
diff (pretty_printer *pp, bool show_filenames)
: m_pp (pp), m_show_filenames (show_filenames) {}
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index e265fa6..a667cda 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -351,7 +351,7 @@ const_fixed_hasher::equal (rtx x, rtx y)
/* Return true if the given memory attributes are equal. */
bool
-mem_attrs_eq_p (const struct mem_attrs *p, const struct mem_attrs *q)
+mem_attrs_eq_p (const class mem_attrs *p, const class mem_attrs *q)
{
if (p == q)
return true;
@@ -1924,7 +1924,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
{
poly_int64 apply_bitpos = 0;
tree type;
- struct mem_attrs attrs, *defattrs, *refattrs;
+ class mem_attrs attrs, *defattrs, *refattrs;
addr_space_t as;
/* It can happen that type_for_mode was given a mode for which there
@@ -2334,7 +2334,7 @@ change_address (rtx memref, machine_mode mode, rtx addr)
{
rtx new_rtx = change_address_1 (memref, mode, addr, 1, false);
machine_mode mmode = GET_MODE (new_rtx);
- struct mem_attrs *defattrs;
+ class mem_attrs *defattrs;
mem_attrs attrs (*get_mem_attrs (memref));
defattrs = mode_mem_attrs[(int) mmode];
@@ -2378,7 +2378,7 @@ adjust_address_1 (rtx memref, machine_mode mode, poly_int64 offset,
rtx addr = XEXP (memref, 0);
rtx new_rtx;
scalar_int_mode address_mode;
- struct mem_attrs attrs (*get_mem_attrs (memref)), *defattrs;
+ class mem_attrs attrs (*get_mem_attrs (memref)), *defattrs;
unsigned HOST_WIDE_INT max_align;
#ifdef POINTERS_EXTEND_UNSIGNED
scalar_int_mode pointer_mode
@@ -2524,7 +2524,7 @@ offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
{
rtx new_rtx, addr = XEXP (memref, 0);
machine_mode address_mode;
- struct mem_attrs *defattrs;
+ class mem_attrs *defattrs;
mem_attrs attrs (*get_mem_attrs (memref));
address_mode = get_address_mode (memref);
@@ -6582,6 +6582,18 @@ curr_insn_location (void)
return curr_location;
}
+/* Set the location of the insn chain starting at INSN to LOC. */
+void
+set_insn_locations (rtx_insn *insn, location_t loc)
+{
+ while (insn)
+ {
+ if (INSN_P (insn))
+ INSN_LOCATION (insn) = loc;
+ insn = NEXT_INSN (insn);
+ }
+}
+
/* Return lexical scope block insn belongs to. */
tree
insn_scope (const rtx_insn *insn)
diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h
index 7b1cecd..7643bf9 100644
--- a/gcc/emit-rtl.h
+++ b/gcc/emit-rtl.h
@@ -20,8 +20,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_EMIT_RTL_H
#define GCC_EMIT_RTL_H
-struct temp_slot;
-typedef struct temp_slot *temp_slot_p;
+class temp_slot;
+typedef class temp_slot *temp_slot_p;
/* Information mainlined about RTL representation of incoming arguments. */
struct GTY(()) incoming_args {
@@ -110,7 +110,7 @@ struct GTY(()) rtl_data {
vec<rtx, va_gc> *x_stack_slot_list;
/* List of empty areas in the stack frame. */
- struct frame_space *frame_space_list;
+ class frame_space *frame_space_list;
/* Place after which to insert the tail_recursion_label if we need one. */
rtx_note *x_stack_check_probe_note;
@@ -136,7 +136,7 @@ struct GTY(()) rtl_data {
vec<temp_slot_p, va_gc> *x_used_temp_slots;
/* List of available temp slots. */
- struct temp_slot *x_avail_temp_slots;
+ class temp_slot *x_avail_temp_slots;
/* Current nesting level for temporaries. */
int x_temp_slot_level;
@@ -319,7 +319,7 @@ extern GTY(()) struct rtl_data x_rtl;
#define crtl (&x_rtl)
/* Return whether two MEM_ATTRs are equal. */
-bool mem_attrs_eq_p (const struct mem_attrs *, const struct mem_attrs *);
+bool mem_attrs_eq_p (const class mem_attrs *, const class mem_attrs *);
/* Set the alias set of MEM to SET. */
extern void set_mem_alias_set (rtx, alias_set_type);
diff --git a/gcc/except.c b/gcc/except.c
index edaeeb4..1e6f8af 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -27,14 +27,14 @@ along with GCC; see the file COPYING3. If not see
the compilation process:
In the beginning, in the front end, we have the GENERIC trees
- TRY_CATCH_EXPR, TRY_FINALLY_EXPR, WITH_CLEANUP_EXPR,
+ TRY_CATCH_EXPR, TRY_FINALLY_EXPR, EH_ELSE_EXPR, WITH_CLEANUP_EXPR,
CLEANUP_POINT_EXPR, CATCH_EXPR, and EH_FILTER_EXPR.
- During initial gimplification (gimplify.c) these are lowered
- to the GIMPLE_TRY, GIMPLE_CATCH, and GIMPLE_EH_FILTER nodes.
- The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are converted
- into GIMPLE_TRY_FINALLY nodes; the others are a more direct 1-1
- conversion.
+ During initial gimplification (gimplify.c) these are lowered to the
+ GIMPLE_TRY, GIMPLE_CATCH, GIMPLE_EH_ELSE, and GIMPLE_EH_FILTER
+ nodes. The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are
+ converted into GIMPLE_TRY_FINALLY nodes; the others are a more
+ direct 1-1 conversion.
During pass_lower_eh (tree-eh.c) we record the nested structure
of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE.
@@ -921,7 +921,7 @@ assign_filter_values (void)
static basic_block
emit_to_new_bb_before (rtx_insn *seq, rtx_insn *insn)
{
- rtx_insn *last;
+ rtx_insn *next, *last;
basic_block bb;
edge e;
edge_iterator ei;
@@ -934,7 +934,16 @@ emit_to_new_bb_before (rtx_insn *seq, rtx_insn *insn)
force_nonfallthru (e);
else
ei_next (&ei);
- last = emit_insn_before (seq, insn);
+
+ /* Make sure to put the location of INSN or a subsequent instruction on SEQ
+ to avoid inheriting the location of the previous instruction. */
+ next = insn;
+ while (next && !NONDEBUG_INSN_P (next))
+ next = NEXT_INSN (next);
+ if (next)
+ last = emit_insn_before_setloc (seq, insn, INSN_LOCATION (next));
+ else
+ last = emit_insn_before (seq, insn);
if (BARRIER_P (last))
last = PREV_INSN (last);
bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
@@ -1006,7 +1015,7 @@ dw2_build_landing_pads (void)
make_single_succ_edge (bb, bb->next_bb, e_flags);
if (current_loops)
{
- struct loop *loop = bb->next_bb->loop_father;
+ class loop *loop = bb->next_bb->loop_father;
/* If we created a pre-header block, add the new block to the
outer loop, otherwise to the loop itself. */
if (bb->next_bb == loop->header)
@@ -1380,7 +1389,7 @@ sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU);
if (current_loops)
{
- struct loop *loop = bb->next_bb->loop_father;
+ class loop *loop = bb->next_bb->loop_father;
/* If we created a pre-header block, add the new block to the
outer loop, otherwise to the loop itself. */
if (bb->next_bb == loop->header)
@@ -1418,7 +1427,7 @@ sjlj_emit_dispatch_table (rtx_code_label *dispatch_label, int num_dispatch)
make_single_succ_edge (bb, bb->next_bb, EDGE_FALLTHRU);
if (current_loops)
{
- struct loop *loop = bb->next_bb->loop_father;
+ class loop *loop = bb->next_bb->loop_father;
/* If we created a pre-header block, add the new block to the
outer loop, otherwise to the loop itself. */
if (bb->next_bb == loop->header)
diff --git a/gcc/explow.c b/gcc/explow.c
index ba06458..7eb854b 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -892,16 +892,7 @@ promote_ssa_mode (const_tree name, int *punsignedp)
tree type = TREE_TYPE (name);
int unsignedp = TYPE_UNSIGNED (type);
- machine_mode mode = TYPE_MODE (type);
-
- /* Bypass TYPE_MODE when it maps vector modes to BLKmode. */
- if (mode == BLKmode)
- {
- gcc_assert (VECTOR_TYPE_P (type));
- mode = type->type_common.mode;
- }
-
- machine_mode pmode = promote_mode (type, mode, &unsignedp);
+ machine_mode pmode = promote_mode (type, TYPE_MODE (type), &unsignedp);
if (punsignedp)
*punsignedp = unsignedp;
@@ -1498,7 +1489,7 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
stack pointer, such as acquiring the space by calling malloc(). */
if (targetm.have_allocate_stack ())
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
/* We don't have to check against the predicate for operand 0 since
TARGET is known to be a pseudo of the proper mode, which must
be valid for the operand. */
@@ -1629,7 +1620,7 @@ emit_stack_probe (rtx address)
{
if (targetm.have_probe_stack_address ())
{
- struct expand_operand ops[1];
+ class expand_operand ops[1];
insn_code icode = targetm.code_for_probe_stack_address;
create_address_operand (ops, address);
maybe_legitimize_operands (icode, 0, 1, ops);
@@ -1689,7 +1680,7 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
/* Next see if we have an insn to check the stack. */
else if (targetm.have_check_stack ())
{
- struct expand_operand ops[1];
+ class expand_operand ops[1];
rtx addr = memory_address (Pmode,
gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
stack_pointer_rtx,
diff --git a/gcc/expmed.c b/gcc/expmed.c
index d7f8e9a..c582f3a 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -599,7 +599,7 @@ store_bit_field_using_insv (const extraction_insn *insv, rtx op0,
unsigned HOST_WIDE_INT bitnum,
rtx value, scalar_int_mode value_mode)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
rtx value1;
rtx xop0 = op0;
rtx_insn *last = get_last_insn ();
@@ -759,7 +759,7 @@ store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
&& known_eq (bitsize, GET_MODE_BITSIZE (innermode))
&& multiple_p (bitnum, GET_MODE_BITSIZE (innermode), &pos))
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
enum insn_code icode = optab_handler (vec_set_optab, outermode);
create_fixed_operand (&ops[0], op0);
@@ -870,7 +870,7 @@ store_integral_bit_field (rtx op0, opt_scalar_int_mode op0_mode,
&& known_eq (bitsize, GET_MODE_BITSIZE (fieldmode))
&& optab_handler (movstrict_optab, fieldmode) != CODE_FOR_nothing)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
enum insn_code icode = optab_handler (movstrict_optab, fieldmode);
rtx arg0 = op0;
unsigned HOST_WIDE_INT subreg_off;
@@ -1499,7 +1499,7 @@ extract_bit_field_using_extv (const extraction_insn *extv, rtx op0,
int unsignedp, rtx target,
machine_mode mode, machine_mode tmode)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
rtx spec_target = target;
rtx spec_target_subreg = 0;
scalar_int_mode ext_mode = extv->field_mode;
@@ -1655,7 +1655,7 @@ extract_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
!= CODE_FOR_nothing)
&& multiple_p (bitnum, GET_MODE_BITSIZE (tmode), &pos))
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
machine_mode outermode = new_mode;
machine_mode innermode = tmode;
enum insn_code icode
@@ -1722,7 +1722,7 @@ extract_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
&& known_eq (bitsize, GET_MODE_BITSIZE (innermode))
&& multiple_p (bitnum, GET_MODE_BITSIZE (innermode), &pos))
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
create_output_operand (&ops[0], target, innermode);
ops[0].target = 1;
@@ -5428,7 +5428,7 @@ emit_cstore (rtx target, enum insn_code icode, enum rtx_code code,
int unsignedp, rtx x, rtx y, int normalizep,
machine_mode target_mode)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
rtx op0, comparison, subtarget;
rtx_insn *last;
scalar_int_mode result_mode = targetm.cstore_mode (icode);
diff --git a/gcc/expr.c b/gcc/expr.c
index 4acf250..20e3f9c 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1732,8 +1732,6 @@ emit_block_move_via_cpymem (rtx x, rtx y, rtx size, unsigned int align,
unsigned HOST_WIDE_INT max_size,
unsigned HOST_WIDE_INT probable_max_size)
{
- int save_volatile_ok = volatile_ok;
-
if (expected_align < align)
expected_align = align;
if (expected_size != -1)
@@ -1745,7 +1743,7 @@ emit_block_move_via_cpymem (rtx x, rtx y, rtx size, unsigned int align,
}
/* Since this is a move insn, we don't care about volatility. */
- volatile_ok = 1;
+ temporary_volatile_ok v (true);
/* Try the most limited insn first, because there's no point
including more than one in the machine description unless
@@ -1769,7 +1767,7 @@ emit_block_move_via_cpymem (rtx x, rtx y, rtx size, unsigned int align,
|| max_size <= (GET_MODE_MASK (mode) >> 1)
|| GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
{
- struct expand_operand ops[9];
+ class expand_operand ops[9];
unsigned int nops;
/* ??? When called via emit_block_move_for_call, it'd be
@@ -1809,14 +1807,10 @@ emit_block_move_via_cpymem (rtx x, rtx y, rtx size, unsigned int align,
create_fixed_operand (&ops[8], NULL);
}
if (maybe_expand_insn (code, nops, ops))
- {
- volatile_ok = save_volatile_ok;
- return true;
- }
+ return true;
}
}
- volatile_ok = save_volatile_ok;
return false;
}
@@ -1932,7 +1926,7 @@ expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx,
if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
target = NULL_RTX;
- struct expand_operand ops[5];
+ class expand_operand ops[5];
create_output_operand (&ops[0], target, insn_mode);
create_fixed_operand (&ops[1], arg1_rtx);
create_fixed_operand (&ops[2], arg2_rtx);
@@ -3137,7 +3131,7 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
|| max_size <= (GET_MODE_MASK (mode) >> 1)
|| GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
{
- struct expand_operand ops[9];
+ class expand_operand ops[9];
unsigned int nops;
nops = insn_data[(int) code].n_generator_args;
@@ -4181,7 +4175,7 @@ emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
icode = optab_handler (push_optab, mode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[1];
+ class expand_operand ops[1];
create_input_operand (&ops[0], x, mode);
if (maybe_expand_insn (icode, 1, ops))
@@ -5027,7 +5021,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
create_fixed_operand (&ops[0], mem);
create_input_operand (&ops[1], reg, mode);
@@ -5456,7 +5450,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
bool
emit_storent_insn (rtx to, rtx from)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
machine_mode mode = GET_MODE (to);
enum insn_code code = optab_handler (storent_optab, mode);
@@ -6759,7 +6753,7 @@ store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
!= CODE_FOR_nothing)
&& (elt = uniform_vector_p (exp)))
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
create_output_operand (&ops[0], target, mode);
create_input_operand (&ops[1], expand_normal (elt), eltmode);
expand_insn (icode, 2, ops);
@@ -9554,7 +9548,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
&& mode == TYPE_MODE (TREE_TYPE (treeop0))
&& SCALAR_INT_MODE_P (mode))
{
- struct expand_operand eops[4];
+ class expand_operand eops[4];
machine_mode imode = TYPE_MODE (TREE_TYPE (treeop0));
expand_operands (treeop0, treeop1,
subtarget, &op0, &op1, EXPAND_NORMAL);
@@ -10292,7 +10286,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
&& ((icode = optab_handler (movmisalign_optab, mode))
!= CODE_FOR_nothing))
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
/* We've already validated the memory, and we're creating a
new pseudo destination. The predicates really can't fail,
@@ -10374,7 +10368,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
if ((icode = optab_handler (movmisalign_optab, mode))
!= CODE_FOR_nothing)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
/* We've already validated the memory, and we're creating a
new pseudo destination. The predicates really can't fail,
@@ -11292,6 +11286,7 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
case CATCH_EXPR:
case EH_FILTER_EXPR:
case TRY_FINALLY_EXPR:
+ case EH_ELSE_EXPR:
/* Lowered by tree-eh.c. */
gcc_unreachable ();
@@ -12179,7 +12174,7 @@ try_casesi (tree index_type, tree index_expr, tree minval, tree range,
rtx table_label, rtx default_label, rtx fallback_label,
profile_probability default_probability)
{
- struct expand_operand ops[5];
+ class expand_operand ops[5];
scalar_int_mode index_mode = SImode;
rtx op1, op2, index;
diff --git a/gcc/fibonacci_heap.c b/gcc/fibonacci_heap.c
index aec6913..bddd047 100644
--- a/gcc/fibonacci_heap.c
+++ b/gcc/fibonacci_heap.c
@@ -219,8 +219,9 @@ test_union_of_equal_heaps ()
/* Dummy struct for testing. */
-struct heap_key
+class heap_key
{
+public:
heap_key (int k): key (k)
{
}
diff --git a/gcc/flags.h b/gcc/flags.h
index 0ea1812..0b9cd12 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -42,8 +42,9 @@ extern bool final_insns_dump_p;
/* Other basic status info about current function. */
-struct target_flag_state
+class target_flag_state
{
+public:
/* Each falign-foo can generate up to two levels of alignment:
-falign-foo=N:M[:N2:M2] */
align_flags x_align_loops;
@@ -55,9 +56,9 @@ struct target_flag_state
enum excess_precision x_flag_excess_precision;
};
-extern struct target_flag_state default_target_flag_state;
+extern class target_flag_state default_target_flag_state;
#if SWITCHABLE_TARGET
-extern struct target_flag_state *this_target_flag_state;
+extern class target_flag_state *this_target_flag_state;
#else
#define this_target_flag_state (&default_target_flag_state)
#endif
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0ca472d..74544bf 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -11839,10 +11839,15 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
}
/* Gets the element ACCESS_INDEX from CTOR, which must be a CONSTRUCTOR
- of an array (or vector). */
+ of an array (or vector). *CTOR_IDX if non-NULL is updated with the
+ constructor element index of the value returned. If the element is
+ not found NULL_TREE is returned and *CTOR_IDX is updated to
+ the index of the element after the ACCESS_INDEX position (which
+ may be outside of the CTOR array). */
tree
-get_array_ctor_element_at_index (tree ctor, offset_int access_index)
+get_array_ctor_element_at_index (tree ctor, offset_int access_index,
+ unsigned *ctor_idx)
{
tree index_type = NULL_TREE;
offset_int low_bound = 0;
@@ -11869,7 +11874,7 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index)
TYPE_SIGN (index_type));
offset_int max_index;
- unsigned HOST_WIDE_INT cnt;
+ unsigned cnt;
tree cfield, cval;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
@@ -11897,11 +11902,26 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index)
max_index = index;
}
- /* Do we have match? */
- if (wi::cmpu (access_index, index) >= 0
- && wi::cmpu (access_index, max_index) <= 0)
- return cval;
- }
+ /* Do we have match? */
+ if (wi::cmpu (access_index, index) >= 0)
+ {
+ if (wi::cmpu (access_index, max_index) <= 0)
+ {
+ if (ctor_idx)
+ *ctor_idx = cnt;
+ return cval;
+ }
+ }
+ else if (in_gimple_form)
+ /* We're past the element we search for. Note during parsing
+ the elements might not be sorted.
+ ??? We should use a binary search and a flag on the
+ CONSTRUCTOR as to whether elements are sorted in declaration
+ order. */
+ break;
+ }
+ if (ctor_idx)
+ *ctor_idx = cnt;
return NULL_TREE;
}
@@ -14026,13 +14046,13 @@ fold_relational_const (enum tree_code code, tree type, tree op0, tree op1)
{
tree elem0 = VECTOR_CST_ELT (op0, i);
tree elem1 = VECTOR_CST_ELT (op1, i);
- tree tmp = fold_relational_const (code, type, elem0, elem1);
+ tree tmp = fold_relational_const (EQ_EXPR, type, elem0, elem1);
if (tmp == NULL_TREE)
return NULL_TREE;
if (integer_zerop (tmp))
- return constant_boolean_node (false, type);
+ return constant_boolean_node (code == NE_EXPR, type);
}
- return constant_boolean_node (true, type);
+ return constant_boolean_node (code == EQ_EXPR, type);
}
tree_vector_builder elts;
if (!elts.new_binary_operation (type, op0, op1, false))
@@ -14803,6 +14823,7 @@ test_vector_folding ()
tree type = build_vector_type (inner_type, 4);
tree zero = build_zero_cst (type);
tree one = build_one_cst (type);
+ tree index = build_index_vector (type, 0, 1);
/* Verify equality tests that return a scalar boolean result. */
tree res_type = boolean_type_node;
@@ -14810,6 +14831,13 @@ test_vector_folding ()
ASSERT_TRUE (integer_nonzerop (fold_build2 (EQ_EXPR, res_type, zero, zero)));
ASSERT_TRUE (integer_nonzerop (fold_build2 (NE_EXPR, res_type, zero, one)));
ASSERT_FALSE (integer_nonzerop (fold_build2 (NE_EXPR, res_type, one, one)));
+ ASSERT_TRUE (integer_nonzerop (fold_build2 (NE_EXPR, res_type, index, one)));
+ ASSERT_FALSE (integer_nonzerop (fold_build2 (EQ_EXPR, res_type,
+ index, one)));
+ ASSERT_FALSE (integer_nonzerop (fold_build2 (NE_EXPR, res_type,
+ index, index)));
+ ASSERT_TRUE (integer_nonzerop (fold_build2 (EQ_EXPR, res_type,
+ index, index)));
}
/* Verify folding of VEC_DUPLICATE_EXPRs. */
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 2a69bf9..eab2b47 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -67,7 +67,8 @@ extern tree fold_build_call_array_loc (location_t, tree, tree, int, tree *);
#define fold_build_call_array_initializer(T1,T2,N,T4)\
fold_build_call_array_initializer_loc (UNKNOWN_LOCATION, T1, T2, N, T4)
extern tree fold_build_call_array_initializer_loc (location_t, tree, tree, int, tree *);
-extern tree get_array_ctor_element_at_index (tree, offset_int);
+extern tree get_array_ctor_element_at_index (tree, offset_int,
+ unsigned * = NULL);
extern bool fold_convertible_p (const_tree, const_tree);
#define fold_convert(T1,T2)\
fold_convert_loc (UNKNOWN_LOCATION, T1, T2)
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index a163a1d..c4c35ad 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,42 @@
+2019-07-21 Thomas König <tkoenig@gcc.gnu.org>
+
+ PR libfortran/91030
+ * gfortran.texi (GFORTRAN_FORMATTED_BUFFER_SIZE): Document
+ (GFORTRAN_UNFORMATTED_BUFFER_SIZE): Likewise.
+
+2019-07-16 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/90903
+ * libgfortran.h: Add mask for -fcheck=bits option.
+ * options.c (gfc_handle_runtime_check_option): Add option "bits"
+ to run-time checks selectable via -fcheck.
+ * trans-intrinsic.c (gfc_conv_intrinsic_btest)
+ (gfc_conv_intrinsic_singlebitop, gfc_conv_intrinsic_ibits)
+ (gfc_conv_intrinsic_shift, gfc_conv_intrinsic_ishft)
+ (gfc_conv_intrinsic_ishftc): Implement run-time checks for the
+ POS, LEN, SHIFT, and SIZE arguments.
+ * gfortran.texi: Document run-time checks for bit manipulation
+ intrinsics.
+ * invoke.texi: Document new -fcheck=bits option.
+
+2019-07-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/87233
+ * expr.c (check_restricted): Relax constraint C1279 which was
+ removed from F2008 and above.
+
+2019-07-07 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/91077
+ * trans-array.c (gfc_conv_scalarized_array_ref) Delete code
+ that gave symbol backend decl for subref arrays and deferred
+ length variables.
+
+2019-07-05 Andrew Stubbs <ams@codesourcery.com>
+
+ * openmp.c (resolve_omp_clauses): Add custom error messages for
+ parameters in map clauses.
+
2019-07-03 Martin Liska <mliska@suse.cz>
* check.c (gfc_check_c_funloc): Remove
@@ -28,9 +67,9 @@
ChangeLog forgotten with revision 272667
* decl.c (access_attr_decl): Use temporary variable to reduce
unreadability of code. Normalize jumping to return.
- (gfc_match_protected): Fix parsing error. Add comments to
+ (gfc_match_protected): Fix parsing error. Add comments to
explain code. Remove dead code.
- (gfc_match_private): Use temporary variable to reduce unreadability
+ (gfc_match_private): Use temporary variable to reduce unreadability
of code. Fix parsing error. Move code to test for blank PRIVATE.
Remove dead code.
(gfc_match_public): Move code to test for blank PUBLIC. Fix
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index ec9e328..a164370 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -3305,12 +3305,14 @@ check_restricted (gfc_expr *e)
restricted expression in an elemental procedure, it will have
already been simplified away once we get here. Therefore we
don't need to jump through hoops to distinguish valid from
- invalid cases. */
- if (sym->attr.dummy && sym->ns == gfc_current_ns
+ invalid cases. Allowed in F2008 and F2018. */
+ if (gfc_notification_std (GFC_STD_F2008)
+ && sym->attr.dummy && sym->ns == gfc_current_ns
&& sym->ns->proc_name && sym->ns->proc_name->attr.elemental)
{
- gfc_error ("Dummy argument %qs not allowed in expression at %L",
- sym->name, &e->where);
+ gfc_error_now ("Dummy argument %qs not "
+ "allowed in expression at %L",
+ sym->name, &e->where);
break;
}
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index c887e7d..16be9e0 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -611,6 +611,8 @@ Malformed environment variables are silently ignored.
* GFORTRAN_LIST_SEPARATOR:: Separator for list output
* GFORTRAN_CONVERT_UNIT:: Set endianness for unformatted I/O
* GFORTRAN_ERROR_BACKTRACE:: Show backtrace on run-time errors
+* GFORTRAN_FORMATTED_BUFFER_SIZE:: Buffer size for formatted files.
+* GFORTRAN_UNFORMATTED_BUFFER_SIZE:: Buffer size for unformatted files.
@end menu
@node TMPDIR
@@ -782,6 +784,20 @@ the backtracing, set the variable to @samp{n}, @samp{N}, @samp{0}.
Default is to print a backtrace unless the @option{-fno-backtrace}
compile option was used.
+@node GFORTRAN_FORMATTED_BUFFER_SIZE
+@section @env{GFORTRAN_FORMATTED_BUFFER_SIZE}---Set buffer size for formatted I/O
+
+The @env{GFORTRAN_FORMATTED_BUFFER_SIZE} environment variable
+specifies buffer size in bytes to be used for formatted output.
+The default value is 8192.
+
+@node GFORTRAN_UNFORMATTED_BUFFER_SIZE
+@section @env{GFORTRAN_UNFORMATTED_BUFFER_SIZE}---Set buffer size for unformatted I/O
+
+The @env{GFORTRAN_UNFORMATTED_BUFFER_SIZE} environment variable
+specifies buffer size in bytes to be used for unformatted output.
+The default value is 131072.
+
@c =====================================================================
@c PART II: LANGUAGE REFERENCE
@c =====================================================================
@@ -3790,7 +3806,8 @@ initialization using @code{_gfortran_set_args}.
Default: enabled.
@item @var{option}[6] @tab Enables run-time checking. Possible values
are (bitwise or-ed): GFC_RTCHECK_BOUNDS (1), GFC_RTCHECK_ARRAY_TEMPS (2),
-GFC_RTCHECK_RECURSION (4), GFC_RTCHECK_DO (16), GFC_RTCHECK_POINTER (32).
+GFC_RTCHECK_RECURSION (4), GFC_RTCHECK_DO (16), GFC_RTCHECK_POINTER (32),
+GFC_RTCHECK_BITS (64).
Default: disabled.
@item @var{option}[7] @tab Unused.
@item @var{option}[8] @tab Show a warning when invoking @code{STOP} and
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 2b08ac4..f8efcd8 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -183,7 +183,7 @@ and warnings}.
@gccoptlist{-faggressive-function-elimination -fblas-matmul-limit=@var{n} @gol
-fbounds-check -ftail-call-workaround -ftail-call-workaround=@var{n} @gol
-fcheck-array-temporaries @gol
--fcheck=@var{<all|array-temps|bounds|do|mem|pointer|recursion>} @gol
+-fcheck=@var{<all|array-temps|bits|bounds|do|mem|pointer|recursion>} @gol
-fcoarray=@var{<none|single|lib>} -fexternal-blas -ff2c
-ffrontend-loop-interchange @gol
-ffrontend-optimize @gol
@@ -1558,6 +1558,7 @@ library needs to be linked.
@item -fcheck=@var{<keyword>}
@opindex @code{fcheck}
@cindex array, bounds checking
+@cindex bit intrinsics checking
@cindex bounds checking
@cindex pointer checking
@cindex memory checking
@@ -1582,6 +1583,10 @@ sometimes useful in optimization, in order to avoid such temporaries.
Note: The warning is only printed once per location.
+@item @samp{bits}
+Enable generation of run-time checks for invalid arguments to the bit
+manipulation intrinsics.
+
@item @samp{bounds}
Enable generation of run-time checks for array subscripts
and against the declared minimum and maximum values. It also
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index 581b2f5..f82fc6a 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -73,9 +73,11 @@ along with GCC; see the file COPYING3. If not see
#define GFC_RTCHECK_DO (1<<3)
#define GFC_RTCHECK_POINTER (1<<4)
#define GFC_RTCHECK_MEM (1<<5)
+#define GFC_RTCHECK_BITS (1<<6)
#define GFC_RTCHECK_ALL (GFC_RTCHECK_BOUNDS | GFC_RTCHECK_ARRAY_TEMPS \
| GFC_RTCHECK_RECURSION | GFC_RTCHECK_DO \
- | GFC_RTCHECK_POINTER | GFC_RTCHECK_MEM)
+ | GFC_RTCHECK_POINTER | GFC_RTCHECK_MEM \
+ | GFC_RTCHECK_BITS)
/* Special unit numbers used to convey certain conditions. Numbers -4
thru -9 available. NEWUNIT values start at -10. */
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 1c7bce6..44fcb9d 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -4208,8 +4208,21 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
continue;
}
}
- gfc_error ("Object %qs is not a variable at %L", n->sym->name,
- &n->where);
+ if (list == OMP_LIST_MAP
+ && n->sym->attr.flavor == FL_PARAMETER)
+ {
+ if (openacc)
+ gfc_error ("Object %qs is not a variable at %L; parameters"
+ " cannot be and need not be copied", n->sym->name,
+ &n->where);
+ else
+ gfc_error ("Object %qs is not a variable at %L; parameters"
+ " cannot be and need not be mapped", n->sym->name,
+ &n->where);
+ }
+ else
+ gfc_error ("Object %qs is not a variable at %L", n->sym->name,
+ &n->where);
}
for (list = 0; list < OMP_LIST_NUM; list++)
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 3bc79ef..ef37ccc 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -580,12 +580,12 @@ gfc_handle_runtime_check_option (const char *arg)
int result, pos = 0, n;
static const char * const optname[] = { "all", "bounds", "array-temps",
"recursion", "do", "pointer",
- "mem", NULL };
+ "mem", "bits", NULL };
static const int optmask[] = { GFC_RTCHECK_ALL, GFC_RTCHECK_BOUNDS,
GFC_RTCHECK_ARRAY_TEMPS,
GFC_RTCHECK_RECURSION, GFC_RTCHECK_DO,
GFC_RTCHECK_POINTER, GFC_RTCHECK_MEM,
- 0 };
+ GFC_RTCHECK_BITS, 0 };
while (*arg)
{
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 1ab0361..c8d74e5 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -3502,19 +3502,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
return;
if (get_CFI_desc (NULL, expr, &decl, ar))
- {
- decl = build_fold_indirect_ref_loc (input_location, decl);
- goto done;
- }
-
- if (expr && ((is_subref_array (expr)
- && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (info->descriptor)))
- || (expr->ts.deferred && (expr->expr_type == EXPR_VARIABLE
- || expr->expr_type == EXPR_FUNCTION))))
- decl = expr->symtree->n.sym->backend_decl;
-
- if (decl && GFC_DECL_PTR_ARRAY_P (decl))
- goto done;
+ decl = build_fold_indirect_ref_loc (input_location, decl);
/* A pointer array component can be detected from its field decl. Fix
the descriptor, mark the resulting variable decl and pass it to
@@ -3532,7 +3520,6 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar)
decl = info->descriptor;
}
-done:
se->expr = gfc_build_array_ref (base, index, decl);
}
@@ -7865,7 +7852,7 @@ array_parameter_size (tree desc, gfc_expr *expr, tree *size)
}
/* Helper function - return true if the argument is a pointer. */
-
+
static bool
is_pointer (gfc_expr *e)
{
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index a7ebc41..a6e3383 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -6166,6 +6166,24 @@ gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_function_args (se, expr, args, 2);
type = TREE_TYPE (args[0]);
+ /* Optionally generate code for runtime argument check. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_BITS)
+ {
+ tree below = fold_build2_loc (input_location, LT_EXPR,
+ logical_type_node, args[1],
+ build_int_cst (TREE_TYPE (args[1]), 0));
+ tree nbits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
+ tree above = fold_build2_loc (input_location, GE_EXPR,
+ logical_type_node, args[1], nbits);
+ tree scond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
+ logical_type_node, below, above);
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "POS argument (%ld) out of range 0:%ld "
+ "in intrinsic BTEST",
+ fold_convert (long_integer_type_node, args[1]),
+ fold_convert (long_integer_type_node, nbits));
+ }
+
tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
build_int_cst (type, 1), args[1]);
tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[0], tmp);
@@ -6236,6 +6254,32 @@ gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
gfc_conv_intrinsic_function_args (se, expr, args, 2);
type = TREE_TYPE (args[0]);
+ /* Optionally generate code for runtime argument check. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_BITS)
+ {
+ tree below = fold_build2_loc (input_location, LT_EXPR,
+ logical_type_node, args[1],
+ build_int_cst (TREE_TYPE (args[1]), 0));
+ tree nbits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
+ tree above = fold_build2_loc (input_location, GE_EXPR,
+ logical_type_node, args[1], nbits);
+ tree scond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
+ logical_type_node, below, above);
+ size_t len_name = strlen (expr->value.function.isym->name);
+ char *name = XALLOCAVEC (char, len_name + 1);
+ for (size_t i = 0; i < len_name; i++)
+ name[i] = TOUPPER (expr->value.function.isym->name[i]);
+ name[len_name] = '\0';
+ tree iname = gfc_build_addr_expr (pchar_type_node,
+ gfc_build_cstring_const (name));
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "POS argument (%ld) out of range 0:%ld "
+ "in intrinsic %s",
+ fold_convert (long_integer_type_node, args[1]),
+ fold_convert (long_integer_type_node, nbits),
+ iname);
+ }
+
tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
build_int_cst (type, 1), args[1]);
if (set)
@@ -6261,6 +6305,42 @@ gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_function_args (se, expr, args, 3);
type = TREE_TYPE (args[0]);
+ /* Optionally generate code for runtime argument check. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_BITS)
+ {
+ tree tmp1 = fold_convert (long_integer_type_node, args[1]);
+ tree tmp2 = fold_convert (long_integer_type_node, args[2]);
+ tree nbits = build_int_cst (long_integer_type_node,
+ TYPE_PRECISION (type));
+ tree below = fold_build2_loc (input_location, LT_EXPR,
+ logical_type_node, args[1],
+ build_int_cst (TREE_TYPE (args[1]), 0));
+ tree above = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, tmp1, nbits);
+ tree scond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
+ logical_type_node, below, above);
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "POS argument (%ld) out of range 0:%ld "
+ "in intrinsic IBITS", tmp1, nbits);
+ below = fold_build2_loc (input_location, LT_EXPR,
+ logical_type_node, args[2],
+ build_int_cst (TREE_TYPE (args[2]), 0));
+ above = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, tmp2, nbits);
+ scond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
+ logical_type_node, below, above);
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "LEN argument (%ld) out of range 0:%ld "
+ "in intrinsic IBITS", tmp2, nbits);
+ above = fold_build2_loc (input_location, PLUS_EXPR,
+ long_integer_type_node, tmp1, tmp2);
+ scond = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, above, nbits);
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "POS(%ld)+LEN(%ld)>BIT_SIZE(%ld) "
+ "in intrinsic IBITS", tmp1, tmp2, nbits);
+ }
+
mask = build_int_cst (type, -1);
mask = fold_build2_loc (input_location, LSHIFT_EXPR, type, mask, args[2]);
mask = fold_build1_loc (input_location, BIT_NOT_EXPR, type, mask);
@@ -6382,6 +6462,32 @@ gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift,
gcc requires a shift width < BIT_SIZE(I), so we have to catch this
special case. */
num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
+
+ /* Optionally generate code for runtime argument check. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_BITS)
+ {
+ tree below = fold_build2_loc (input_location, LT_EXPR,
+ logical_type_node, args[1],
+ build_int_cst (TREE_TYPE (args[1]), 0));
+ tree above = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, args[1], num_bits);
+ tree scond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
+ logical_type_node, below, above);
+ size_t len_name = strlen (expr->value.function.isym->name);
+ char *name = XALLOCAVEC (char, len_name + 1);
+ for (size_t i = 0; i < len_name; i++)
+ name[i] = TOUPPER (expr->value.function.isym->name[i]);
+ name[len_name] = '\0';
+ tree iname = gfc_build_addr_expr (pchar_type_node,
+ gfc_build_cstring_const (name));
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "SHIFT argument (%ld) out of range 0:%ld "
+ "in intrinsic %s",
+ fold_convert (long_integer_type_node, args[1]),
+ fold_convert (long_integer_type_node, num_bits),
+ iname);
+ }
+
cond = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
args[1], num_bits);
@@ -6436,6 +6542,20 @@ gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
gcc requires a shift width < BIT_SIZE(I), so we have to catch this
special case. */
num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
+
+ /* Optionally generate code for runtime argument check. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_BITS)
+ {
+ tree outside = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, width, num_bits);
+ gfc_trans_runtime_check (true, false, outside, &se->pre, &expr->where,
+ "SHIFT argument (%ld) out of range -%ld:%ld "
+ "in intrinsic ISHFT",
+ fold_convert (long_integer_type_node, args[1]),
+ fold_convert (long_integer_type_node, num_bits),
+ fold_convert (long_integer_type_node, num_bits));
+ }
+
cond = fold_build2_loc (input_location, GE_EXPR, logical_type_node, width,
num_bits);
se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
@@ -6454,6 +6574,7 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
tree lrot;
tree rrot;
tree zero;
+ tree nbits;
unsigned int num_args;
num_args = gfc_intrinsic_argument_list_length (expr);
@@ -6461,12 +6582,14 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
gfc_conv_intrinsic_function_args (se, expr, args, num_args);
+ type = TREE_TYPE (args[0]);
+ nbits = build_int_cst (long_integer_type_node, TYPE_PRECISION (type));
+
if (num_args == 3)
{
/* Use a library function for the 3 parameter version. */
tree int4type = gfc_get_int_type (4);
- type = TREE_TYPE (args[0]);
/* We convert the first argument to at least 4 bytes, and
convert back afterwards. This removes the need for library
functions for all argument sizes, and function will be
@@ -6480,6 +6603,32 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
args[1] = convert (int4type, args[1]);
args[2] = convert (int4type, args[2]);
+ /* Optionally generate code for runtime argument check. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_BITS)
+ {
+ tree size = fold_convert (long_integer_type_node, args[2]);
+ tree below = fold_build2_loc (input_location, LE_EXPR,
+ logical_type_node, size,
+ build_int_cst (TREE_TYPE (args[1]), 0));
+ tree above = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, size, nbits);
+ tree scond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
+ logical_type_node, below, above);
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "SIZE argument (%ld) out of range 1:%ld "
+ "in intrinsic ISHFTC", size, nbits);
+ tree width = fold_convert (long_integer_type_node, args[1]);
+ width = fold_build1_loc (input_location, ABS_EXPR,
+ long_integer_type_node, width);
+ scond = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, width, size);
+ gfc_trans_runtime_check (true, false, scond, &se->pre, &expr->where,
+ "SHIFT argument (%ld) out of range -%ld:%ld "
+ "in intrinsic ISHFTC",
+ fold_convert (long_integer_type_node, args[1]),
+ size, size);
+ }
+
switch (expr->ts.kind)
{
case 1:
@@ -6505,12 +6654,26 @@ gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
return;
}
- type = TREE_TYPE (args[0]);
/* Evaluate arguments only once. */
args[0] = gfc_evaluate_now (args[0], &se->pre);
args[1] = gfc_evaluate_now (args[1], &se->pre);
+ /* Optionally generate code for runtime argument check. */
+ if (gfc_option.rtcheck & GFC_RTCHECK_BITS)
+ {
+ tree width = fold_convert (long_integer_type_node, args[1]);
+ width = fold_build1_loc (input_location, ABS_EXPR,
+ long_integer_type_node, width);
+ tree outside = fold_build2_loc (input_location, GT_EXPR,
+ logical_type_node, width, nbits);
+ gfc_trans_runtime_check (true, false, outside, &se->pre, &expr->where,
+ "SHIFT argument (%ld) out of range -%ld:%ld "
+ "in intrinsic ISHFTC",
+ fold_convert (long_integer_type_node, args[1]),
+ nbits, nbits);
+ }
+
/* Rotate left if positive. */
lrot = fold_build2_loc (input_location, LROTATE_EXPR, type, args[0], args[1]);
diff --git a/gcc/function.c b/gcc/function.c
index a957679..2a0061c 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -133,7 +133,7 @@ vec<tree, va_gc> *types_used_by_cur_var_decl;
/* Forward declarations. */
-static struct temp_slot *find_temp_slot_from_address (rtx);
+static class temp_slot *find_temp_slot_from_address (rtx);
static void pad_to_arg_alignment (struct args_size *, int, struct args_size *);
static void pad_below (struct args_size *, machine_mode, tree);
static void reorder_blocks_1 (rtx_insn *, tree, vec<tree> *);
@@ -345,7 +345,7 @@ try_fit_stack_local (poly_int64 start, poly_int64 length,
static void
add_frame_space (poly_int64 start, poly_int64 end)
{
- struct frame_space *space = ggc_alloc<frame_space> ();
+ class frame_space *space = ggc_alloc<frame_space> ();
space->next = crtl->frame_space_list;
crtl->frame_space_list = space;
space->start = start;
@@ -441,11 +441,11 @@ assign_stack_local_1 (machine_mode mode, poly_int64 size,
{
if (kind & ASLK_RECORD_PAD)
{
- struct frame_space **psp;
+ class frame_space **psp;
for (psp = &crtl->frame_space_list; *psp; psp = &(*psp)->next)
{
- struct frame_space *space = *psp;
+ class frame_space *space = *psp;
if (!try_fit_stack_local (space->start, space->length, size,
alignment, &slot_offset))
continue;
@@ -556,11 +556,12 @@ assign_stack_local (machine_mode mode, poly_int64 size, int align)
result, all temporaries are preserved. A temporary is preserved by
pretending it was allocated at the previous nesting level. */
-struct GTY(()) temp_slot {
+class GTY(()) temp_slot {
+public:
/* Points to next temporary slot. */
- struct temp_slot *next;
+ class temp_slot *next;
/* Points to previous temporary slot. */
- struct temp_slot *prev;
+ class temp_slot *prev;
/* The rtx to used to reference the slot. */
rtx slot;
/* The size, in units, of the slot. */
@@ -588,7 +589,7 @@ struct GTY(()) temp_slot {
struct GTY((for_user)) temp_slot_address_entry {
hashval_t hash;
rtx address;
- struct temp_slot *temp_slot;
+ class temp_slot *temp_slot;
};
struct temp_address_hasher : ggc_ptr_hash<temp_slot_address_entry>
@@ -605,7 +606,7 @@ static size_t n_temp_slots_in_use;
/* Removes temporary slot TEMP from LIST. */
static void
-cut_slot_from_list (struct temp_slot *temp, struct temp_slot **list)
+cut_slot_from_list (class temp_slot *temp, class temp_slot **list)
{
if (temp->next)
temp->next->prev = temp->prev;
@@ -620,7 +621,7 @@ cut_slot_from_list (struct temp_slot *temp, struct temp_slot **list)
/* Inserts temporary slot TEMP to LIST. */
static void
-insert_slot_to_list (struct temp_slot *temp, struct temp_slot **list)
+insert_slot_to_list (class temp_slot *temp, class temp_slot **list)
{
temp->next = *list;
if (*list)
@@ -631,7 +632,7 @@ insert_slot_to_list (struct temp_slot *temp, struct temp_slot **list)
/* Returns the list of used temp slots at LEVEL. */
-static struct temp_slot **
+static class temp_slot **
temp_slots_at_level (int level)
{
if (level >= (int) vec_safe_length (used_temp_slots))
@@ -654,7 +655,7 @@ max_slot_level (void)
/* Moves temporary slot TEMP to LEVEL. */
static void
-move_slot_to_level (struct temp_slot *temp, int level)
+move_slot_to_level (class temp_slot *temp, int level)
{
cut_slot_from_list (temp, temp_slots_at_level (temp->level));
insert_slot_to_list (temp, temp_slots_at_level (level));
@@ -664,7 +665,7 @@ move_slot_to_level (struct temp_slot *temp, int level)
/* Make temporary slot TEMP available. */
static void
-make_slot_available (struct temp_slot *temp)
+make_slot_available (class temp_slot *temp)
{
cut_slot_from_list (temp, temp_slots_at_level (temp->level));
insert_slot_to_list (temp, &avail_temp_slots);
@@ -700,10 +701,10 @@ temp_address_hasher::equal (temp_slot_address_entry *t1,
/* Add ADDRESS as an alias of TEMP_SLOT to the addess -> temp slot mapping. */
static void
-insert_temp_slot_address (rtx address, struct temp_slot *temp_slot)
+insert_temp_slot_address (rtx address, class temp_slot *temp_slot)
{
struct temp_slot_address_entry *t = ggc_alloc<temp_slot_address_entry> ();
- t->address = address;
+ t->address = copy_rtx (address);
t->temp_slot = temp_slot;
t->hash = temp_slot_address_compute_hash (t);
*temp_slot_address_table->find_slot_with_hash (t, t->hash, INSERT) = t;
@@ -734,10 +735,10 @@ remove_unused_temp_slot_addresses (void)
/* Find the temp slot corresponding to the object at address X. */
-static struct temp_slot *
+static class temp_slot *
find_temp_slot_from_address (rtx x)
{
- struct temp_slot *p;
+ class temp_slot *p;
struct temp_slot_address_entry tmp, *t;
/* First try the easy way:
@@ -786,7 +787,7 @@ rtx
assign_stack_temp_for_type (machine_mode mode, poly_int64 size, tree type)
{
unsigned int align;
- struct temp_slot *p, *best_p = 0, *selected = NULL, **pp;
+ class temp_slot *p, *best_p = 0, *selected = NULL, **pp;
rtx slot;
gcc_assert (known_size_p (size));
@@ -1030,7 +1031,7 @@ assign_temp (tree type_or_decl, int memory_required,
static void
combine_temp_slots (void)
{
- struct temp_slot *p, *q, *next, *next_q;
+ class temp_slot *p, *q, *next, *next_q;
int num_slots;
/* We can't combine slots, because the information about which slot
@@ -1094,7 +1095,7 @@ combine_temp_slots (void)
void
update_temp_slot_address (rtx old_rtx, rtx new_rtx)
{
- struct temp_slot *p;
+ class temp_slot *p;
if (rtx_equal_p (old_rtx, new_rtx))
return;
@@ -1148,7 +1149,7 @@ update_temp_slot_address (rtx old_rtx, rtx new_rtx)
void
preserve_temp_slots (rtx x)
{
- struct temp_slot *p = 0, *next;
+ class temp_slot *p = 0, *next;
if (x == 0)
return;
@@ -1188,7 +1189,7 @@ preserve_temp_slots (rtx x)
void
free_temp_slots (void)
{
- struct temp_slot *p, *next;
+ class temp_slot *p, *next;
bool some_available = false;
for (p = *temp_slots_at_level (temp_slot_level); p; p = next)
@@ -5244,19 +5245,6 @@ use_return_register (void)
diddle_return_value (do_use_return_reg, NULL);
}
-/* Set the location of the insn chain starting at INSN to LOC. */
-
-static void
-set_insn_locations (rtx_insn *insn, int loc)
-{
- while (insn != NULL)
- {
- if (INSN_P (insn))
- INSN_LOCATION (insn) = loc;
- insn = NEXT_INSN (insn);
- }
-}
-
/* Generate RTL for the end of the current function. */
void
diff --git a/gcc/function.h b/gcc/function.h
index bfe9919..43ac5dff 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -183,16 +183,18 @@ struct GTY(()) function_subsections {
/* Describe an empty area of space in the stack frame. These can be chained
into a list; this is used to keep track of space wasted for alignment
reasons. */
-struct GTY(()) frame_space
+class GTY(()) frame_space
{
- struct frame_space *next;
+public:
+ class frame_space *next;
poly_int64 start;
poly_int64 length;
};
-struct GTY(()) stack_usage
+class GTY(()) stack_usage
{
+public:
/* # of bytes of static stack space allocated by the function. */
HOST_WIDE_INT static_stack_size;
@@ -241,7 +243,7 @@ struct GTY(()) function {
char *pass_startwith;
/* The stack usage of this function. */
- struct stack_usage *su;
+ class stack_usage *su;
/* Value histograms attached to particular statements. */
htab_t GTY((skip)) value_histograms;
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 45703fe..137864c 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -224,8 +224,8 @@ edge
single_def_use_dom_walker::before_dom_children (basic_block bb)
{
int bb_index = bb->index;
- struct df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index);
- struct df_lr_bb_info *lr_bb_info = df_lr_get_bb_info (bb_index);
+ class df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index);
+ class df_lr_bb_info *lr_bb_info = df_lr_get_bb_info (bb_index);
rtx_insn *insn;
bitmap_copy (local_md, &md_bb_info->in);
@@ -448,6 +448,18 @@ enum {
PR_OPTIMIZE_FOR_SPEED = 4
};
+/* Check that X has a single def. */
+
+static bool
+reg_single_def_p (rtx x)
+{
+ if (!REG_P (x))
+ return false;
+
+ int regno = REGNO (x);
+ return (DF_REG_DEF_COUNT (regno) == 1
+ && !bitmap_bit_p (DF_LR_OUT (ENTRY_BLOCK_PTR_FOR_FN (cfun)), regno));
+}
/* Replace all occurrences of OLD in *PX with NEW and try to simplify the
resulting expression. Replace *PX with a new RTL expression if an
@@ -547,6 +559,54 @@ propagate_rtx_1 (rtx *px, rtx old_rtx, rtx new_rtx, int flags)
tem = simplify_gen_subreg (mode, op0, GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
}
+
+ else
+ {
+ rtvec vec;
+ rtvec newvec;
+ const char *fmt = GET_RTX_FORMAT (code);
+ rtx op;
+
+ for (int i = 0; fmt[i]; i++)
+ switch (fmt[i])
+ {
+ case 'E':
+ vec = XVEC (x, i);
+ newvec = vec;
+ for (int j = 0; j < GET_NUM_ELEM (vec); j++)
+ {
+ op = RTVEC_ELT (vec, j);
+ valid_ops &= propagate_rtx_1 (&op, old_rtx, new_rtx, flags);
+ if (op != RTVEC_ELT (vec, j))
+ {
+ if (newvec == vec)
+ {
+ newvec = shallow_copy_rtvec (vec);
+ if (!tem)
+ tem = shallow_copy_rtx (x);
+ XVEC (tem, i) = newvec;
+ }
+ RTVEC_ELT (newvec, j) = op;
+ }
+ }
+ break;
+
+ case 'e':
+ if (XEXP (x, i))
+ {
+ op = XEXP (x, i);
+ valid_ops &= propagate_rtx_1 (&op, old_rtx, new_rtx, flags);
+ if (op != XEXP (x, i))
+ {
+ if (!tem)
+ tem = shallow_copy_rtx (x);
+ XEXP (tem, i) = op;
+ }
+ }
+ break;
+ }
+ }
+
break;
case RTX_OBJ:
@@ -1370,10 +1430,11 @@ forward_propagate_and_simplify (df_ref use, rtx_insn *def_insn, rtx def_set)
/* Given a use USE of an insn, if it has a single reaching
definition, try to forward propagate it into that insn.
- Return true if cfg cleanup will be needed. */
+ Return true if cfg cleanup will be needed.
+ REG_PROP_ONLY is true if we should only propagate register copies. */
static bool
-forward_propagate_into (df_ref use)
+forward_propagate_into (df_ref use, bool reg_prop_only = false)
{
df_ref def;
rtx_insn *def_insn, *use_insn;
@@ -1394,10 +1455,6 @@ forward_propagate_into (df_ref use)
if (DF_REF_IS_ARTIFICIAL (def))
return false;
- /* Do not propagate loop invariant definitions inside the loop. */
- if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father)
- return false;
-
/* Check if the use is still present in the insn! */
use_insn = DF_REF_INSN (use);
if (DF_REF_FLAGS (use) & DF_REF_IN_NOTE)
@@ -1415,6 +1472,19 @@ forward_propagate_into (df_ref use)
if (!def_set)
return false;
+ if (reg_prop_only
+ && (!reg_single_def_p (SET_SRC (def_set))
+ || !reg_single_def_p (SET_DEST (def_set))))
+ return false;
+
+ /* Allow propagations into a loop only for reg-to-reg copies, since
+ replacing one register by another shouldn't increase the cost. */
+
+ if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father
+ && (!reg_single_def_p (SET_SRC (def_set))
+ || !reg_single_def_p (SET_DEST (def_set))))
+ return false;
+
/* Only try one kind of propagation. If two are possible, we'll
do it on the following iterations. */
if (forward_propagate_and_simplify (use, def_insn, def_set)
@@ -1483,7 +1553,7 @@ gate_fwprop (void)
}
static unsigned int
-fwprop (void)
+fwprop (bool fwprop_addr_p)
{
unsigned i;
@@ -1502,11 +1572,16 @@ fwprop (void)
df_ref use = DF_USES_GET (i);
if (use)
- if (DF_REF_TYPE (use) == DF_REF_REG_USE
- || DF_REF_BB (use)->loop_father == NULL
- /* The outer most loop is not really a loop. */
- || loop_outer (DF_REF_BB (use)->loop_father) == NULL)
- forward_propagate_into (use);
+ {
+ if (DF_REF_TYPE (use) == DF_REF_REG_USE
+ || DF_REF_BB (use)->loop_father == NULL
+ /* The outer most loop is not really a loop. */
+ || loop_outer (DF_REF_BB (use)->loop_father) == NULL)
+ forward_propagate_into (use, fwprop_addr_p);
+
+ else if (fwprop_addr_p)
+ forward_propagate_into (use, false);
+ }
}
fwprop_done ();
@@ -1537,7 +1612,7 @@ public:
/* opt_pass methods: */
virtual bool gate (function *) { return gate_fwprop (); }
- virtual unsigned int execute (function *) { return fwprop (); }
+ virtual unsigned int execute (function *) { return fwprop (false); }
}; // class pass_rtl_fwprop
@@ -1549,33 +1624,6 @@ make_pass_rtl_fwprop (gcc::context *ctxt)
return new pass_rtl_fwprop (ctxt);
}
-static unsigned int
-fwprop_addr (void)
-{
- unsigned i;
-
- fwprop_init ();
-
- /* Go through all the uses. df_uses_create will create new ones at the
- end, and we'll go through them as well. */
- for (i = 0; i < DF_USES_TABLE_SIZE (); i++)
- {
- if (!propagations_left)
- break;
-
- df_ref use = DF_USES_GET (i);
- if (use)
- if (DF_REF_TYPE (use) != DF_REF_REG_USE
- && DF_REF_BB (use)->loop_father != NULL
- /* The outer most loop is not really a loop. */
- && loop_outer (DF_REF_BB (use)->loop_father) != NULL)
- forward_propagate_into (use);
- }
-
- fwprop_done ();
- return 0;
-}
-
namespace {
const pass_data pass_data_rtl_fwprop_addr =
@@ -1600,7 +1648,7 @@ public:
/* opt_pass methods: */
virtual bool gate (function *) { return gate_fwprop (); }
- virtual unsigned int execute (function *) { return fwprop_addr (); }
+ virtual unsigned int execute (function *) { return fwprop (true); }
}; // class pass_rtl_fwprop_addr
diff --git a/gcc/gcc-rich-location.h b/gcc/gcc-rich-location.h
index de92e3b..3bee2e8 100644
--- a/gcc/gcc-rich-location.h
+++ b/gcc/gcc-rich-location.h
@@ -181,7 +181,7 @@ class maybe_range_label_for_tree_type_mismatch : public range_label
tree m_other_expr;
};
-struct op_location_t;
+class op_location_t;
/* A subclass of rich_location for showing problems with binary operations.
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 0c0a686..a4323eb 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -57,7 +57,7 @@ compilation is specified by a string called a "spec". */
getenv ();
Hence we need to use "get" for the accessor method, not "getenv". */
-class env_manager
+struct env_manager
{
public:
void init (bool can_restore, bool debug);
@@ -8579,7 +8579,7 @@ static int n_mdswitches;
/* Check whether a particular argument was used. The first time we
canonicalize the switches to keep only the ones we care about. */
-class used_arg_t
+struct used_arg_t
{
public:
int operator () (const char *p, int len);
diff --git a/gcc/gcov.c b/gcc/gcov.c
index b06a671..c65b715 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -76,17 +76,17 @@ using namespace std;
/* This is the size of the buffer used to read in source file lines. */
-struct function_info;
-struct block_info;
-struct source_info;
+class function_info;
+class block_info;
+class source_info;
/* Describes an arc between two basic blocks. */
struct arc_info
{
/* source and destination blocks. */
- struct block_info *src;
- struct block_info *dst;
+ class block_info *src;
+ class block_info *dst;
/* transition counts. */
gcov_type count;
@@ -121,8 +121,9 @@ struct arc_info
/* Describes which locations (lines and files) are associated with
a basic block. */
-struct block_location_info
+class block_location_info
{
+public:
block_location_info (unsigned _source_file_idx):
source_file_idx (_source_file_idx)
{}
@@ -134,8 +135,9 @@ struct block_location_info
/* Describes a basic block. Contains lists of arcs to successor and
predecessor blocks. */
-struct block_info
+class block_info
{
+public:
/* Constructor. */
block_info ();
@@ -176,7 +178,7 @@ struct block_info
/* Temporary chain for solving graph, and for chaining blocks on one
line. */
- struct block_info *chain;
+ class block_info *chain;
};
@@ -191,8 +193,9 @@ block_info::block_info (): succ (NULL), pred (NULL), num_succ (0), num_pred (0),
/* Describes a single line of source. Contains a chain of basic blocks
with code on it. */
-struct line_info
+class line_info
{
+public:
/* Default constructor. */
line_info ();
@@ -230,8 +233,9 @@ static int flag_demangled_names = 0;
/* Describes a single function. Contains an array of basic blocks. */
-struct function_info
+class function_info
{
+public:
function_info ();
~function_info ();
@@ -293,7 +297,7 @@ struct function_info
vector<line_info> lines;
/* Next function. */
- struct function_info *next;
+ class function_info *next;
/* Get demangled name of a function. The demangled name
is converted when it is used for the first time. */
@@ -356,8 +360,9 @@ struct coverage_info
/* Describes a file mentioned in the block graph. Contains an array
of line info. */
-struct source_info
+class source_info
{
+public:
/* Default constructor. */
source_info ();
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
index 191a5e2..54056b3 100644
--- a/gcc/gdbhooks.py
+++ b/gcc/gdbhooks.py
@@ -605,7 +605,8 @@ def build_pretty_printer():
gdb.printing.register_pretty_printer(
gdb.current_objfile(),
- build_pretty_printer())
+ build_pretty_printer(),
+ replace=True)
def find_gcc_source_dir():
# Use location of global "g" to locate the source tree
@@ -740,18 +741,17 @@ class DumpFn(gdb.Command):
f.close()
# Open file
- fp = gdb.parse_and_eval("fopen (\"%s\", \"w\")" % filename)
+ fp = gdb.parse_and_eval("(FILE *) fopen (\"%s\", \"w\")" % filename)
if fp == 0:
print ("Could not open file: %s" % filename)
return
- fp = "(FILE *)%u" % fp
# Dump function to file
_ = gdb.parse_and_eval("dump_function_to_file (%s, %s, %u)" %
(func, fp, flags))
# Close file
- ret = gdb.parse_and_eval("fclose (%s)" % fp)
+ ret = gdb.parse_and_eval("(int) fclose (%s)" % fp)
if ret != 0:
print ("Could not close file: %s" % filename)
return
@@ -810,11 +810,10 @@ class DotFn(gdb.Command):
# Close and reopen temp file to get C FILE*
f.close()
- fp = gdb.parse_and_eval("fopen (\"%s\", \"w\")" % filename)
+ fp = gdb.parse_and_eval("(FILE *) fopen (\"%s\", \"w\")" % filename)
if fp == 0:
print("Cannot open temp file")
return
- fp = "(FILE *)%u" % fp
# Write graph to temp file
_ = gdb.parse_and_eval("start_graph_dump (%s, \"<debug>\")" % fp)
@@ -823,7 +822,7 @@ class DotFn(gdb.Command):
_ = gdb.parse_and_eval("end_graph_dump (%s)" % fp)
# Close temp file
- ret = gdb.parse_and_eval("fclose (%s)" % fp)
+ ret = gdb.parse_and_eval("(int) fclose (%s)" % fp)
if ret != 0:
print("Could not close temp file: %s" % filename)
return
diff --git a/gcc/gdbinit.in b/gcc/gdbinit.in
index 440fd25..42302ae 100644
--- a/gcc/gdbinit.in
+++ b/gcc/gdbinit.in
@@ -219,6 +219,16 @@ is emitted (as opposed to those warnings that are suppressed by
command-line options).
end
+define reload-gdbhooks
+python import imp; imp.reload(gdbhooks)
+end
+
+document reload-gdbhooks
+Load the gdbhooks.py module again in order to pick up any changes made to it.
+end
+
+alias rh = reload-gdbhooks
+
# Define some macros helpful to gdb when it is expanding macros.
macro define __FILE__ "gdb"
macro define __LINE__ 1
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 78816ba..cdf0b5c 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -133,9 +133,10 @@ static struct obstack *temp_obstack = &obstack2;
`struct insn_def'. This is done to allow attribute definitions to occur
anywhere in the file. */
-struct insn_def
+class insn_def
{
- struct insn_def *next; /* Next insn in chain. */
+public:
+ class insn_def *next; /* Next insn in chain. */
rtx def; /* The DEFINE_... */
int insn_code; /* Instruction number. */
int insn_index; /* Expression number in file, for errors. */
@@ -151,7 +152,7 @@ struct insn_def
struct insn_ent
{
struct insn_ent *next; /* Next in chain. */
- struct insn_def *def; /* Instruction definition. */
+ class insn_def *def; /* Instruction definition. */
};
/* Each value of an attribute (either constant or computed) is assigned a
@@ -169,11 +170,12 @@ struct attr_value
/* Structure for each attribute. */
-struct attr_desc
+class attr_desc
{
+public:
char *name; /* Name of attribute. */
const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */
- struct attr_desc *next; /* Next attribute. */
+ class attr_desc *next; /* Next attribute. */
struct attr_value *first_value; /* First value of this attribute. */
struct attr_value *default_val; /* Default value for this attribute. */
file_location loc; /* Where in the .md files it occurs. */
@@ -184,10 +186,11 @@ struct attr_desc
/* Structure for each DEFINE_DELAY. */
-struct delay_desc
+class delay_desc
{
+public:
rtx def; /* DEFINE_DELAY expression. */
- struct delay_desc *next; /* Next DEFINE_DELAY. */
+ class delay_desc *next; /* Next DEFINE_DELAY. */
file_location loc; /* Where in the .md files it occurs. */
int num; /* Number of DEFINE_DELAY, starting at 1. */
};
@@ -196,7 +199,7 @@ struct attr_value_list
{
struct attr_value *av;
struct insn_ent *ie;
- struct attr_desc *attr;
+ class attr_desc *attr;
struct attr_value_list *next;
};
@@ -204,9 +207,9 @@ struct attr_value_list
/* This one is indexed by the first character of the attribute name. */
#define MAX_ATTRS_INDEX 256
-static struct attr_desc *attrs[MAX_ATTRS_INDEX];
-static struct insn_def *defs;
-static struct delay_desc *delays;
+static class attr_desc *attrs[MAX_ATTRS_INDEX];
+static class insn_def *defs;
+static class delay_desc *delays;
struct attr_value_list **insn_code_values;
/* Other variables. */
@@ -257,7 +260,7 @@ static char *attr_string (const char *, int);
static char *attr_printf (unsigned int, const char *, ...)
ATTRIBUTE_PRINTF_2;
static rtx make_numeric_value (int);
-static struct attr_desc *find_attr (const char **, int);
+static class attr_desc *find_attr (const char **, int);
static rtx mk_attr_alt (alternative_mask);
static char *next_comma_elt (const char **);
static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
@@ -275,15 +278,15 @@ static rtx copy_rtx_unchanging (rtx);
static bool attr_alt_subset_p (rtx, rtx);
static bool attr_alt_subset_of_compl_p (rtx, rtx);
static void clear_struct_flag (rtx);
-static void write_attr_valueq (FILE *, struct attr_desc *, const char *);
-static struct attr_value *find_most_used (struct attr_desc *);
-static void write_attr_set (FILE *, struct attr_desc *, int, rtx,
+static void write_attr_valueq (FILE *, class attr_desc *, const char *);
+static struct attr_value *find_most_used (class attr_desc *);
+static void write_attr_set (FILE *, class attr_desc *, int, rtx,
const char *, const char *, rtx,
int, int, unsigned int);
-static void write_attr_case (FILE *, struct attr_desc *,
+static void write_attr_case (FILE *, class attr_desc *,
struct attr_value *,
int, const char *, const char *, int, rtx);
-static void write_attr_value (FILE *, struct attr_desc *, rtx);
+static void write_attr_value (FILE *, class attr_desc *, rtx);
static void write_upcase (FILE *, const char *);
static void write_indent (FILE *, int);
static rtx identity_fn (rtx);
@@ -844,7 +847,7 @@ check_attr_test (file_location loc, rtx exp, attr_desc *attr)
Return a perhaps modified replacement expression for the value. */
static rtx
-check_attr_value (file_location loc, rtx exp, struct attr_desc *attr)
+check_attr_value (file_location loc, rtx exp, class attr_desc *attr)
{
struct attr_value *av;
const char *p;
@@ -954,7 +957,7 @@ check_attr_value (file_location loc, rtx exp, struct attr_desc *attr)
case ATTR:
{
- struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
+ class attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
if (attr2 == NULL)
error_at (loc, "unknown attribute `%s' in ATTR",
XSTR (exp, 0));
@@ -988,7 +991,7 @@ check_attr_value (file_location loc, rtx exp, struct attr_desc *attr)
It becomes a COND with each test being (eq_attr "alternative" "n") */
static rtx
-convert_set_attr_alternative (rtx exp, struct insn_def *id)
+convert_set_attr_alternative (rtx exp, class insn_def *id)
{
int num_alt = id->num_alternatives;
rtx condexp;
@@ -1024,7 +1027,7 @@ convert_set_attr_alternative (rtx exp, struct insn_def *id)
list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
static rtx
-convert_set_attr (rtx exp, struct insn_def *id)
+convert_set_attr (rtx exp, class insn_def *id)
{
rtx newexp;
const char *name_ptr;
@@ -1058,8 +1061,8 @@ convert_set_attr (rtx exp, struct insn_def *id)
static void
check_defs (void)
{
- struct insn_def *id;
- struct attr_desc *attr;
+ class insn_def *id;
+ class attr_desc *attr;
int i;
rtx value;
@@ -1116,7 +1119,7 @@ check_defs (void)
value. LOC is the location to use for error reporting. */
static rtx
-make_canonical (file_location loc, struct attr_desc *attr, rtx exp)
+make_canonical (file_location loc, class attr_desc *attr, rtx exp)
{
int i;
rtx newexp;
@@ -1223,7 +1226,7 @@ copy_boolean (rtx exp)
alternatives. LOC is the location to use for error reporting. */
static struct attr_value *
-get_attr_value (file_location loc, rtx value, struct attr_desc *attr,
+get_attr_value (file_location loc, rtx value, class attr_desc *attr,
int insn_code)
{
struct attr_value *av;
@@ -1273,7 +1276,7 @@ get_attr_value (file_location loc, rtx value, struct attr_desc *attr,
static void
expand_delays (void)
{
- struct delay_desc *delay;
+ class delay_desc *delay;
rtx condexp;
rtx newexp;
int i;
@@ -1359,11 +1362,11 @@ expand_delays (void)
the attribute. */
static void
-fill_attr (struct attr_desc *attr)
+fill_attr (class attr_desc *attr)
{
struct attr_value *av;
struct insn_ent *ie;
- struct insn_def *id;
+ class insn_def *id;
int i;
rtx value;
@@ -1488,7 +1491,7 @@ make_length_attrs (void)
static rtx (*const address_fn[]) (rtx)
= {max_fn, min_fn, one_fn, identity_fn};
size_t i;
- struct attr_desc *length_attr, *new_attr;
+ class attr_desc *length_attr, *new_attr;
struct attr_value *av, *new_av;
struct insn_ent *ie, *new_ie;
@@ -1562,7 +1565,7 @@ min_fn (rtx exp)
static void
write_length_unit_log (FILE *outf)
{
- struct attr_desc *length_attr = find_attr (&length_str, 0);
+ class attr_desc *length_attr = find_attr (&length_str, 0);
struct attr_value *av;
struct insn_ent *ie;
unsigned int length_unit_log, length_or;
@@ -1921,7 +1924,7 @@ make_alternative_compare (alternative_mask mask)
corresponding to INSN_CODE and INSN_INDEX. */
static rtx
-evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
+evaluate_eq_attr (rtx exp, class attr_desc *attr, rtx value,
int insn_code, int insn_index)
{
rtx orexp, andexp;
@@ -2414,7 +2417,7 @@ static rtx
simplify_test_exp (rtx exp, int insn_code, int insn_index)
{
rtx left, right;
- struct attr_desc *attr;
+ class attr_desc *attr;
struct attr_value *av;
struct insn_ent *ie;
struct attr_value_list *iv;
@@ -2755,7 +2758,7 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index)
otherwise return 0. */
static int
-tests_attr_p (rtx p, struct attr_desc *attr)
+tests_attr_p (rtx p, class attr_desc *attr)
{
const char *fmt;
int i, ie, j, je;
@@ -2796,18 +2799,18 @@ tests_attr_p (rtx p, struct attr_desc *attr)
attr_desc pointers), and return the size of that array. */
static int
-get_attr_order (struct attr_desc ***ret)
+get_attr_order (class attr_desc ***ret)
{
int i, j;
int num = 0;
- struct attr_desc *attr;
- struct attr_desc **all, **sorted;
+ class attr_desc *attr;
+ class attr_desc **all, **sorted;
char *handled;
for (i = 0; i < MAX_ATTRS_INDEX; i++)
for (attr = attrs[i]; attr; attr = attr->next)
num++;
- all = XNEWVEC (struct attr_desc *, num);
- sorted = XNEWVEC (struct attr_desc *, num);
+ all = XNEWVEC (class attr_desc *, num);
+ sorted = XNEWVEC (class attr_desc *, num);
handled = XCNEWVEC (char, num);
num = 0;
for (i = 0; i < MAX_ATTRS_INDEX; i++)
@@ -2855,7 +2858,7 @@ get_attr_order (struct attr_desc ***ret)
if (DEBUG)
for (j = 0; j < num; j++)
{
- struct attr_desc *attr2;
+ class attr_desc *attr2;
struct attr_value *av;
attr = sorted[j];
@@ -2886,14 +2889,14 @@ get_attr_order (struct attr_desc ***ret)
static void
optimize_attrs (int num_insn_codes)
{
- struct attr_desc *attr;
+ class attr_desc *attr;
struct attr_value *av;
struct insn_ent *ie;
rtx newexp;
int i;
struct attr_value_list *ivbuf;
struct attr_value_list *iv;
- struct attr_desc **topsort;
+ class attr_desc **topsort;
int topnum;
/* For each insn code, make a list of all the insn_ent's for it,
@@ -3041,7 +3044,7 @@ clear_struct_flag (rtx x)
/* Add attribute value NAME to the beginning of ATTR's list. */
static void
-add_attr_value (struct attr_desc *attr, const char *name)
+add_attr_value (class attr_desc *attr, const char *name)
{
struct attr_value *av;
@@ -3061,7 +3064,7 @@ gen_attr (md_rtx_info *info)
{
struct enum_type *et;
struct enum_value *ev;
- struct attr_desc *attr;
+ class attr_desc *attr;
const char *name_ptr;
char *p;
rtx def = info->def;
@@ -3192,10 +3195,10 @@ compares_alternatives_p (rtx exp)
static void
gen_insn (md_rtx_info *info)
{
- struct insn_def *id;
+ class insn_def *id;
rtx def = info->def;
- id = oballoc (struct insn_def);
+ id = oballoc (class insn_def);
id->next = defs;
defs = id;
id->def = def;
@@ -3240,7 +3243,7 @@ gen_insn (md_rtx_info *info)
static void
gen_delay (md_rtx_info *info)
{
- struct delay_desc *delay;
+ class delay_desc *delay;
int i;
rtx def = info->def;
@@ -3259,7 +3262,7 @@ gen_delay (md_rtx_info *info)
have_annul_false = 1;
}
- delay = oballoc (struct delay_desc);
+ delay = oballoc (class delay_desc);
delay->def = def;
delay->num = ++num_delays;
delay->next = delays;
@@ -3286,7 +3289,7 @@ find_attrs_to_cache (rtx exp, bool create)
{
int i;
const char *name;
- struct attr_desc *attr;
+ class attr_desc *attr;
if (exp == NULL)
return;
@@ -3366,7 +3369,7 @@ write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
{
int comparison_operator = 0;
RTX_CODE code;
- struct attr_desc *attr;
+ class attr_desc *attr;
if (emit_parens)
fprintf (outf, "(");
@@ -4039,7 +4042,7 @@ walk_attr_value (rtx exp)
/* Write out a function to obtain the attribute for a given INSN. */
static void
-write_attr_get (FILE *outf, struct attr_desc *attr)
+write_attr_get (FILE *outf, class attr_desc *attr)
{
struct attr_value *av, *common_av;
int i, j;
@@ -4096,7 +4099,7 @@ write_attr_get (FILE *outf, struct attr_desc *attr)
if ((attrs_seen_more_than_once & (1U << i)) != 0)
{
const char *name = cached_attrs[i];
- struct attr_desc *cached_attr;
+ class attr_desc *cached_attr;
if (i != j)
cached_attrs[j] = name;
cached_attr = find_attr (&name, 0);
@@ -4160,7 +4163,7 @@ eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
and ";"). */
static void
-write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
+write_attr_set (FILE *outf, class attr_desc *attr, int indent, rtx value,
const char *prefix, const char *suffix, rtx known_true,
int insn_code, int insn_index, unsigned int attrs_cached)
{
@@ -4288,7 +4291,7 @@ write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
/* Write out the computation for one attribute value. */
static void
-write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
+write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
int write_case_lines, const char *prefix, const char *suffix,
int indent, rtx known_true)
{
@@ -4352,7 +4355,7 @@ write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
/* Utilities to write in various forms. */
static void
-write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
+write_attr_valueq (FILE *outf, class attr_desc *attr, const char *s)
{
if (attr->is_numeric)
{
@@ -4372,7 +4375,7 @@ write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
}
static void
-write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
+write_attr_value (FILE *outf, class attr_desc *attr, rtx value)
{
int op;
@@ -4392,7 +4395,7 @@ write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
case ATTR:
{
- struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
+ class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
if (attr->enum_name)
fprintf (outf, "(enum %s)", attr->enum_name);
else if (!attr->is_numeric)
@@ -4500,11 +4503,11 @@ write_dummy_eligible_delay (FILE *outf, const char *kind)
static void
write_eligible_delay (FILE *outf, const char *kind)
{
- struct delay_desc *delay;
+ class delay_desc *delay;
int max_slots;
char str[50];
const char *pstr;
- struct attr_desc *attr;
+ class attr_desc *attr;
struct attr_value *av, *common_av;
int i;
@@ -4636,14 +4639,14 @@ next_comma_elt (const char **pstr)
return attr_string (start, *pstr - start);
}
-/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
+/* Return a `class attr_desc' pointer for a given named attribute. If CREATE
is nonzero, build a new attribute, if one does not exist. *NAME_P is
replaced by a pointer to a canonical copy of the string. */
-static struct attr_desc *
+static class attr_desc *
find_attr (const char **name_p, int create)
{
- struct attr_desc *attr;
+ class attr_desc *attr;
int index;
const char *name = *name_p;
@@ -4668,7 +4671,7 @@ find_attr (const char **name_p, int create)
if (! create)
return NULL;
- attr = oballoc (struct attr_desc);
+ attr = oballoc (class attr_desc);
attr->name = DEF_ATTR_STRING (name);
attr->enum_name = 0;
attr->first_value = attr->default_val = NULL;
@@ -4686,7 +4689,7 @@ find_attr (const char **name_p, int create)
static void
make_internal_attr (const char *name, rtx value, int special)
{
- struct attr_desc *attr;
+ class attr_desc *attr;
attr = find_attr (&name, 1);
gcc_assert (!attr->default_val);
@@ -4701,7 +4704,7 @@ make_internal_attr (const char *name, rtx value, int special)
/* Find the most used value of an attribute. */
static struct attr_value *
-find_most_used (struct attr_desc *attr)
+find_most_used (class attr_desc *attr)
{
struct attr_value *av;
struct attr_value *most_used;
@@ -4756,7 +4759,7 @@ copy_rtx_unchanging (rtx orig)
static void
write_const_num_delay_slots (FILE *outf)
{
- struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
+ class attr_desc *attr = find_attr (&num_delay_slots_str, 0);
struct attr_value *av;
if (attr)
@@ -4812,7 +4815,7 @@ gen_insn_reserv (md_rtx_info *info)
struct insn_reserv *decl = oballoc (struct insn_reserv);
rtx def = info->def;
- struct attr_desc attr = { };
+ class attr_desc attr = { };
attr.name = DEF_ATTR_STRING (XSTR (def, 0));
attr.loc = info->loc;
@@ -4929,10 +4932,10 @@ check_tune_attr (const char *name, rtx exp)
/* Try to find a const attribute (usually cpu or tune) that is used
in all define_insn_reservation conditions. */
-static struct attr_desc *
+static class attr_desc *
find_tune_attr (rtx exp)
{
- struct attr_desc *attr;
+ class attr_desc *attr;
switch (GET_CODE (exp))
{
@@ -4976,7 +4979,7 @@ make_automaton_attrs (void)
int i;
struct insn_reserv *decl;
rtx code_exp, lats_exp, byps_exp;
- struct attr_desc *tune_attr;
+ class attr_desc *tune_attr;
if (n_insn_reservs == 0)
return;
@@ -5242,8 +5245,8 @@ handle_arg (const char *arg)
int
main (int argc, const char **argv)
{
- struct attr_desc *attr;
- struct insn_def *id;
+ class attr_desc *attr;
+ class insn_def *id;
int i;
progname = "genattrtab";
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 83f86a3..3ff8197 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -811,42 +811,45 @@ handle_overloaded_code_for (overloaded_name *oname)
static void
handle_overloaded_gen (overloaded_name *oname)
{
+ unsigned HOST_WIDE_INT seen = 0;
/* All patterns must have the same number of operands. */
- pattern_stats stats;
- get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1));
for (overloaded_instance *instance = oname->first_instance->next;
instance; instance = instance->next)
{
- pattern_stats stats2;
- get_pattern_stats (&stats2, XVEC (instance->insn, 1));
- if (stats.num_generator_args != stats2.num_generator_args)
- fatal_at (get_file_location (instance->insn),
- "inconsistent number of operands for '%s'; "
- "this instance has %d, but previous instances had %d",
- oname->name, stats2.num_generator_args,
- stats.num_generator_args);
+ pattern_stats stats;
+ get_pattern_stats (&stats, XVEC (instance->insn, 1));
+ unsigned HOST_WIDE_INT mask
+ = HOST_WIDE_INT_1U << stats.num_generator_args;
+ if (seen & mask)
+ continue;
+
+ seen |= mask;
+
+ /* Print the function prototype. */
+ printf ("\nrtx\nmaybe_gen_%s (", oname->name);
+ print_overload_arguments (oname);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ printf (", rtx x%d", i);
+ printf (")\n{\n");
+
+ /* Use maybe_code_for_*, instead of duplicating the selection
+ logic here. */
+ printf (" insn_code code = maybe_code_for_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ printf ("%sarg%d", i == 0 ? "" : ", ", i);
+ printf (");\n"
+ " if (code != CODE_FOR_nothing)\n"
+ " {\n"
+ " gcc_assert (insn_data[code].n_generator_args == %d);\n"
+ " return GEN_FCN (code) (", stats.num_generator_args);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ printf ("%sx%d", i == 0 ? "" : ", ", i);
+ printf (");\n"
+ " }\n"
+ " else\n"
+ " return NULL_RTX;\n"
+ "}\n");
}
-
- /* Print the function prototype. */
- printf ("\nrtx\nmaybe_gen_%s (", oname->name);
- print_overload_arguments (oname);
- for (int i = 0; i < stats.num_generator_args; ++i)
- printf (", rtx x%d", i);
- printf (")\n{\n");
-
- /* Use maybe_code_for_*, instead of duplicating the selection logic here. */
- printf (" insn_code code = maybe_code_for_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- printf ("%sarg%d", i == 0 ? "" : ", ", i);
- printf (");\n"
- " if (code != CODE_FOR_nothing)\n"
- " return GEN_FCN (code) (");
- for (int i = 0; i < stats.num_generator_args; ++i)
- printf ("%sx%d", i == 0 ? "" : ", ", i);
- printf (");\n"
- " else\n"
- " return NULL_RTX;\n"
- "}\n");
}
int
diff --git a/gcc/genextract.c b/gcc/genextract.c
index b26f56a..5dff683 100644
--- a/gcc/genextract.c
+++ b/gcc/genextract.c
@@ -68,8 +68,9 @@ static struct code_ptr *peepholes;
data that will be used to produce an extractions structure. */
-struct accum_extract
+class accum_extract
{
+public:
accum_extract () : oplocs (10), duplocs (10), dupnums (10), pathstr (20) {}
auto_vec<locstr> oplocs;
@@ -79,7 +80,7 @@ struct accum_extract
};
/* Forward declarations. */
-static void walk_rtx (md_rtx_info *, rtx, struct accum_extract *);
+static void walk_rtx (md_rtx_info *, rtx, class accum_extract *);
#define UPPER_OFFSET ('A' - ('z' - 'a' + 1))
@@ -88,7 +89,7 @@ static void walk_rtx (md_rtx_info *, rtx, struct accum_extract *);
in ACC. */
static void
push_pathstr_operand (int operand, bool is_vector,
- struct accum_extract *acc)
+ class accum_extract *acc)
{
if (is_vector && 'a' + operand > 'z')
acc->pathstr.safe_push (operand + UPPER_OFFSET);
@@ -105,7 +106,7 @@ gen_insn (md_rtx_info *info)
unsigned int op_count, dup_count, j;
struct extraction *p;
struct code_ptr *link;
- struct accum_extract acc;
+ class accum_extract acc;
/* Walk the insn's pattern, remembering at all times the path
down to the walking point. */
@@ -223,7 +224,7 @@ VEC_char_to_string (vec<char> v)
}
static void
-walk_rtx (md_rtx_info *info, rtx x, struct accum_extract *acc)
+walk_rtx (md_rtx_info *info, rtx x, class accum_extract *acc)
{
RTX_CODE code;
int i, len;
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 109bd9e..2e7bf27 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -50,7 +50,7 @@ unsigned verbose;
/* libccp helpers. */
-static struct line_maps *line_table;
+static class line_maps *line_table;
/* The rich_location class within libcpp requires a way to expand
location_t instances, and relies on the client code
@@ -347,8 +347,9 @@ comparison_code_p (enum tree_code code)
/* Base class for all identifiers the parser knows. */
-struct id_base : nofree_ptr_hash<id_base>
+class id_base : public nofree_ptr_hash<id_base>
{
+public:
enum id_kind { CODE, FN, PREDICATE, USER, NULL_ID } kind;
id_base (id_kind, const char *, int = -1);
@@ -393,8 +394,9 @@ id_base::id_base (id_kind kind_, const char *id_, int nargs_)
/* Identifier that maps to a tree code. */
-struct operator_id : public id_base
+class operator_id : public id_base
{
+public:
operator_id (enum tree_code code_, const char *id_, unsigned nargs_,
const char *tcc_)
: id_base (id_base::CODE, id_, nargs_), code (code_), tcc (tcc_) {}
@@ -404,8 +406,9 @@ struct operator_id : public id_base
/* Identifier that maps to a builtin or internal function code. */
-struct fn_id : public id_base
+class fn_id : public id_base
{
+public:
fn_id (enum built_in_function fn_, const char *id_)
: id_base (id_base::FN, id_), fn (fn_) {}
fn_id (enum internal_fn fn_, const char *id_)
@@ -413,12 +416,13 @@ struct fn_id : public id_base
unsigned int fn;
};
-struct simplify;
+class simplify;
/* Identifier that maps to a user-defined predicate. */
-struct predicate_id : public id_base
+class predicate_id : public id_base
{
+public:
predicate_id (const char *id_)
: id_base (id_base::PREDICATE, id_), matchers (vNULL) {}
vec<simplify *> matchers;
@@ -426,8 +430,9 @@ struct predicate_id : public id_base
/* Identifier that maps to a operator defined by a 'for' directive. */
-struct user_id : public id_base
+class user_id : public id_base
{
+public:
user_id (const char *id_, bool is_oper_list_ = false)
: id_base (id_base::USER, id_), substitutes (vNULL),
used (false), is_oper_list (is_oper_list_) {}
@@ -660,12 +665,13 @@ typedef hash_map<nofree_string_hash, unsigned> cid_map_t;
/* The AST produced by parsing of the pattern definitions. */
-struct dt_operand;
-struct capture_info;
+class dt_operand;
+class capture_info;
/* The base class for operands. */
-struct operand {
+class operand {
+public:
enum op_type { OP_PREDICATE, OP_EXPR, OP_CAPTURE, OP_C_EXPR, OP_IF, OP_WITH };
operand (enum op_type type_, location_t loc_)
: type (type_), location (loc_) {}
@@ -680,8 +686,9 @@ struct operand {
/* A predicate operand. Predicates are leafs in the AST. */
-struct predicate : public operand
+class predicate : public operand
{
+public:
predicate (predicate_id *p_, location_t loc)
: operand (OP_PREDICATE, loc), p (p_) {}
predicate_id *p;
@@ -690,8 +697,9 @@ struct predicate : public operand
/* An operand that constitutes an expression. Expressions include
function calls and user-defined predicate invocations. */
-struct expr : public operand
+class expr : public operand
{
+public:
expr (id_base *operation_, location_t loc, bool is_commutative_ = false)
: operand (OP_EXPR, loc), operation (operation_),
ops (vNULL), expr_type (NULL), is_commutative (is_commutative_),
@@ -723,11 +731,13 @@ struct expr : public operand
a leaf operand in the AST. This class is also used to represent
the code to be generated for 'if' and 'with' expressions. */
-struct c_expr : public operand
+class c_expr : public operand
{
+public:
/* A mapping of an identifier and its replacement. Used to apply
'for' lowering. */
- struct id_tab {
+ class id_tab {
+ public:
const char *id;
const char *oper;
id_tab (const char *id_, const char *oper_): id (id_), oper (oper_) {}
@@ -753,8 +763,9 @@ struct c_expr : public operand
/* A wrapper around another operand that captures its value. */
-struct capture : public operand
+class capture : public operand
{
+public:
capture (location_t loc, unsigned where_, operand *what_, bool value_)
: operand (OP_CAPTURE, loc), where (where_), value_match (value_),
what (what_) {}
@@ -773,8 +784,9 @@ struct capture : public operand
/* if expression. */
-struct if_expr : public operand
+class if_expr : public operand
{
+public:
if_expr (location_t loc)
: operand (OP_IF, loc), cond (NULL), trueexpr (NULL), falseexpr (NULL) {}
c_expr *cond;
@@ -784,8 +796,9 @@ struct if_expr : public operand
/* with expression. */
-struct with_expr : public operand
+class with_expr : public operand
{
+public:
with_expr (location_t loc)
: operand (OP_WITH, loc), with (NULL), subexpr (NULL) {}
c_expr *with;
@@ -845,8 +858,9 @@ is_a_helper <with_expr *>::test (operand *op)
duplicates all outer 'if' and 'for' expressions here so each
simplify can exist in isolation. */
-struct simplify
+class simplify
{
+public:
enum simplify_kind { SIMPLIFY, MATCH };
simplify (simplify_kind kind_, unsigned id_, operand *match_,
@@ -866,7 +880,7 @@ struct simplify
produced when the pattern applies in the leafs.
For a (match ...) the leafs are either empty if it is a simple predicate
or the single expression specifying the matched operands. */
- struct operand *result;
+ class operand *result;
/* Collected 'for' expression operators that have to be replaced
in the lowering phase. */
vec<vec<user_id *> > for_vec;
@@ -919,7 +933,7 @@ print_operand (operand *o, FILE *f = stderr, bool flattened = false)
}
DEBUG_FUNCTION void
-print_matches (struct simplify *s, FILE *f = stderr)
+print_matches (class simplify *s, FILE *f = stderr)
{
fprintf (f, "for expression: ");
print_operand (s->match, f);
@@ -1569,7 +1583,7 @@ lower (vec<simplify *>& simplifiers, bool gimple)
matching code. It represents the 'match' expression of all
simplifies and has those as its leafs. */
-struct dt_simplify;
+class dt_simplify;
/* A hash-map collecting semantically equivalent leafs in the decision
tree for splitting out to separate functions. */
@@ -1598,8 +1612,9 @@ static unsigned current_id;
/* Decision tree base class, used for DT_NODE. */
-struct dt_node
+class dt_node
{
+public:
enum dt_type { DT_NODE, DT_OPERAND, DT_TRUE, DT_MATCH, DT_SIMPLIFY };
enum dt_type type;
@@ -1634,8 +1649,9 @@ struct dt_node
/* Generic decision tree node used for DT_OPERAND, DT_MATCH and DT_TRUE. */
-struct dt_operand : public dt_node
+class dt_operand : public dt_node
{
+public:
operand *op;
dt_operand *match_dop;
unsigned pos;
@@ -1660,8 +1676,9 @@ struct dt_operand : public dt_node
/* Leaf node of the decision tree, used for DT_SIMPLIFY. */
-struct dt_simplify : public dt_node
+class dt_simplify : public dt_node
{
+public:
simplify *s;
unsigned pattern_no;
dt_operand **indexes;
@@ -1697,11 +1714,12 @@ is_a_helper <dt_simplify *>::test (dt_node *n)
/* A container for the actual decision tree. */
-struct decision_tree
+class decision_tree
{
+public:
dt_node *root;
- void insert (struct simplify *, unsigned);
+ void insert (class simplify *, unsigned);
void gen (FILE *f, bool gimple);
void print (FILE *f = stderr);
@@ -2007,7 +2025,7 @@ at_assert_elm:
/* Insert S into the decision tree. */
void
-decision_tree::insert (struct simplify *s, unsigned pattern_no)
+decision_tree::insert (class simplify *s, unsigned pattern_no)
{
current_id = s->id;
dt_operand **indexes = XCNEWVEC (dt_operand *, s->capture_max + 1);
@@ -2070,8 +2088,9 @@ decision_tree::print (FILE *f)
on the outermost match expression operands for cases we cannot
handle. */
-struct capture_info
+class capture_info
{
+public:
capture_info (simplify *s, operand *, bool);
void walk_match (operand *o, unsigned toplevel_arg, bool, bool);
bool walk_result (operand *o, bool, operand *);
@@ -4171,7 +4190,7 @@ parser::parse_operation ()
/* Parse a capture.
capture = '@'<number> */
-struct operand *
+class operand *
parser::parse_capture (operand *op, bool require_existing)
{
location_t src_loc = eat_token (CPP_ATSIGN)->src_loc;
@@ -4208,7 +4227,7 @@ parser::parse_capture (operand *op, bool require_existing)
/* Parse an expression
expr = '(' <operation>[capture][flag][type] <operand>... ')' */
-struct operand *
+class operand *
parser::parse_expr ()
{
const cpp_token *token = peek ();
@@ -4376,11 +4395,11 @@ parser::parse_c_expr (cpp_ttype start)
a standalone capture.
op = predicate | expr | c_expr | capture */
-struct operand *
+class operand *
parser::parse_op ()
{
const cpp_token *token = peek ();
- struct operand *op = NULL;
+ class operand *op = NULL;
if (token->type == CPP_OPEN_PAREN)
{
eat_token (CPP_OPEN_PAREN);
@@ -4599,7 +4618,7 @@ parser::parse_simplify (simplify::simplify_kind kind,
const cpp_token *loc = peek ();
parsing_match_operand = true;
- struct operand *match = parse_op ();
+ class operand *match = parse_op ();
finish_match_operand (match);
parsing_match_operand = false;
if (match->type == operand::OP_CAPTURE && !matcher)
@@ -5071,7 +5090,7 @@ main (int argc, char **argv)
}
}
- line_table = XCNEW (struct line_maps);
+ line_table = XCNEW (class line_maps);
linemap_init (line_table, 0);
line_table->reallocator = xrealloc;
line_table->round_alloc_size = round_alloc_size;
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index ea4c3ce..1dd1d82 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -134,31 +134,43 @@ handle_overloaded_code_for (FILE *file, overloaded_name *oname)
static void
handle_overloaded_gen (FILE *file, overloaded_name *oname)
{
- pattern_stats stats;
- get_pattern_stats (&stats, XVEC (oname->first_instance->insn, 1));
-
- fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
- for (int i = 0; i < stats.num_generator_args; ++i)
- fprintf (file, ", rtx");
- fprintf (file, ");\n");
-
- fprintf (file, "inline rtx\ngen_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ", oname->arg_types[i], i);
- for (int i = 0; i < stats.num_generator_args; ++i)
- fprintf (file, ", rtx x%d", i);
- fprintf (file, ")\n{\n rtx res = maybe_gen_%s (", oname->name);
- for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
- fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
- for (int i = 0; i < stats.num_generator_args; ++i)
- fprintf (file, ", x%d", i);
- fprintf (file,
- ");\n"
- " gcc_assert (res);\n"
- " return res;\n"
- "}\n");
+ unsigned HOST_WIDE_INT seen = 0;
+ for (overloaded_instance *instance = oname->first_instance->next;
+ instance; instance = instance->next)
+ {
+ pattern_stats stats;
+ get_pattern_stats (&stats, XVEC (instance->insn, 1));
+ unsigned HOST_WIDE_INT mask
+ = HOST_WIDE_INT_1U << stats.num_generator_args;
+ if (seen & mask)
+ continue;
+
+ seen |= mask;
+
+ fprintf (file, "\nextern rtx maybe_gen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s", i == 0 ? "" : ", ", oname->arg_types[i]);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", rtx");
+ fprintf (file, ");\n");
+
+ fprintf (file, "inline rtx\ngen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%s%s arg%d", i == 0 ? "" : ", ",
+ oname->arg_types[i], i);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", rtx x%d", i);
+ fprintf (file, ")\n{\n rtx res = maybe_gen_%s (", oname->name);
+ for (unsigned int i = 0; i < oname->arg_types.length (); ++i)
+ fprintf (file, "%sarg%d", i == 0 ? "" : ", ", i);
+ for (int i = 0; i < stats.num_generator_args; ++i)
+ fprintf (file, ", x%d", i);
+ fprintf (file,
+ ");\n"
+ " gcc_assert (res);\n"
+ " return res;\n"
+ "}\n");
+ }
}
int
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 37ee509..03fa482 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -143,9 +143,10 @@ static struct operand_data **odata_end = &null_operand.next;
/* Record in this chain all information that we will output,
associated with the code number of the insn. */
-struct data
+class data
{
- struct data *next;
+public:
+ class data *next;
const char *name;
const char *template_code;
file_location loc;
@@ -160,28 +161,29 @@ struct data
};
/* This variable points to the first link in the insn chain. */
-static struct data *idata;
+static class data *idata;
/* This variable points to the end of the insn chain. This is where
everything relevant from the machien description is appended to. */
-static struct data **idata_end;
+static class data **idata_end;
static void output_prologue (void);
static void output_operand_data (void);
static void output_insn_data (void);
static void output_get_insn_name (void);
-static void scan_operands (struct data *, rtx, int, int);
+static void scan_operands (class data *, rtx, int, int);
static int compare_operands (struct operand_data *,
struct operand_data *);
-static void place_operands (struct data *);
-static void process_template (struct data *, const char *);
-static void validate_insn_alternatives (struct data *);
-static void validate_insn_operands (struct data *);
+static void place_operands (class data *);
+static void process_template (class data *, const char *);
+static void validate_insn_alternatives (class data *);
+static void validate_insn_operands (class data *);
-struct constraint_data
+class constraint_data
{
- struct constraint_data *next_this_letter;
+public:
+ class constraint_data *next_this_letter;
file_location loc;
unsigned int namelen;
char name[1];
@@ -191,7 +193,7 @@ struct constraint_data
are handled outside the define*_constraint mechanism. */
static const char indep_constraints[] = ",=+%*?!^$#&g";
-static struct constraint_data *
+static class constraint_data *
constraints_by_letter_table[1 << CHAR_BIT];
static int mdep_constraint_len (const char *, file_location, int);
@@ -275,12 +277,12 @@ output_operand_data (void)
static void
output_insn_data (void)
{
- struct data *d;
+ class data *d;
int name_offset = 0;
int next_name_offset;
const char * last_name = 0;
const char * next_name = 0;
- struct data *n;
+ class data *n;
for (n = idata, next_name_offset = 1; n; n = n->next, next_name_offset++)
if (n->name)
@@ -421,7 +423,7 @@ output_get_insn_name (void)
THIS_STRICT_LOW is nonzero if the containing rtx was a STRICT_LOW_PART. */
static void
-scan_operands (struct data *d, rtx part, int this_address_p,
+scan_operands (class data *d, rtx part, int this_address_p,
int this_strict_low)
{
int i, j;
@@ -563,7 +565,7 @@ compare_operands (struct operand_data *d0, struct operand_data *d1)
find a subsequence that is the same, or allocate a new one at the end. */
static void
-place_operands (struct data *d)
+place_operands (class data *d)
{
struct operand_data *od, *od2;
int i;
@@ -617,7 +619,7 @@ place_operands (struct data *d)
templates, or C code to generate the assembler code template. */
static void
-process_template (struct data *d, const char *template_code)
+process_template (class data *d, const char *template_code)
{
const char *cp;
int i;
@@ -740,7 +742,7 @@ process_template (struct data *d, const char *template_code)
/* Check insn D for consistency in number of constraint alternatives. */
static void
-validate_insn_alternatives (struct data *d)
+validate_insn_alternatives (class data *d)
{
int n = 0, start;
@@ -823,7 +825,7 @@ validate_insn_alternatives (struct data *d)
/* Verify that there are no gaps in operand numbers for INSNs. */
static void
-validate_insn_operands (struct data *d)
+validate_insn_operands (class data *d)
{
int i;
@@ -833,7 +835,7 @@ validate_insn_operands (struct data *d)
}
static void
-validate_optab_operands (struct data *d)
+validate_optab_operands (class data *d)
{
if (!d->name || d->name[0] == '\0' || d->name[0] == '*')
return;
@@ -978,7 +980,7 @@ gen_expand (md_rtx_info *info)
static void
init_insn_for_nothing (void)
{
- idata = XCNEW (struct data);
+ idata = XCNEW (class data);
new (idata) data ();
idata->name = "*placeholder_for_nothing";
idata->loc = file_location ("<internal>", 0, 0);
@@ -1086,7 +1088,7 @@ note_constraint (md_rtx_info *info)
{
rtx exp = info->def;
const char *name = XSTR (exp, 0);
- struct constraint_data **iter, **slot, *new_cdata;
+ class constraint_data **iter, **slot, *new_cdata;
if (strcmp (name, "TARGET_MEM_CONSTRAINT") == 0)
name = general_mem;
@@ -1136,8 +1138,8 @@ note_constraint (md_rtx_info *info)
return;
}
}
- new_cdata = XNEWVAR (struct constraint_data,
- sizeof (struct constraint_data) + namelen);
+ new_cdata = XNEWVAR (class constraint_data,
+ sizeof (class constraint_data) + namelen);
new (new_cdata) constraint_data ();
strcpy (CONST_CAST (char *, new_cdata->name), name);
new_cdata->namelen = namelen;
@@ -1153,7 +1155,7 @@ note_constraint (md_rtx_info *info)
static int
mdep_constraint_len (const char *s, file_location loc, int opno)
{
- struct constraint_data *p;
+ class constraint_data *p;
p = constraints_by_letter_table[(unsigned int)s[0]];
diff --git a/gcc/genpreds.c b/gcc/genpreds.c
index 19b7dcb..556c4bd 100644
--- a/gcc/genpreds.c
+++ b/gcc/genpreds.c
@@ -666,10 +666,11 @@ write_one_predicate_function (struct pred_data *p)
verify that there are no duplicate names. */
/* All data from one constraint definition. */
-struct constraint_data
+class constraint_data
{
- struct constraint_data *next_this_letter;
- struct constraint_data *next_textual;
+public:
+ class constraint_data *next_this_letter;
+ class constraint_data *next_textual;
const char *name;
const char *c_name; /* same as .name unless mangling is necessary */
file_location loc; /* location of definition */
@@ -689,13 +690,13 @@ struct constraint_data
/* Overview of all constraints beginning with a given letter. */
-static struct constraint_data *
+static class constraint_data *
constraints_by_letter_table[1<<CHAR_BIT];
/* For looking up all the constraints in the order that they appeared
in the machine description. */
-static struct constraint_data *first_constraint;
-static struct constraint_data **last_constraint_ptr = &first_constraint;
+static class constraint_data *first_constraint;
+static class constraint_data **last_constraint_ptr = &first_constraint;
#define FOR_ALL_CONSTRAINTS(iter_) \
for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
@@ -774,7 +775,7 @@ add_constraint (const char *name, const char *regclass,
rtx exp, bool is_memory, bool is_special_memory,
bool is_address, file_location loc)
{
- struct constraint_data *c, **iter, **slot;
+ class constraint_data *c, **iter, **slot;
const char *p;
bool need_mangled_name = false;
bool is_const_int;
@@ -908,7 +909,7 @@ add_constraint (const char *name, const char *regclass,
}
- c = XOBNEW (rtl_obstack, struct constraint_data);
+ c = XOBNEW (rtl_obstack, class constraint_data);
c->name = name;
c->c_name = need_mangled_name ? mangle (name) : name;
c->loc = loc;
@@ -979,7 +980,7 @@ process_define_register_constraint (md_rtx_info *info)
static void
choose_enum_order (void)
{
- struct constraint_data *c;
+ class constraint_data *c;
enum_order = XNEWVEC (const constraint_data *, num_constraints);
unsigned int next = 0;
@@ -1076,7 +1077,7 @@ write_lookup_constraint_1 (void)
for (i = 0; i < ARRAY_SIZE (constraints_by_letter_table); i++)
{
- struct constraint_data *c = constraints_by_letter_table[i];
+ class constraint_data *c = constraints_by_letter_table[i];
if (!c)
continue;
@@ -1116,7 +1117,7 @@ write_lookup_constraint_array (void)
{
if (i != 0)
printf (",\n ");
- struct constraint_data *c = constraints_by_letter_table[i];
+ class constraint_data *c = constraints_by_letter_table[i];
if (!c)
printf ("CONSTRAINT__UNKNOWN");
else if (c->namelen == 1)
@@ -1142,7 +1143,7 @@ write_insn_constraint_len (void)
for (i = 0; i < ARRAY_SIZE (constraints_by_letter_table); i++)
{
- struct constraint_data *c = constraints_by_letter_table[i];
+ class constraint_data *c = constraints_by_letter_table[i];
if (!c
|| c->namelen == 1)
@@ -1151,7 +1152,7 @@ write_insn_constraint_len (void)
/* Constraints with multiple characters should have the same
length. */
{
- struct constraint_data *c2 = c->next_this_letter;
+ class constraint_data *c2 = c->next_this_letter;
size_t len = c->namelen;
while (c2)
{
@@ -1177,7 +1178,7 @@ write_insn_constraint_len (void)
static void
write_reg_class_for_constraint_1 (void)
{
- struct constraint_data *c;
+ class constraint_data *c;
puts ("enum reg_class\n"
"reg_class_for_constraint_1 (enum constraint_num c)\n"
@@ -1200,7 +1201,7 @@ write_reg_class_for_constraint_1 (void)
static void
write_tm_constrs_h (void)
{
- struct constraint_data *c;
+ class constraint_data *c;
printf ("\
/* Generated automatically by the program '%s'\n\
@@ -1287,7 +1288,7 @@ write_constraint_satisfied_p_array (void)
static void
write_insn_const_int_ok_for_constraint (void)
{
- struct constraint_data *c;
+ class constraint_data *c;
puts ("bool\n"
"insn_const_int_ok_for_constraint (HOST_WIDE_INT ival, "
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 90e2508..f20089e 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -818,11 +818,13 @@ validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
to "T *prev, *next;" and a function "void set_parent (list_head <T> *)"
to set the parent list. */
template <typename T>
-struct list_head
+class list_head
{
+public:
/* A range of linked items. */
- struct range
+ class range
{
+ public:
range (T *);
range (T *, T *);
@@ -948,7 +950,7 @@ list_head <T>::singleton () const
return first == last ? first : 0;
}
-struct state;
+class state;
/* Describes a possible successful return from a routine. */
struct acceptance_type
@@ -1008,8 +1010,9 @@ operator != (const acceptance_type &a, const acceptance_type &b)
}
/* Represents a parameter to a pattern routine. */
-struct parameter
+class parameter
{
+public:
/* The C type of parameter. */
enum type_enum {
/* Represents an invalid parameter. */
@@ -1069,8 +1072,9 @@ operator != (const parameter &param1, const parameter &param2)
an ad-hoc enum value on success and -1 on failure. The routine can
be used by any subroutine type. The match can be parameterized by
things like mode, code and UNSPEC number. */
-struct pattern_routine
+class pattern_routine
{
+public:
/* The state that implements the pattern. */
state *s;
@@ -1096,8 +1100,9 @@ struct pattern_routine
static vec <pattern_routine *> patterns;
/* Represents one use of a pattern routine. */
-struct pattern_use
+class pattern_use
{
+public:
/* The pattern routine to use. */
pattern_routine *routine;
@@ -1107,8 +1112,9 @@ struct pattern_use
};
/* Represents a test performed by a decision. */
-struct rtx_test
+class rtx_test
{
+public:
rtx_test ();
/* The types of test that can be performed. Most of them take as input
@@ -1427,8 +1433,9 @@ operator != (const rtx_test &a, const rtx_test &b)
/* A simple set of transition labels. Most transitions have a singleton
label, so try to make that case as efficient as possible. */
-struct int_set : public auto_vec <uint64_t, 1>
+class int_set : public auto_vec <uint64_t, 1>
{
+public:
typedef uint64_t *iterator;
int_set ();
@@ -1492,12 +1499,13 @@ operator != (const int_set &a, const int_set &b)
return !operator == (a, b);
}
-struct decision;
+class decision;
/* Represents a transition between states, dependent on the result of
a test T. */
-struct transition
+class transition
{
+public:
transition (const int_set &, state *, bool);
void set_parent (list_head <transition> *);
@@ -1536,8 +1544,9 @@ struct transition
to the transition's target state. If no suitable transition exists,
the machine either falls through to the next decision or, if there are no
more decisions to try, fails the match. */
-struct decision : list_head <transition>
+class decision : public list_head <transition>
{
+public:
decision (const rtx_test &);
void set_parent (list_head <decision> *s);
@@ -1556,8 +1565,9 @@ struct decision : list_head <transition>
/* Represents one machine state. For each state the machine tries a list
of decisions, in order, and acts on the first match. It fails without
further backtracking if no decisions match. */
-struct state : list_head <decision>
+class state : public list_head <decision>
{
+public:
void set_parent (list_head <state> *) {}
};
@@ -1767,8 +1777,9 @@ const unsigned char TESTED_CODE = 1;
const unsigned char TESTED_VECLEN = 2;
/* Represents a set of conditions that are known to hold. */
-struct known_conditions
+class known_conditions
{
+public:
/* A mask of TESTED_ values for each position, indexed by the position's
id field. */
auto_vec <unsigned char> position_tests;
@@ -2095,8 +2106,9 @@ find_operand_positions (state *s, vec <int> &operand_pos)
}
/* Statistics about a matching routine. */
-struct stats
+class stats
{
+public:
stats ();
/* The total number of decisions in the routine, excluding trivial
@@ -2232,11 +2244,12 @@ optimize_subroutine_group (const char *type, state *root)
st.longest_backtrack, st.longest_backtrack_code);
}
-struct merge_pattern_info;
+class merge_pattern_info;
/* Represents a transition from one pattern to another. */
-struct merge_pattern_transition
+class merge_pattern_transition
{
+public:
merge_pattern_transition (merge_pattern_info *);
/* The target pattern. */
@@ -2256,8 +2269,9 @@ merge_pattern_transition::merge_pattern_transition (merge_pattern_info *to_in)
/* Represents a pattern that can might match several states. The pattern
may replace parts of the test with a parameter value. It may also
replace transition labels with parameters. */
-struct merge_pattern_info
+class merge_pattern_info
{
+public:
merge_pattern_info (unsigned int);
/* If PARAM_TEST_P, the state's singleton test should be generalized
@@ -2329,8 +2343,9 @@ merge_pattern_info::merge_pattern_info (unsigned int num_transitions)
/* Describes one way of matching a particular state to a particular
pattern. */
-struct merge_state_result
+class merge_state_result
{
+public:
merge_state_result (merge_pattern_info *, position *, merge_state_result *);
/* A pattern that matches the state. */
@@ -2360,8 +2375,9 @@ merge_state_result::merge_state_result (merge_pattern_info *pattern_in,
/* Information about a state, used while trying to match it against
a pattern. */
-struct merge_state_info
+class merge_state_info
{
+public:
merge_state_info (state *);
/* The state itself. */
@@ -3860,7 +3876,8 @@ merge_into_state (state *s1, state *s2)
/* Pairs a pattern that needs to be matched with the rtx position at
which the pattern should occur. */
-struct pattern_pos {
+class pattern_pos {
+public:
pattern_pos () {}
pattern_pos (rtx, position *);
@@ -4384,8 +4401,9 @@ enum exit_state {
/* Information used while writing out code. */
-struct output_state
+class output_state
{
+public:
/* The type of routine that we're generating. */
routine_type type;
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 0150346..1aab711 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -65,59 +65,60 @@ static htab_t condition_table;
define_cond_exec and define_subst patterns, then return
them one at a time. */
-struct queue_elem
+class queue_elem
{
+public:
rtx data;
file_location loc;
- struct queue_elem *next;
+ class queue_elem *next;
/* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT or
DEFINE_INSN_AND_REWRITE, SPLIT points to the generated DEFINE_SPLIT. */
- struct queue_elem *split;
+ class queue_elem *split;
};
#define MNEMONIC_ATTR_NAME "mnemonic"
#define MNEMONIC_HTAB_SIZE 1024
-static struct queue_elem *define_attr_queue;
-static struct queue_elem **define_attr_tail = &define_attr_queue;
-static struct queue_elem *define_pred_queue;
-static struct queue_elem **define_pred_tail = &define_pred_queue;
-static struct queue_elem *define_insn_queue;
-static struct queue_elem **define_insn_tail = &define_insn_queue;
-static struct queue_elem *define_cond_exec_queue;
-static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
-static struct queue_elem *define_subst_queue;
-static struct queue_elem **define_subst_tail = &define_subst_queue;
-static struct queue_elem *other_queue;
-static struct queue_elem **other_tail = &other_queue;
-static struct queue_elem *define_subst_attr_queue;
-static struct queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
+static class queue_elem *define_attr_queue;
+static class queue_elem **define_attr_tail = &define_attr_queue;
+static class queue_elem *define_pred_queue;
+static class queue_elem **define_pred_tail = &define_pred_queue;
+static class queue_elem *define_insn_queue;
+static class queue_elem **define_insn_tail = &define_insn_queue;
+static class queue_elem *define_cond_exec_queue;
+static class queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
+static class queue_elem *define_subst_queue;
+static class queue_elem **define_subst_tail = &define_subst_queue;
+static class queue_elem *other_queue;
+static class queue_elem **other_tail = &other_queue;
+static class queue_elem *define_subst_attr_queue;
+static class queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
/* Mapping from DEFINE_* rtxes to their location in the source file. */
static hash_map <rtx, file_location> *rtx_locs;
static void remove_constraints (rtx);
-static int is_predicable (struct queue_elem *);
+static int is_predicable (class queue_elem *);
static void identify_predicable_attribute (void);
static int n_alternatives (const char *);
static void collect_insn_data (rtx, int *, int *);
-static const char *alter_test_for_insn (struct queue_elem *,
- struct queue_elem *);
+static const char *alter_test_for_insn (class queue_elem *,
+ class queue_elem *);
static char *shift_output_template (char *, const char *, int);
-static const char *alter_output_for_insn (struct queue_elem *,
- struct queue_elem *,
+static const char *alter_output_for_insn (class queue_elem *,
+ class queue_elem *,
int, int);
-static void process_one_cond_exec (struct queue_elem *);
+static void process_one_cond_exec (class queue_elem *);
static void process_define_cond_exec (void);
static void init_predicate_table (void);
static void record_insn_name (int, const char *);
-static bool has_subst_attribute (struct queue_elem *, struct queue_elem *);
+static bool has_subst_attribute (class queue_elem *, class queue_elem *);
static const char * alter_output_for_subst_insn (rtx, int);
-static void alter_attrs_for_subst_insn (struct queue_elem *, int);
-static void process_substs_on_one_elem (struct queue_elem *,
- struct queue_elem *);
+static void alter_attrs_for_subst_insn (class queue_elem *, int);
+static void process_substs_on_one_elem (class queue_elem *,
+ class queue_elem *);
static rtx subst_dup (rtx, int, int);
static void process_define_subst (void);
@@ -399,11 +400,11 @@ process_define_predicate (rtx desc, file_location loc)
/* Queue PATTERN on LIST_TAIL. Return the address of the new queue
element. */
-static struct queue_elem *
-queue_pattern (rtx pattern, struct queue_elem ***list_tail,
+static class queue_elem *
+queue_pattern (rtx pattern, class queue_elem ***list_tail,
file_location loc)
{
- struct queue_elem *e = XNEW (struct queue_elem);
+ class queue_elem *e = XNEW (class queue_elem);
e->data = pattern;
e->loc = loc;
e->next = NULL;
@@ -415,9 +416,9 @@ queue_pattern (rtx pattern, struct queue_elem ***list_tail,
/* Remove element ELEM from QUEUE. */
static void
-remove_from_queue (struct queue_elem *elem, struct queue_elem **queue)
+remove_from_queue (class queue_elem *elem, class queue_elem **queue)
{
- struct queue_elem *prev, *e;
+ class queue_elem *prev, *e;
prev = NULL;
for (e = *queue; e ; e = e->next)
{
@@ -439,7 +440,7 @@ remove_from_queue (struct queue_elem *elem, struct queue_elem **queue)
static void
add_define_attr (const char *name)
{
- struct queue_elem *e = XNEW (struct queue_elem);
+ class queue_elem *e = XNEW (class queue_elem);
rtx t1 = rtx_alloc (DEFINE_ATTR);
XSTR (t1, 0) = name;
XSTR (t1, 1) = "no,yes";
@@ -499,12 +500,14 @@ replace_operands_with_dups (rtx x)
{
newx = rtx_alloc (MATCH_DUP);
XINT (newx, 0) = XINT (x, 0);
+ x = newx;
}
else if (GET_CODE (x) == MATCH_OPERATOR)
{
newx = rtx_alloc (MATCH_OP_DUP);
XINT (newx, 0) = XINT (x, 0);
XVEC (newx, 1) = XVEC (x, 2);
+ x = newx;
}
else
newx = shallow_copy_rtx (x);
@@ -590,8 +593,8 @@ process_rtx (rtx desc, file_location loc)
rtx split;
rtvec attr;
int i;
- struct queue_elem *insn_elem;
- struct queue_elem *split_elem;
+ class queue_elem *insn_elem;
+ class queue_elem *split_elem;
int split_code = (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE ? 5 : 6);
/* Create a split with values from the insn_and_split. */
@@ -645,7 +648,7 @@ process_rtx (rtx desc, file_location loc)
a DEFINE_INSN. */
static int
-is_predicable (struct queue_elem *elem)
+is_predicable (class queue_elem *elem)
{
rtvec vec = XVEC (elem->data, 4);
const char *value;
@@ -715,8 +718,8 @@ is_predicable (struct queue_elem *elem)
/* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
static void
-change_subst_attribute (struct queue_elem *elem,
- struct queue_elem *subst_elem,
+change_subst_attribute (class queue_elem *elem,
+ class queue_elem *subst_elem,
const char *new_value)
{
rtvec attrs_vec = XVEC (elem->data, 4);
@@ -745,7 +748,7 @@ change_subst_attribute (struct queue_elem *elem,
words, we suppose the default value of the attribute to be 'no' since it is
always generated automatically in read-rtl.c. */
static bool
-has_subst_attribute (struct queue_elem *elem, struct queue_elem *subst_elem)
+has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
{
rtvec attrs_vec = XVEC (elem->data, 4);
const char *value, *subst_name = XSTR (subst_elem->data, 0);
@@ -978,7 +981,7 @@ subst_pattern_match (rtx x, rtx pt, file_location loc)
static void
identify_predicable_attribute (void)
{
- struct queue_elem *elem;
+ class queue_elem *elem;
char *p_true, *p_false;
const char *value;
@@ -1326,8 +1329,8 @@ alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
}
static const char *
-alter_test_for_insn (struct queue_elem *ce_elem,
- struct queue_elem *insn_elem)
+alter_test_for_insn (class queue_elem *ce_elem,
+ class queue_elem *insn_elem)
{
return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
XSTR (insn_elem->data, 2));
@@ -1438,7 +1441,7 @@ alter_attrs_for_insn (rtx insn)
if (!global_changes_made)
{
- struct queue_elem *elem;
+ class queue_elem *elem;
global_changes_made = true;
add_define_attr ("ce_enabled");
@@ -1479,7 +1482,7 @@ alter_attrs_for_insn (rtx insn)
ELEM is a queue element, containing our rtl-template,
N_DUP - multiplication factor. */
static void
-alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup)
+alter_attrs_for_subst_insn (class queue_elem * elem, int n_dup)
{
rtvec vec = XVEC (elem->data, 4);
int num_elem;
@@ -1542,8 +1545,8 @@ shift_output_template (char *dest, const char *src, int disp)
}
static const char *
-alter_output_for_insn (struct queue_elem *ce_elem,
- struct queue_elem *insn_elem,
+alter_output_for_insn (class queue_elem *ce_elem,
+ class queue_elem *insn_elem,
int alt, int max_op)
{
const char *ce_out, *insn_out;
@@ -1731,9 +1734,9 @@ alter_output_for_subst_insn (rtx insn, int alt)
/* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
static void
-process_one_cond_exec (struct queue_elem *ce_elem)
+process_one_cond_exec (class queue_elem *ce_elem)
{
- struct queue_elem *insn_elem;
+ class queue_elem *insn_elem;
for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
{
int alternatives, max_operand;
@@ -1837,10 +1840,10 @@ process_one_cond_exec (struct queue_elem *ce_elem)
was applied, ELEM would be deleted. */
static void
-process_substs_on_one_elem (struct queue_elem *elem,
- struct queue_elem *queue)
+process_substs_on_one_elem (class queue_elem *elem,
+ class queue_elem *queue)
{
- struct queue_elem *subst_elem;
+ class queue_elem *subst_elem;
int i, j, patterns_match;
for (subst_elem = define_subst_queue;
@@ -2247,7 +2250,7 @@ subst_dup (rtx pattern, int n_alt, int n_subst_alt)
static void
process_define_cond_exec (void)
{
- struct queue_elem *elem;
+ class queue_elem *elem;
identify_predicable_attribute ();
if (have_error)
@@ -2263,7 +2266,7 @@ process_define_cond_exec (void)
static void
process_define_subst (void)
{
- struct queue_elem *elem, *elem_attr;
+ class queue_elem *elem, *elem_attr;
/* Check if each define_subst has corresponding define_subst_attr. */
for (elem = define_subst_queue; elem ; elem = elem->next)
@@ -2474,7 +2477,7 @@ mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
static void
gen_mnemonic_attr (void)
{
- struct queue_elem *elem;
+ class queue_elem *elem;
rtx mnemonic_attr = NULL;
htab_t mnemonic_htab;
const char *str, *p;
@@ -2551,7 +2554,7 @@ gen_mnemonic_attr (void)
static void
check_define_attr_duplicates ()
{
- struct queue_elem *elem;
+ class queue_elem *elem;
htab_t attr_htab;
char * attr_name;
void **slot;
@@ -2647,7 +2650,7 @@ read_md_rtx (md_rtx_info *info)
to use elided pattern numbers for anything. */
do
{
- struct queue_elem **queue, *elem;
+ class queue_elem **queue, *elem;
/* Read all patterns from a given queue before moving on to the next. */
if (define_attr_queue != NULL)
diff --git a/gcc/gensupport.h b/gcc/gensupport.h
index 5c43203..10a5c7a 100644
--- a/gcc/gensupport.h
+++ b/gcc/gensupport.h
@@ -26,7 +26,8 @@ struct obstack;
extern struct obstack *rtl_obstack;
/* Information about an .md define_* rtx. */
-struct md_rtx_info {
+class md_rtx_info {
+public:
/* The rtx itself. */
rtx def;
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 6fb5a3d..0968d97 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -818,8 +818,9 @@ init_ggc_heuristics (void)
}
/* GGC memory usage. */
-struct ggc_usage: public mem_usage
+class ggc_usage: public mem_usage
{
+public:
/* Default constructor. */
ggc_usage (): m_freed (0), m_collected (0), m_overhead (0) {}
/* Constructor. */
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index a95ff46..a2736bc 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -200,7 +200,7 @@ static const size_t extra_order_size_table[] = {
sizeof (struct function),
sizeof (struct basic_block_def),
sizeof (struct cgraph_node),
- sizeof (struct loop),
+ sizeof (class loop),
};
/* The total number of orders. */
diff --git a/gcc/ggc-tests.c b/gcc/ggc-tests.c
index 752f446..1ea5e4c 100644
--- a/gcc/ggc-tests.c
+++ b/gcc/ggc-tests.c
@@ -176,8 +176,9 @@ test_union ()
/* Verify that destructors get run when instances are collected. */
-struct GTY(()) test_struct_with_dtor
+class GTY(()) test_struct_with_dtor
{
+public:
/* This struct has a destructor; it *ought* to be called
by the ggc machinery when instances are collected. */
~test_struct_with_dtor () { dtor_call_count++; }
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 118718a..be83620 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -6716,14 +6716,13 @@ fold_array_ctor_reference (tree type, tree ctor,
elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
/* When TYPE is non-null, verify that it specifies a constant-sized
- accessed not larger than size of array element. Avoid division
+ access of a multiple of the array element size. Avoid division
by zero below when ELT_SIZE is zero, such as with the result of
an initializer for a zero-length array or an empty struct. */
if (elt_size == 0
|| (type
&& (!TYPE_SIZE_UNIT (type)
- || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
- || elt_size < wi::to_offset (TYPE_SIZE_UNIT (type)))))
+ || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)))
return NULL_TREE;
/* Compute the array index we look for. */
@@ -6734,10 +6733,88 @@ fold_array_ctor_reference (tree type, tree ctor,
/* And offset within the access. */
inner_offset = offset % (elt_size.to_uhwi () * BITS_PER_UNIT);
- /* See if the array field is large enough to span whole access. We do not
- care to fold accesses spanning multiple array indexes. */
- if (inner_offset + size > elt_size.to_uhwi () * BITS_PER_UNIT)
- return NULL_TREE;
+ if (size > elt_size.to_uhwi () * BITS_PER_UNIT)
+ {
+ /* native_encode_expr constraints. */
+ if (size > MAX_BITSIZE_MODE_ANY_MODE
+ || size % BITS_PER_UNIT != 0
+ || inner_offset % BITS_PER_UNIT != 0)
+ return NULL_TREE;
+
+ unsigned ctor_idx;
+ tree val = get_array_ctor_element_at_index (ctor, access_index,
+ &ctor_idx);
+ if (!val && ctor_idx >= CONSTRUCTOR_NELTS (ctor))
+ return build_zero_cst (type);
+
+ /* native-encode adjacent ctor elements. */
+ unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
+ unsigned bufoff = 0;
+ offset_int index = 0;
+ offset_int max_index = access_index;
+ constructor_elt *elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
+ if (!val)
+ val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
+ else if (!CONSTANT_CLASS_P (val))
+ return NULL_TREE;
+ if (!elt->index)
+ ;
+ else if (TREE_CODE (elt->index) == RANGE_EXPR)
+ {
+ index = wi::to_offset (TREE_OPERAND (elt->index, 0));
+ max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
+ }
+ else
+ index = max_index = wi::to_offset (elt->index);
+ index = wi::umax (index, access_index);
+ do
+ {
+ int len = native_encode_expr (val, buf + bufoff,
+ elt_size.to_uhwi (),
+ inner_offset / BITS_PER_UNIT);
+ if (len != elt_size - inner_offset / BITS_PER_UNIT)
+ return NULL_TREE;
+ inner_offset = 0;
+ bufoff += len;
+
+ access_index += 1;
+ if (wi::cmpu (access_index, index) == 0)
+ val = elt->value;
+ else if (wi::cmpu (access_index, max_index) > 0)
+ {
+ ctor_idx++;
+ if (ctor_idx >= CONSTRUCTOR_NELTS (ctor))
+ {
+ val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
+ ++max_index;
+ }
+ else
+ {
+ elt = CONSTRUCTOR_ELT (ctor, ctor_idx);
+ index = 0;
+ max_index = access_index;
+ if (!elt->index)
+ ;
+ else if (TREE_CODE (elt->index) == RANGE_EXPR)
+ {
+ index = wi::to_offset (TREE_OPERAND (elt->index, 0));
+ max_index = wi::to_offset (TREE_OPERAND (elt->index, 1));
+ }
+ else
+ index = max_index = wi::to_offset (elt->index);
+ index = wi::umax (index, access_index);
+ if (wi::cmpu (access_index, index) == 0)
+ val = elt->value;
+ else
+ val = build_zero_cst (TREE_TYPE (TREE_TYPE (ctor)));
+ }
+ }
+ }
+ while (bufoff < size / BITS_PER_UNIT);
+ *suboff += size;
+ return native_interpret_expr (type, buf, size / BITS_PER_UNIT);
+ }
+
if (tree val = get_array_ctor_element_at_index (ctor, access_index))
{
if (!size && TREE_CODE (val) != CONSTRUCTOR)
diff --git a/gcc/gimple-loop-interchange.cc b/gcc/gimple-loop-interchange.cc
index b188ce8..b56155b 100644
--- a/gcc/gimple-loop-interchange.cc
+++ b/gcc/gimple-loop-interchange.cc
@@ -159,7 +159,7 @@ dump_reduction (reduction_p re)
/* Dump LOOP's induction IV. */
static void
-dump_induction (struct loop *loop, induction_p iv)
+dump_induction (class loop *loop, induction_p iv)
{
fprintf (dump_file, " Induction: ");
print_generic_expr (dump_file, iv->var, TDF_SLIM);
@@ -172,9 +172,10 @@ dump_induction (struct loop *loop, induction_p iv)
/* Loop candidate for interchange. */
-struct loop_cand
+class loop_cand
{
- loop_cand (struct loop *, struct loop *);
+public:
+ loop_cand (class loop *, class loop *);
~loop_cand ();
reduction_p find_reduction_by_stmt (gimple *);
@@ -188,10 +189,10 @@ struct loop_cand
void undo_simple_reduction (reduction_p, bitmap);
/* The loop itself. */
- struct loop *m_loop;
+ class loop *m_loop;
/* The outer loop for interchange. It equals to loop if this loop cand
itself represents the outer loop. */
- struct loop *m_outer;
+ class loop *m_outer;
/* Vector of induction variables in loop. */
vec<induction_p> m_inductions;
/* Vector of reduction variables in loop. */
@@ -210,7 +211,7 @@ struct loop_cand
/* Constructor. */
-loop_cand::loop_cand (struct loop *loop, struct loop *outer)
+loop_cand::loop_cand (class loop *loop, class loop *outer)
: m_loop (loop), m_outer (outer), m_exit (single_exit (loop)),
m_bbs (get_loop_body (loop)), m_num_stmts (0), m_const_init_reduc (0)
{
@@ -240,7 +241,7 @@ loop_cand::~loop_cand ()
/* Return single use stmt of VAR in LOOP, otherwise return NULL. */
static gimple *
-single_use_in_loop (tree var, struct loop *loop)
+single_use_in_loop (tree var, class loop *loop)
{
gimple *stmt, *res = NULL;
use_operand_p use_p;
@@ -950,7 +951,7 @@ free_data_refs_with_aux (vec<data_reference_p> datarefs)
class tree_loop_interchange
{
public:
- tree_loop_interchange (vec<struct loop *> loop_nest)
+ tree_loop_interchange (vec<class loop *> loop_nest)
: m_loop_nest (loop_nest), m_niters_iv_var (NULL_TREE),
m_dce_seeds (BITMAP_ALLOC (NULL)) { }
~tree_loop_interchange () { BITMAP_FREE (m_dce_seeds); }
@@ -961,10 +962,10 @@ private:
bool valid_data_dependences (unsigned, unsigned, vec<ddr_p>);
void interchange_loops (loop_cand &, loop_cand &);
void map_inductions_to_loop (loop_cand &, loop_cand &);
- void move_code_to_inner_loop (struct loop *, struct loop *, basic_block *);
+ void move_code_to_inner_loop (class loop *, class loop *, basic_block *);
/* The whole loop nest in which interchange is ongoing. */
- vec<struct loop *> m_loop_nest;
+ vec<class loop *> m_loop_nest;
/* We create new IV which is only used in loop's exit condition check.
In case of 3-level loop nest interchange, when we interchange the
innermost two loops, new IV created in the middle level loop does
@@ -1078,7 +1079,7 @@ tree_loop_interchange::interchange_loops (loop_cand &iloop, loop_cand &oloop)
}
/* Prepare niters for both loops. */
- struct loop *loop_nest = m_loop_nest[0];
+ class loop *loop_nest = m_loop_nest[0];
edge instantiate_below = loop_preheader_edge (loop_nest);
gsi = gsi_last_bb (loop_preheader_edge (loop_nest)->src);
i_niters = number_of_latch_executions (iloop.m_loop);
@@ -1213,8 +1214,8 @@ tree_loop_interchange::map_inductions_to_loop (loop_cand &src, loop_cand &tgt)
/* Move stmts of outer loop to inner loop. */
void
-tree_loop_interchange::move_code_to_inner_loop (struct loop *outer,
- struct loop *inner,
+tree_loop_interchange::move_code_to_inner_loop (class loop *outer,
+ class loop *inner,
basic_block *outer_bbs)
{
basic_block oloop_exit_bb = single_exit (outer)->src;
@@ -1275,7 +1276,7 @@ tree_loop_interchange::move_code_to_inner_loop (struct loop *outer,
arr[i][j - 1][k] = 0; */
static void
-compute_access_stride (struct loop *loop_nest, struct loop *loop,
+compute_access_stride (class loop *loop_nest, class loop *loop,
data_reference_p dr)
{
vec<tree> *strides = new vec<tree> ();
@@ -1319,10 +1320,10 @@ compute_access_stride (struct loop *loop_nest, struct loop *loop,
if (! chrec_contains_undetermined (scev))
{
tree sl = scev;
- struct loop *expected = loop;
+ class loop *expected = loop;
while (TREE_CODE (sl) == POLYNOMIAL_CHREC)
{
- struct loop *sl_loop = get_chrec_loop (sl);
+ class loop *sl_loop = get_chrec_loop (sl);
while (sl_loop != expected)
{
strides->safe_push (size_int (0));
@@ -1350,8 +1351,8 @@ compute_access_stride (struct loop *loop_nest, struct loop *loop,
all data references. If access strides cannot be computed at least
for two levels of loop for any data reference, it returns NULL. */
-static struct loop *
-compute_access_strides (struct loop *loop_nest, struct loop *loop,
+static class loop *
+compute_access_strides (class loop *loop_nest, class loop *loop,
vec<data_reference_p> datarefs)
{
unsigned i, j, num_loops = (unsigned) -1;
@@ -1389,8 +1390,8 @@ compute_access_strides (struct loop *loop_nest, struct loop *loop,
of loops that isn't in current LOOP_NEST. */
static void
-prune_access_strides_not_in_loop (struct loop *loop_nest,
- struct loop *innermost,
+prune_access_strides_not_in_loop (class loop *loop_nest,
+ class loop *innermost,
vec<data_reference_p> datarefs)
{
data_reference_p dr;
@@ -1711,7 +1712,7 @@ public:
nest with LOOP. */
static bool
-proper_loop_form_for_interchange (struct loop *loop, struct loop **min_outer)
+proper_loop_form_for_interchange (class loop *loop, class loop **min_outer)
{
edge e0, e1, exit;
@@ -1810,14 +1811,14 @@ proper_loop_form_for_interchange (struct loop *loop, struct loop **min_outer)
should be interchanged by looking into all DATAREFS. */
static bool
-should_interchange_loop_nest (struct loop *loop_nest, struct loop *innermost,
+should_interchange_loop_nest (class loop *loop_nest, class loop *innermost,
vec<data_reference_p> datarefs)
{
unsigned idx = loop_depth (innermost) - loop_depth (loop_nest);
gcc_assert (idx > 0);
/* Check if any two adjacent loops should be interchanged. */
- for (struct loop *loop = innermost;
+ for (class loop *loop = innermost;
loop != loop_nest; loop = loop_outer (loop), idx--)
if (should_interchange_loops (idx, idx - 1, datarefs, 0, 0,
loop == innermost, false))
@@ -1837,7 +1838,7 @@ tree_loop_interchange_compute_ddrs (vec<loop_p> loop_nest,
vec<ddr_p> *ddrs)
{
struct data_reference *a, *b;
- struct loop *innermost = loop_nest.last ();
+ class loop *innermost = loop_nest.last ();
for (unsigned i = 0; datarefs.iterate (i, &a); ++i)
{
@@ -1879,7 +1880,7 @@ tree_loop_interchange_compute_ddrs (vec<loop_p> loop_nest,
/* Prune DATAREFS by removing any data reference not inside of LOOP. */
static inline void
-prune_datarefs_not_in_loop (struct loop *loop, vec<data_reference_p> datarefs)
+prune_datarefs_not_in_loop (class loop *loop, vec<data_reference_p> datarefs)
{
unsigned i, j;
struct data_reference *dr;
@@ -1906,10 +1907,10 @@ prune_datarefs_not_in_loop (struct loop *loop, vec<data_reference_p> datarefs)
inner loop of that basic block's father loop. On success, return the
outer loop of the result loop nest. */
-static struct loop *
-prepare_data_references (struct loop *loop, vec<data_reference_p> *datarefs)
+static class loop *
+prepare_data_references (class loop *loop, vec<data_reference_p> *datarefs)
{
- struct loop *loop_nest = loop;
+ class loop *loop_nest = loop;
vec<data_reference_p> *bb_refs;
basic_block bb, *bbs = get_loop_body_in_dom_order (loop);
@@ -1973,11 +1974,11 @@ prepare_data_references (struct loop *loop, vec<data_reference_p> *datarefs)
in interchange. */
static bool
-prepare_perfect_loop_nest (struct loop *loop, vec<loop_p> *loop_nest,
+prepare_perfect_loop_nest (class loop *loop, vec<loop_p> *loop_nest,
vec<data_reference_p> *datarefs, vec<ddr_p> *ddrs)
{
- struct loop *start_loop = NULL, *innermost = loop;
- struct loop *outermost = loops_for_fn (cfun)->tree_root;
+ class loop *start_loop = NULL, *innermost = loop;
+ class loop *outermost = loops_for_fn (cfun)->tree_root;
/* Find loop nest from the innermost loop. The outermost is the innermost
outer*/
@@ -2063,7 +2064,7 @@ pass_linterchange::execute (function *fun)
return 0;
bool changed_p = false;
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
{
vec<loop_p> loop_nest = vNULL;
diff --git a/gcc/gimple-loop-jam.c b/gcc/gimple-loop-jam.c
index 90ddbf3..11153f5 100644
--- a/gcc/gimple-loop-jam.c
+++ b/gcc/gimple-loop-jam.c
@@ -103,11 +103,11 @@ along with GCC; see the file COPYING3. If not see
to the OLD loop or the outer loop of OLD now is inside LOOP. */
static void
-merge_loop_tree (struct loop *loop, struct loop *old)
+merge_loop_tree (class loop *loop, class loop *old)
{
basic_block *bbs;
int i, n;
- struct loop *subloop;
+ class loop *subloop;
edge e;
edge_iterator ei;
@@ -186,11 +186,11 @@ bb_prevents_fusion_p (basic_block bb)
If so return true, otherwise return false. */
static bool
-unroll_jam_possible_p (struct loop *outer, struct loop *loop)
+unroll_jam_possible_p (class loop *outer, class loop *loop)
{
basic_block *bbs;
int i, n;
- struct tree_niter_desc niter;
+ class tree_niter_desc niter;
/* When fusing the loops we skip the latch block
of the first one, so it mustn't have any effects to
@@ -301,9 +301,9 @@ unroll_jam_possible_p (struct loop *outer, struct loop *loop)
be in appropriate form. */
static void
-fuse_loops (struct loop *loop)
+fuse_loops (class loop *loop)
{
- struct loop *next = loop->next;
+ class loop *next = loop->next;
while (next)
{
@@ -353,7 +353,7 @@ fuse_loops (struct loop *loop)
merge_loop_tree (loop, next);
gcc_assert (!next->num_nodes);
- struct loop *ln = next->next;
+ class loop *ln = next->next;
delete_loop (next);
next = ln;
}
@@ -422,7 +422,7 @@ adjust_unroll_factor (struct data_dependence_relation *ddr,
static unsigned int
tree_loop_unroll_and_jam (void)
{
- struct loop *loop;
+ class loop *loop;
bool changed = false;
gcc_assert (scev_initialized_p ());
@@ -430,7 +430,7 @@ tree_loop_unroll_and_jam (void)
/* Go through all innermost loops. */
FOR_EACH_LOOP (loop, LI_ONLY_INNERMOST)
{
- struct loop *outer = loop_outer (loop);
+ class loop *outer = loop_outer (loop);
if (loop_depth (loop) < 2
|| optimize_loop_nest_for_size_p (outer))
@@ -442,7 +442,7 @@ tree_loop_unroll_and_jam (void)
vec<data_reference_p> datarefs;
vec<ddr_p> dependences;
unsigned unroll_factor, profit_unroll, removed;
- struct tree_niter_desc desc;
+ class tree_niter_desc desc;
bool unroll = false;
auto_vec<loop_p, 3> loop_nest;
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index fe27300..be8c2d8 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -179,8 +179,9 @@ struct address_term_info
/* Information about an address calculation, and the range of constant
offsets applied to it. */
-struct address_info
+class address_info
{
+public:
static const unsigned int MAX_TERMS = 8;
/* One statement that calculates the address. If multiple statements
@@ -189,7 +190,7 @@ struct address_info
/* The loop containing STMT (cached for convenience). If multiple
statements share the same address, they all belong to this loop. */
- struct loop *loop;
+ class loop *loop;
/* A decomposition of the calculation into a sum of terms plus an
optional base. When BASE is provided, it is never an SSA name.
@@ -210,8 +211,9 @@ struct address_info_hasher : nofree_ptr_hash <address_info>
};
/* Information about the versioning we'd like to apply to a loop. */
-struct loop_info
+class loop_info
{
+public:
bool worth_versioning_p () const;
/* True if we've decided not to version this loop. The remaining
@@ -227,7 +229,7 @@ struct loop_info
/* The outermost loop that can handle all the version checks
described below. */
- struct loop *outermost;
+ class loop *outermost;
/* The first entry in the list of blocks that belong to this loop
(and not to subloops). m_next_block_in_loop provides the chain
@@ -240,7 +242,7 @@ struct loop_info
/* If versioning succeeds, this points the version of the loop that
assumes the version conditions holds. */
- struct loop *optimized_loop;
+ class loop *optimized_loop;
};
/* The main pass structure. */
@@ -283,9 +285,9 @@ private:
loop_info &m_li;
};
- loop_info &get_loop_info (struct loop *loop) { return m_loops[loop->num]; }
+ loop_info &get_loop_info (class loop *loop) { return m_loops[loop->num]; }
- unsigned int max_insns_for_loop (struct loop *);
+ unsigned int max_insns_for_loop (class loop *);
bool expensive_stmt_p (gimple *);
void version_for_unity (gimple *, tree);
@@ -296,7 +298,7 @@ private:
inner_likelihood get_inner_likelihood (tree, unsigned HOST_WIDE_INT);
void dump_inner_likelihood (address_info &, address_term_info &);
void analyze_stride (address_info &, address_term_info &,
- tree, struct loop *);
+ tree, class loop *);
bool find_per_loop_multiplication (address_info &, address_term_info &);
bool analyze_term_using_scevs (address_info &, address_term_info &);
void analyze_arbitrary_term (address_info &, address_term_info &);
@@ -307,15 +309,15 @@ private:
bool analyze_block (basic_block);
bool analyze_blocks ();
- void prune_loop_conditions (struct loop *, vr_values *);
+ void prune_loop_conditions (class loop *, vr_values *);
bool prune_conditions ();
- void merge_loop_info (struct loop *, struct loop *);
- void add_loop_to_queue (struct loop *);
- bool decide_whether_loop_is_versionable (struct loop *);
+ void merge_loop_info (class loop *, class loop *);
+ void add_loop_to_queue (class loop *);
+ bool decide_whether_loop_is_versionable (class loop *);
bool make_versioning_decisions ();
- bool version_loop (struct loop *);
+ bool version_loop (class loop *);
void implement_versioning_decisions ();
/* The function we're optimizing. */
@@ -346,7 +348,7 @@ private:
auto_vec<basic_block> m_next_block_in_loop;
/* The list of loops that we've decided to version. */
- auto_vec<struct loop *> m_loops_to_version;
+ auto_vec<class loop *> m_loops_to_version;
/* A table of addresses in the current loop, keyed off their values
but not their offsets. */
@@ -600,7 +602,7 @@ loop_versioning::~loop_versioning ()
interchange or outer-loop vectorization). */
unsigned int
-loop_versioning::max_insns_for_loop (struct loop *loop)
+loop_versioning::max_insns_for_loop (class loop *loop)
{
return (loop->inner
? PARAM_VALUE (PARAM_LOOP_VERSIONING_MAX_OUTER_INSNS)
@@ -631,7 +633,7 @@ loop_versioning::expensive_stmt_p (gimple *stmt)
void
loop_versioning::version_for_unity (gimple *stmt, tree name)
{
- struct loop *loop = loop_containing_stmt (stmt);
+ class loop *loop = loop_containing_stmt (stmt);
loop_info &li = get_loop_info (loop);
if (bitmap_set_bit (&li.unity_names, SSA_NAME_VERSION (name)))
@@ -639,7 +641,7 @@ loop_versioning::version_for_unity (gimple *stmt, tree name)
/* This is the first time we've wanted to version LOOP for NAME.
Keep track of the outermost loop that can handle all versioning
checks in LI. */
- struct loop *outermost
+ class loop *outermost
= outermost_invariant_loop_for_expr (loop, name);
if (loop_depth (li.outermost) < loop_depth (outermost))
li.outermost = outermost;
@@ -832,7 +834,7 @@ loop_versioning::dump_inner_likelihood (address_info &address,
void
loop_versioning::analyze_stride (address_info &address,
address_term_info &term,
- tree stride, struct loop *op_loop)
+ tree stride, class loop *op_loop)
{
term.stride = stride;
@@ -893,7 +895,7 @@ loop_versioning::find_per_loop_multiplication (address_info &address,
if (!mult || gimple_assign_rhs_code (mult) != MULT_EXPR)
return false;
- struct loop *mult_loop = loop_containing_stmt (mult);
+ class loop *mult_loop = loop_containing_stmt (mult);
if (!loop_outer (mult_loop))
return false;
@@ -935,7 +937,7 @@ loop_versioning::analyze_term_using_scevs (address_info &address,
if (!setter)
return false;
- struct loop *wrt_loop = loop_containing_stmt (setter);
+ class loop *wrt_loop = loop_containing_stmt (setter);
if (!loop_outer (wrt_loop))
return false;
@@ -1197,7 +1199,7 @@ loop_versioning::record_address_fragment (gimple *stmt,
/* Quick exit if no part of the address is calculated in STMT's loop,
since such addresses have no versioning opportunities. */
- struct loop *loop = loop_containing_stmt (stmt);
+ class loop *loop = loop_containing_stmt (stmt);
if (expr_invariant_in_loop_p (loop, expr))
return;
@@ -1373,7 +1375,7 @@ loop_versioning::analyze_expr (gimple *stmt, tree expr)
bool
loop_versioning::analyze_block (basic_block bb)
{
- struct loop *loop = bb->loop_father;
+ class loop *loop = bb->loop_father;
loop_info &li = get_loop_info (loop);
for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
gsi_next (&gsi))
@@ -1422,7 +1424,7 @@ loop_versioning::analyze_blocks ()
versioning at that level could be useful in some cases. */
get_loop_info (get_loop (m_fn, 0)).rejected_p = true;
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
{
loop_info &linfo = get_loop_info (loop);
@@ -1433,7 +1435,7 @@ loop_versioning::analyze_blocks ()
/* See whether an inner loop prevents versioning of this loop. */
if (!linfo.rejected_p)
- for (struct loop *inner = loop->inner; inner; inner = inner->next)
+ for (class loop *inner = loop->inner; inner; inner = inner->next)
if (get_loop_info (inner).rejected_p)
{
linfo.rejected_p = true;
@@ -1477,7 +1479,7 @@ loop_versioning::analyze_blocks ()
LOOP. */
void
-loop_versioning::prune_loop_conditions (struct loop *loop, vr_values *vrs)
+loop_versioning::prune_loop_conditions (class loop *loop, vr_values *vrs)
{
loop_info &li = get_loop_info (loop);
@@ -1523,7 +1525,7 @@ loop_versioning::prune_conditions ()
OUTER. */
void
-loop_versioning::merge_loop_info (struct loop *outer, struct loop *inner)
+loop_versioning::merge_loop_info (class loop *outer, class loop *inner)
{
loop_info &inner_li = get_loop_info (inner);
loop_info &outer_li = get_loop_info (outer);
@@ -1547,7 +1549,7 @@ loop_versioning::merge_loop_info (struct loop *outer, struct loop *inner)
/* Add LOOP to the queue of loops to version. */
void
-loop_versioning::add_loop_to_queue (struct loop *loop)
+loop_versioning::add_loop_to_queue (class loop *loop)
{
loop_info &li = get_loop_info (loop);
@@ -1569,7 +1571,7 @@ loop_versioning::add_loop_to_queue (struct loop *loop)
We have already made this decision for all inner loops of LOOP. */
bool
-loop_versioning::decide_whether_loop_is_versionable (struct loop *loop)
+loop_versioning::decide_whether_loop_is_versionable (class loop *loop)
{
loop_info &li = get_loop_info (loop);
@@ -1577,7 +1579,7 @@ loop_versioning::decide_whether_loop_is_versionable (struct loop *loop)
return false;
/* Examine the decisions made for inner loops. */
- for (struct loop *inner = loop->inner; inner; inner = inner->next)
+ for (class loop *inner = loop->inner; inner; inner = inner->next)
{
loop_info &inner_li = get_loop_info (inner);
if (inner_li.rejected_p)
@@ -1629,7 +1631,7 @@ loop_versioning::decide_whether_loop_is_versionable (struct loop *loop)
}
/* Hoist all version checks from subloops to this loop. */
- for (struct loop *subloop = loop->inner; subloop; subloop = subloop->next)
+ for (class loop *subloop = loop->inner; subloop; subloop = subloop->next)
merge_loop_info (loop, subloop);
return true;
@@ -1644,7 +1646,7 @@ loop_versioning::make_versioning_decisions ()
AUTO_DUMP_SCOPE ("make_versioning_decisions",
dump_user_location_t::from_function_decl (m_fn->decl));
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
{
loop_info &linfo = get_loop_info (loop);
@@ -1661,7 +1663,7 @@ loop_versioning::make_versioning_decisions ()
/* We can't version this loop, so individually version any
subloops that would benefit and haven't been versioned yet. */
linfo.rejected_p = true;
- for (struct loop *subloop = loop->inner; subloop;
+ for (class loop *subloop = loop->inner; subloop;
subloop = subloop->next)
if (get_loop_info (subloop).worth_versioning_p ())
add_loop_to_queue (subloop);
@@ -1675,7 +1677,7 @@ loop_versioning::make_versioning_decisions ()
cached in the associated loop_info. Return true on success. */
bool
-loop_versioning::version_loop (struct loop *loop)
+loop_versioning::version_loop (class loop *loop)
{
loop_info &li = get_loop_info (loop);
@@ -1737,7 +1739,7 @@ loop_versioning::implement_versioning_decisions ()
user-facing at this point. */
bool any_succeeded_p = false;
- struct loop *loop;
+ class loop *loop;
unsigned int i;
FOR_EACH_VEC_ELT (m_loops_to_version, i, loop)
if (version_loop (loop))
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index df9f0c5..5327816 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -57,6 +57,16 @@ static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
code_helper, tree, tree, tree, tree, tree);
static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
code_helper, tree, tree, tree, tree, tree, tree);
+static bool gimple_resimplify1 (gimple_seq *, gimple_match_op *,
+ tree (*)(tree));
+static bool gimple_resimplify2 (gimple_seq *, gimple_match_op *,
+ tree (*)(tree));
+static bool gimple_resimplify3 (gimple_seq *, gimple_match_op *,
+ tree (*)(tree));
+static bool gimple_resimplify4 (gimple_seq *, gimple_match_op *,
+ tree (*)(tree));
+static bool gimple_resimplify5 (gimple_seq *, gimple_match_op *,
+ tree (*)(tree));
const unsigned int gimple_match_op::MAX_NUM_OPS;
@@ -173,7 +183,7 @@ maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
RES_OP with a simplified and/or canonicalized result and
returns whether any change was made. */
-bool
+static bool
gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
tree (*valueize)(tree))
{
@@ -233,7 +243,7 @@ gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
RES_OP with a simplified and/or canonicalized result and
returns whether any change was made. */
-bool
+static bool
gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
tree (*valueize)(tree))
{
@@ -305,7 +315,7 @@ gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
RES_OP with a simplified and/or canonicalized result and
returns whether any change was made. */
-bool
+static bool
gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
tree (*valueize)(tree))
{
@@ -376,7 +386,7 @@ gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
RES_OP with a simplified and/or canonicalized result and
returns whether any change was made. */
-bool
+static bool
gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
tree (*valueize)(tree))
{
@@ -417,7 +427,7 @@ gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
RES_OP with a simplified and/or canonicalized result and
returns whether any change was made. */
-bool
+static bool
gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
tree (*valueize)(tree))
{
@@ -439,6 +449,30 @@ gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
return false;
}
+/* Match and simplify the toplevel valueized operation THIS.
+ Replaces THIS with a simplified and/or canonicalized result and
+ returns whether any change was made. */
+
+bool
+gimple_match_op::resimplify (gimple_seq *seq, tree (*valueize)(tree))
+{
+ switch (num_ops)
+ {
+ case 1:
+ return gimple_resimplify1 (seq, this, valueize);
+ case 2:
+ return gimple_resimplify2 (seq, this, valueize);
+ case 3:
+ return gimple_resimplify3 (seq, this, valueize);
+ case 4:
+ return gimple_resimplify4 (seq, this, valueize);
+ case 5:
+ return gimple_resimplify5 (seq, this, valueize);
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* If in GIMPLE the operation described by RES_OP should be single-rhs,
build a GENERIC tree for that expression and update RES_OP accordingly. */
diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h
index 22fa86c..ea0f66f 100644
--- a/gcc/gimple-match.h
+++ b/gcc/gimple-match.h
@@ -43,8 +43,9 @@ private:
/* Represents the condition under which an operation should happen,
and the value to use otherwise. The condition applies elementwise
(as for VEC_COND_EXPR) if the values are vectors. */
-struct gimple_match_cond
+class gimple_match_cond
{
+public:
enum uncond { UNCOND };
/* Build an unconditional op. */
@@ -79,8 +80,9 @@ gimple_match_cond::any_else () const
/* Represents an operation to be simplified, or the result of the
simplification. */
-struct gimple_match_op
+class gimple_match_op
{
+public:
gimple_match_op ();
gimple_match_op (const gimple_match_cond &, code_helper, tree, unsigned int);
gimple_match_op (const gimple_match_cond &,
@@ -105,6 +107,8 @@ struct gimple_match_op
tree op_or_null (unsigned int) const;
+ bool resimplify (gimple_seq *, tree (*)(tree));
+
/* The maximum value of NUM_OPS. */
static const unsigned int MAX_NUM_OPS = 5;
@@ -331,11 +335,6 @@ extern tree (*mprts_hook) (gimple_match_op *);
bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
tree (*)(tree), tree (*)(tree));
-bool gimple_resimplify1 (gimple_seq *, gimple_match_op *, tree (*)(tree));
-bool gimple_resimplify2 (gimple_seq *, gimple_match_op *, tree (*)(tree));
-bool gimple_resimplify3 (gimple_seq *, gimple_match_op *, tree (*)(tree));
-bool gimple_resimplify4 (gimple_seq *, gimple_match_op *, tree (*)(tree));
-bool gimple_resimplify5 (gimple_seq *, gimple_match_op *, tree (*)(tree));
tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
tree res = NULL_TREE);
void maybe_build_generic_op (gimple_match_op *);
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 45e7260..ce339ee 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1232,6 +1232,8 @@ dump_gimple_try (pretty_printer *buffer, gtry *gs, int spc,
newline_and_indent (buffer, spc + 2);
pp_right_brace (buffer);
+ gimple_seq seq = gimple_try_cleanup (gs);
+
if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
{
newline_and_indent (buffer, spc);
@@ -1245,12 +1247,28 @@ dump_gimple_try (pretty_printer *buffer, gtry *gs, int spc,
pp_string (buffer, "finally");
newline_and_indent (buffer, spc + 2);
pp_left_brace (buffer);
+
+ if (seq && is_a <geh_else *> (gimple_seq_first_stmt (seq))
+ && gimple_seq_nondebug_singleton_p (seq))
+ {
+ geh_else *stmt = as_a <geh_else *> (gimple_seq_first_stmt (seq));
+ seq = gimple_eh_else_n_body (stmt);
+ pp_newline (buffer);
+ dump_gimple_seq (buffer, seq, spc + 4, flags);
+ newline_and_indent (buffer, spc + 2);
+ pp_right_brace (buffer);
+ seq = gimple_eh_else_e_body (stmt);
+ newline_and_indent (buffer, spc);
+ pp_string (buffer, "else");
+ newline_and_indent (buffer, spc + 2);
+ pp_left_brace (buffer);
+ }
}
else
pp_string (buffer, " <UNKNOWN GIMPLE_TRY> {");
pp_newline (buffer);
- dump_gimple_seq (buffer, gimple_try_cleanup (gs), spc + 4, flags);
+ dump_gimple_seq (buffer, seq, spc + 4, flags);
newline_and_indent (buffer, spc + 2);
pp_right_brace (buffer);
}
diff --git a/gcc/gimple-ssa-backprop.c b/gcc/gimple-ssa-backprop.c
index 30fb7cb..0aeac4e 100644
--- a/gcc/gimple-ssa-backprop.c
+++ b/gcc/gimple-ssa-backprop.c
@@ -107,8 +107,9 @@ along with GCC; see the file COPYING3. If not see
namespace {
/* Information about a group of uses of an SSA name. */
-struct usage_info
+class usage_info
{
+public:
usage_info () : flag_word (0) {}
usage_info &operator &= (const usage_info &);
usage_info operator & (const usage_info &) const;
diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index 4c68af8..46f5a01 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -262,7 +262,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
use PHI arg ranges which may be still UNDEFINED but have
to use VARYING for them. But we can still resort to
SCEV for loop header PHIs. */
- struct loop *l;
+ class loop *l;
if (scev_initialized_p ()
&& interesting
&& (l = loop_containing_stmt (phi))
diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
index 33fe352..72e6c77 100644
--- a/gcc/gimple-ssa-isolate-paths.c
+++ b/gcc/gimple-ssa-isolate-paths.c
@@ -128,9 +128,9 @@ insert_trap (gimple_stmt_iterator *si_p, tree op)
DUPLICATE is a pre-existing duplicate, use it as BB' if it exists.
- Return BB'. */
+ Return BB' (which may be equal to DUPLICATE). */
-basic_block
+ATTRIBUTE_RETURNS_NONNULL basic_block
isolate_path (basic_block bb, basic_block duplicate,
edge e, gimple *stmt, tree op, bool ret_zero)
{
@@ -341,6 +341,322 @@ stmt_uses_0_or_null_in_undefined_way (gimple *stmt)
return false;
}
+/* Describes the property of a return statement that may return
+ the address of one or more local variables. The type must
+ be safely assignable and copyable so that it can be stored in
+ a hash_map. */
+class args_loc_t
+{
+ public:
+
+ args_loc_t (): nargs (), locvec (), ptr (&ptr)
+ {
+ locvec.create (4);
+ }
+
+ args_loc_t (const args_loc_t &rhs)
+ : nargs (rhs.nargs), locvec (rhs.locvec.copy ()), ptr (&ptr) { }
+
+ args_loc_t& operator= (const args_loc_t &rhs)
+ {
+ nargs = rhs.nargs;
+ locvec.release ();
+ locvec = rhs.locvec.copy ();
+ return *this;
+ }
+
+ ~args_loc_t ()
+ {
+ locvec.release ();
+ gcc_assert (ptr == &ptr);
+ }
+
+ /* For a PHI in a return statement its number of arguments. When greater
+ than LOCVEC.LENGTH () implies that an address of one of the locals in
+ LOCVEC may but need not be returned by the statement. Otherwise,
+ unless both are zero, it implies it definitely is returned. */
+ unsigned nargs;
+ /* The locations of local variables/alloca calls returned by the return
+ statement. Avoid using auto_vec here since it's not safe to copy due
+ to pr90904. */
+ vec <location_t> locvec;
+ void *ptr;
+};
+
+/* A mapping from a return statement to the locations of local variables
+ whose addresses it may return. */
+typedef hash_map <gimple *, args_loc_t> locmap_t;
+
+/* Given the LOCMAP mapping, issue diagnostics about returning addresses
+ of local variables. When MAYBE is set, all diagnostics will be of
+ the "may return" kind. Otherwise each will be determined based on
+ the equality of the corresponding NARGS and LOCVEC.LENGTH () values. */
+
+static void
+diag_returned_locals (bool maybe, const locmap_t &locmap)
+{
+ for (locmap_t::iterator it = locmap.begin (); it != locmap.end (); ++it)
+ {
+ gimple *stmt = (*it).first;
+ const args_loc_t &argsloc = (*it).second;
+ location_t stmtloc = gimple_location (stmt);
+
+ auto_diagnostic_group d;
+ unsigned nargs = argsloc.locvec.length ();
+ if (warning_at (stmtloc, OPT_Wreturn_local_addr,
+ (maybe || argsloc.nargs > nargs
+ ? G_("function may return address of local variable")
+ : G_("function returns address of local variable"))))
+ {
+ for (unsigned i = 0; i != nargs; ++i)
+ inform (argsloc.locvec[i], "declared here");
+ }
+ }
+}
+
+/* Return true if EXPR is an expression of pointer type that refers
+ to the address of one or more variables with automatic storage
+ duration. If so, add an entry to *PLOCMAP and insert into
+ PLOCMAP->LOCVEC the locations of the corresponding local variables
+ whose address is returned by the RETURN_STMT (which may be set to
+ (gimple*)-1 as a placeholder for such a statement). VISITED is
+ a bitmap of PHI nodes already visited by recursive calls. When
+ null, PHI expressions are not considered. */
+
+static bool
+is_addr_local (gimple *return_stmt, tree exp, locmap_t *plocmap,
+ hash_set<gphi *> *visited)
+{
+ if (TREE_CODE (exp) == ADDR_EXPR)
+ {
+ tree baseaddr = get_base_address (TREE_OPERAND (exp, 0));
+ if (TREE_CODE (baseaddr) == MEM_REF)
+ return is_addr_local (return_stmt, TREE_OPERAND (baseaddr, 0),
+ plocmap, visited);
+
+ if ((!VAR_P (baseaddr)
+ || is_global_var (baseaddr))
+ && TREE_CODE (baseaddr) != PARM_DECL)
+ return false;
+
+ args_loc_t &argsloc = plocmap->get_or_insert (return_stmt);
+ argsloc.locvec.safe_push (DECL_SOURCE_LOCATION (baseaddr));
+ return true;
+ }
+
+ if (!POINTER_TYPE_P (TREE_TYPE (exp)))
+ return false;
+
+ if (TREE_CODE (exp) == SSA_NAME)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (exp);
+ enum gimple_code code = gimple_code (def_stmt);
+
+ if (is_gimple_assign (def_stmt))
+ {
+ tree type = TREE_TYPE (gimple_assign_lhs (def_stmt));
+ if (POINTER_TYPE_P (type))
+ {
+ tree_code code = gimple_assign_rhs_code (def_stmt);
+ tree ptr1 = NULL_TREE, ptr2 = NULL_TREE;
+
+ /* Set to the number of arguments examined that should
+ be added to ARGSLOC->NARGS to identify expressions
+ only some but not all of whose operands refer to local
+ addresses. */
+ unsigned nargs = 0;
+ if (code == COND_EXPR)
+ {
+ ptr1 = gimple_assign_rhs2 (def_stmt);
+ ptr2 = gimple_assign_rhs3 (def_stmt);
+ nargs = 2;
+ }
+ else if (code == MAX_EXPR || code == MIN_EXPR)
+ {
+ ptr1 = gimple_assign_rhs1 (def_stmt);
+ ptr2 = gimple_assign_rhs2 (def_stmt);
+ nargs = 2;
+ }
+ else if (code == ADDR_EXPR
+ || code == NOP_EXPR
+ || code == POINTER_PLUS_EXPR)
+ /* Leave NARGS at zero and let the recursive call set it. */
+ ptr1 = gimple_assign_rhs1 (def_stmt);
+
+ /* Avoid short-circuiting the logical OR result in case
+ both operands refer to local variables, in which case
+ both should be considered and identified in the warning. */
+ bool res1 = false, res2 = false;
+ if (ptr1)
+ res1 = is_addr_local (return_stmt, ptr1, plocmap, visited);
+ if (ptr2)
+ res2 = is_addr_local (return_stmt, ptr2, plocmap, visited);
+
+ if (nargs)
+ if (args_loc_t *argsloc = plocmap->get (return_stmt))
+ argsloc->nargs += nargs;
+
+ return res1 || res2;
+ }
+ return false;
+ }
+
+ if (code == GIMPLE_CALL
+ && gimple_call_builtin_p (def_stmt))
+ {
+ /* Handle alloca and friends that return pointers to automatic
+ storage. */
+ tree fn = gimple_call_fndecl (def_stmt);
+ int code = DECL_FUNCTION_CODE (fn);
+ if (code == BUILT_IN_ALLOCA
+ || code == BUILT_IN_ALLOCA_WITH_ALIGN
+ || code == BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX)
+ {
+ args_loc_t &argsloc = plocmap->get_or_insert (return_stmt);
+ argsloc.locvec.safe_push (gimple_location (def_stmt));
+ return true;
+ }
+
+ if (gimple_call_num_args (def_stmt) < 1)
+ return false;
+
+ /* Recursively examine the first argument of calls to built-ins
+ that return it. */
+ switch (code)
+ {
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMCPY_CHK:
+ case BUILT_IN_MEMPCPY:
+ case BUILT_IN_MEMPCPY_CHK:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMMOVE_CHK:
+ case BUILT_IN_STPCPY:
+ case BUILT_IN_STPCPY_CHK:
+ case BUILT_IN_STPNCPY:
+ case BUILT_IN_STPNCPY_CHK:
+ case BUILT_IN_STRCAT:
+ case BUILT_IN_STRCAT_CHK:
+ case BUILT_IN_STRCHR:
+ case BUILT_IN_STRCPY:
+ case BUILT_IN_STRCPY_CHK:
+ case BUILT_IN_STRNCAT:
+ case BUILT_IN_STRNCAT_CHK:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRNCPY_CHK:
+ case BUILT_IN_STRRCHR:
+ case BUILT_IN_STRSTR:
+ return is_addr_local (return_stmt,
+ gimple_call_arg (def_stmt, 0),
+ plocmap, visited);
+ default:
+ return false;
+ }
+ }
+
+ if (code == GIMPLE_PHI && visited)
+ {
+ gphi *phi_stmt = as_a <gphi *> (def_stmt);
+ if (visited->add (phi_stmt))
+ return false;
+
+ unsigned count = 0;
+ unsigned nargs = gimple_phi_num_args (phi_stmt);
+ args_loc_t &argsloc = plocmap->get_or_insert (return_stmt);
+ /* Bump up the number of operands examined by the number of
+ operands of this PHI. */
+ argsloc.nargs += nargs;
+ for (unsigned i = 0; i < gimple_phi_num_args (phi_stmt); ++i)
+ {
+ tree arg = gimple_phi_arg_def (phi_stmt, i);
+ if (is_addr_local (return_stmt, arg, plocmap, visited))
+ ++count;
+ }
+ return count != 0;
+ }
+ }
+
+ return false;
+}
+
+/* Detect returning the address of a local variable in a PHI result LHS
+ and argument ARG and PHI edge E in basic block BB. Add an entry for
+ each use to LOCMAP, setting its NARGS member to the NARGS argument
+ (the number of PHI operands) plus the number of arguments in binary
+ expressions refereced by ARG. Call isolate_path for each returned
+ address and set *ISOLATED to true if called.
+ Return either DUPLICATE or the most recent result of isolate_path. */
+
+static basic_block
+handle_return_addr_local_phi_arg (basic_block bb, basic_block duplicate,
+ tree lhs, tree arg, edge e, locmap_t &locmap,
+ unsigned nargs, bool *isolated)
+{
+ /* Use (gimple*)-1 as a temporary placeholder and replace it with
+ the return statement below once it is known. Using a null doesn't
+ work because it's used by the hash_map to mean "no-entry." Pass
+ null instead of a visited_phis bitmap to avoid descending into
+ PHIs since they are being processed by the caller. Those that
+ remain will be checked again later. */
+ if (!is_addr_local ((gimple*)-1, arg, &locmap, NULL))
+ {
+ /* Remove the placeholder regardless of success or failure. */
+ locmap.remove ((gimple*)-1);
+ return duplicate;
+ }
+
+ const args_loc_t* const placeargsloc = locmap.get ((gimple*)-1);
+ const unsigned nlocs = placeargsloc->locvec.length ();
+ gcc_assert (nlocs);
+
+ /* Add to the number of PHI arguments determined by the caller
+ the number of operands of the expressions referenced by ARG.
+ This lets the caller determine whether it's dealing with
+ a "may return" or "definitely returns." */
+ nargs += placeargsloc->nargs;
+
+ /* Set to true if any expressions referenced by ARG involve
+ multiple addresses only some of which are those of locals. */
+ bool maybe = placeargsloc->nargs > placeargsloc->locvec.length ();
+
+ gimple *use_stmt;
+ imm_use_iterator iter;
+
+ /* Look for uses of the PHI result LHS in return statements. */
+ FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
+ {
+ greturn *return_stmt = dyn_cast <greturn *> (use_stmt);
+ if (!return_stmt)
+ continue;
+
+ if (gimple_return_retval (return_stmt) != lhs)
+ continue;
+
+ /* Add an entry for the return statement and the locations
+ oof the PHI arguments obtained above to the map. */
+ args_loc_t &argsloc = locmap.get_or_insert (use_stmt);
+ argsloc.nargs = nargs;
+ unsigned nelts = argsloc.locvec.length () + nlocs;
+ argsloc.locvec.reserve (nelts);
+ argsloc.locvec.splice (placeargsloc->locvec);
+
+ if (!maybe
+ && (flag_isolate_erroneous_paths_dereference
+ || flag_isolate_erroneous_paths_attribute)
+ && gimple_bb (use_stmt) == bb)
+ {
+ duplicate = isolate_path (bb, duplicate, e,
+ use_stmt, lhs, true);
+
+ /* Let caller know the path has been isolated. */
+ *isolated = true;
+ }
+ }
+
+ locmap.remove ((gimple*)-1);
+
+ return duplicate;
+}
+
/* Look for PHI nodes which feed statements in the same block where
the value of the PHI node implies the statement is erroneous.
@@ -352,6 +668,8 @@ stmt_uses_0_or_null_in_undefined_way (gimple *stmt)
static void
find_implicit_erroneous_behavior (void)
{
+ locmap_t locmap;
+
basic_block bb;
FOR_EACH_BB_FN (bb, cfun)
@@ -388,70 +706,46 @@ find_implicit_erroneous_behavior (void)
gphi *phi = si.phi ();
tree lhs = gimple_phi_result (phi);
+ /* Initial number of PHI arguments. The result may change
+ from one iteration of the loop below to the next in
+ response to changes to the CFG but only the initial
+ value is stored below for use by diagnostics. */
+ unsigned nargs = gimple_phi_num_args (phi);
+
/* PHI produces a pointer result. See if any of the PHI's
arguments are NULL.
When we remove an edge, we want to reprocess the current
- index, hence the ugly way we update I for each iteration. */
+ index since the argument at that index will have been
+ removed, hence the ugly way we update I for each iteration. */
basic_block duplicate = NULL;
for (unsigned i = 0, next_i = 0;
- i < gimple_phi_num_args (phi);
- i = next_i)
+ i < gimple_phi_num_args (phi); i = next_i)
{
- tree op = gimple_phi_arg_def (phi, i);
+ tree arg = gimple_phi_arg_def (phi, i);
edge e = gimple_phi_arg_edge (phi, i);
- imm_use_iterator iter;
- gimple *use_stmt;
+ /* Advance the argument index unless a path involving
+ the current argument has been isolated. */
next_i = i + 1;
-
- if (TREE_CODE (op) == ADDR_EXPR)
+ bool isolated = false;
+ duplicate = handle_return_addr_local_phi_arg (bb, duplicate, lhs,
+ arg, e, locmap,
+ nargs, &isolated);
+ if (isolated)
{
- tree valbase = get_base_address (TREE_OPERAND (op, 0));
- if ((VAR_P (valbase) && !is_global_var (valbase))
- || TREE_CODE (valbase) == PARM_DECL)
- {
- FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
- {
- greturn *return_stmt
- = dyn_cast <greturn *> (use_stmt);
- if (!return_stmt)
- continue;
-
- if (gimple_return_retval (return_stmt) != lhs)
- continue;
-
- {
- auto_diagnostic_group d;
- if (warning_at (gimple_location (use_stmt),
- OPT_Wreturn_local_addr,
- "function may return address "
- "of local variable"))
- inform (DECL_SOURCE_LOCATION(valbase),
- "declared here");
- }
-
- if ((flag_isolate_erroneous_paths_dereference
- || flag_isolate_erroneous_paths_attribute)
- && gimple_bb (use_stmt) == bb)
- {
- duplicate = isolate_path (bb, duplicate, e,
- use_stmt, lhs, true);
-
- /* When we remove an incoming edge, we need to
- reprocess the Ith element. */
- next_i = i;
- cfg_altered = true;
- }
- }
- }
+ cfg_altered = true;
+ next_i = i;
}
- if (!integer_zerop (op))
+ if (!integer_zerop (arg))
continue;
location_t phi_arg_loc = gimple_phi_arg_location (phi, i);
+ imm_use_iterator iter;
+ gimple *use_stmt;
+
/* We've got a NULL PHI argument. Now see if the
PHI's result is dereferenced within BB. */
FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
@@ -480,6 +774,57 @@ find_implicit_erroneous_behavior (void)
}
}
}
+
+ diag_returned_locals (false, locmap);
+}
+
+/* Detect and diagnose returning the address of a local variable
+ in RETURN_STMT in basic block BB. This only becomes undefined
+ behavior if the result is used, so we do not insert a trap and
+ only return NULL instead. */
+
+static void
+warn_return_addr_local (basic_block bb, greturn *return_stmt)
+{
+ tree val = gimple_return_retval (return_stmt);
+ if (!val)
+ return;
+
+ locmap_t locmap;
+ hash_set<gphi *> visited_phis;
+ if (!is_addr_local (return_stmt, val, &locmap, &visited_phis))
+ return;
+
+ /* We only need it for this particular case. */
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+
+ const args_loc_t *argsloc = locmap.get (return_stmt);
+ gcc_assert (argsloc);
+
+ bool maybe = argsloc->nargs > argsloc->locvec.length ();
+ if (!maybe)
+ maybe = !dominated_by_p (CDI_POST_DOMINATORS,
+ single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)), bb);
+
+ diag_returned_locals (maybe, locmap);
+
+ /* Bail if the statement isn't certain to return the address
+ of a local (e.g., if it involves a conditional expression
+ that wasn't trasnformed into a PHI or if it involves
+ a MAX_EXPR or MIN_EXPR only one of whose operands is a local
+ (even though such an expression isn't valid in C or has
+ defined semantics in C++). */
+ if (maybe)
+ return;
+
+ /* Do not modify code if the user only asked for warnings. */
+ if (flag_isolate_erroneous_paths_dereference
+ || flag_isolate_erroneous_paths_attribute)
+ {
+ tree zero = build_zero_cst (TREE_TYPE (val));
+ gimple_return_set_retval (return_stmt, zero);
+ update_stmt (return_stmt);
+ }
}
/* Look for statements which exhibit erroneous behavior. For example
@@ -525,49 +870,10 @@ find_explicit_erroneous_behavior (void)
break;
}
- /* Detect returning the address of a local variable. This only
- becomes undefined behavior if the result is used, so we do not
- insert a trap and only return NULL instead. */
+ /* Look for a return statement that returns the address
+ of a local variable or the result of alloca. */
if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
- {
- tree val = gimple_return_retval (return_stmt);
- if (val && TREE_CODE (val) == ADDR_EXPR)
- {
- tree valbase = get_base_address (TREE_OPERAND (val, 0));
- if ((VAR_P (valbase) && !is_global_var (valbase))
- || TREE_CODE (valbase) == PARM_DECL)
- {
- /* We only need it for this particular case. */
- calculate_dominance_info (CDI_POST_DOMINATORS);
- const char* msg;
- bool always_executed = dominated_by_p
- (CDI_POST_DOMINATORS,
- single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)), bb);
- if (always_executed)
- msg = N_("function returns address of local variable");
- else
- msg = N_("function may return address of "
- "local variable");
- {
- auto_diagnostic_group d;
- if (warning_at (gimple_location (stmt),
- OPT_Wreturn_local_addr, msg))
- inform (DECL_SOURCE_LOCATION(valbase),
- "declared here");
- }
-
- /* Do not modify code if the user only asked for
- warnings. */
- if (flag_isolate_erroneous_paths_dereference
- || flag_isolate_erroneous_paths_attribute)
- {
- tree zero = build_zero_cst (TREE_TYPE (val));
- gimple_return_set_retval (return_stmt, zero);
- update_stmt (stmt);
- }
- }
- }
- }
+ warn_return_addr_local (bb, return_stmt);
}
}
}
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index a0934bc..6ba3d86 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -520,8 +520,9 @@ enum format_lengths
/* Description of the result of conversion either of a single directive
or the whole format string. */
-struct fmtresult
+class fmtresult
{
+public:
/* Construct a FMTRESULT object with all counters initialized
to MIN. KNOWNRANGE is set when MIN is valid. */
fmtresult (unsigned HOST_WIDE_INT min = HOST_WIDE_INT_MAX)
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index 5a93830..0bf64b3 100644
--- a/gcc/gimple-ssa-store-merging.c
+++ b/gcc/gimple-ssa-store-merging.c
@@ -1324,8 +1324,9 @@ namespace {
and the other fields also reflect the memory load, or an SSA name, then
VAL represents the SSA name and all the other fields are zero, */
-struct store_operand_info
+class store_operand_info
{
+public:
tree val;
tree base_addr;
poly_uint64 bitsize;
@@ -1347,8 +1348,9 @@ store_operand_info::store_operand_info ()
to memory. These are created in the first phase and coalesced into
merged_store_group objects in the second phase. */
-struct store_immediate_info
+class store_immediate_info
{
+public:
unsigned HOST_WIDE_INT bitsize;
unsigned HOST_WIDE_INT bitpos;
unsigned HOST_WIDE_INT bitregion_start;
@@ -1413,8 +1415,9 @@ store_immediate_info::store_immediate_info (unsigned HOST_WIDE_INT bs,
These are produced by the second phase (coalescing) and consumed in the
third phase that outputs the widened stores. */
-struct merged_store_group
+class merged_store_group
{
+public:
unsigned HOST_WIDE_INT start;
unsigned HOST_WIDE_INT width;
unsigned HOST_WIDE_INT bitregion_start;
@@ -2083,8 +2086,9 @@ merged_store_group::apply_stores ()
/* Structure describing the store chain. */
-struct imm_store_chain_info
+class imm_store_chain_info
{
+public:
/* Doubly-linked list that imposes an order on chain processing.
PNXP (prev's next pointer) points to the head of a list, or to
the next field in the previous chain in the list.
@@ -2155,7 +2159,7 @@ public:
virtual unsigned int execute (function *);
private:
- hash_map<tree_operand_hash, struct imm_store_chain_info *> m_stores;
+ hash_map<tree_operand_hash, class imm_store_chain_info *> m_stores;
/* Form a doubly-linked stack of the elements of m_stores, so that
we can iterate over them in a predictable way. Using this order
@@ -3064,8 +3068,9 @@ get_location_for_stmts (vec<gimple *> &stmts)
/* Used to decribe a store resulting from splitting a wide store in smaller
regularly-sized stores in split_group. */
-struct split_store
+class split_store
{
+public:
unsigned HOST_WIDE_INT bytepos;
unsigned HOST_WIDE_INT size;
unsigned HOST_WIDE_INT align;
@@ -3092,7 +3097,7 @@ split_store::split_store (unsigned HOST_WIDE_INT bp,
if there is exactly one original store in the range. */
static store_immediate_info *
-find_constituent_stores (struct merged_store_group *group,
+find_constituent_stores (class merged_store_group *group,
vec<store_immediate_info *> *stores,
unsigned int *first,
unsigned HOST_WIDE_INT bitpos,
@@ -3235,7 +3240,7 @@ count_multiple_uses (store_immediate_info *info)
static unsigned int
split_group (merged_store_group *group, bool allow_unaligned_store,
bool allow_unaligned_load, bool bzero_first,
- vec<struct split_store *> *split_stores,
+ vec<split_store *> *split_stores,
unsigned *total_orig,
unsigned *total_new)
{
@@ -3272,7 +3277,7 @@ split_group (merged_store_group *group, bool allow_unaligned_store,
if (align_bitpos)
align = least_bit_hwi (align_bitpos);
bytepos = group->start / BITS_PER_UNIT;
- struct split_store *store
+ split_store *store
= new split_store (bytepos, group->width, align);
unsigned int first = 0;
find_constituent_stores (group, &store->orig_stores,
@@ -3330,7 +3335,7 @@ split_group (merged_store_group *group, bool allow_unaligned_store,
ret = 1;
if (split_stores)
{
- struct split_store *store
+ split_store *store
= new split_store (bytepos, group->stores[0]->bitsize, align_base);
store->orig_stores.safe_push (group->stores[0]);
store->orig = true;
@@ -3457,7 +3462,7 @@ split_group (merged_store_group *group, bool allow_unaligned_store,
if (split_stores)
{
- struct split_store *store
+ split_store *store
= new split_store (try_pos, try_size, align);
info = find_constituent_stores (group, &store->orig_stores,
&first, try_bitpos, try_size);
@@ -3478,7 +3483,7 @@ split_group (merged_store_group *group, bool allow_unaligned_store,
if (total_orig)
{
unsigned int i;
- struct split_store *store;
+ split_store *store;
/* If we are reusing some original stores and any of the
original SSA_NAMEs had multiple uses, we need to subtract
those now before we add the new ones. */
@@ -3645,7 +3650,7 @@ imm_store_chain_info::output_merged_store (merged_store_group *group)
if (orig_num_stmts < 2)
return false;
- auto_vec<struct split_store *, 32> split_stores;
+ auto_vec<class split_store *, 32> split_stores;
bool allow_unaligned_store
= !STRICT_ALIGNMENT && PARAM_VALUE (PARAM_STORE_MERGING_ALLOW_UNALIGNED);
bool allow_unaligned_load = allow_unaligned_store;
@@ -4605,7 +4610,7 @@ pass_store_merging::process_store (gimple *stmt)
if (!ins_stmt)
memset (&n, 0, sizeof (n));
- struct imm_store_chain_info **chain_info = NULL;
+ class imm_store_chain_info **chain_info = NULL;
if (base_addr)
chain_info = m_stores.get (base_addr);
@@ -4641,7 +4646,7 @@ pass_store_merging::process_store (gimple *stmt)
/* Store aliases any existing chain? */
terminate_all_aliasing_chains (NULL, stmt);
/* Start a new chain. */
- struct imm_store_chain_info *new_chain
+ class imm_store_chain_info *new_chain
= new imm_store_chain_info (m_stores_head, base_addr);
info = new store_immediate_info (const_bitsize, const_bitpos,
const_bitregion_start,
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index bfda44a..d343da0 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -226,8 +226,9 @@ enum cand_kind
CAND_PHI
};
-struct slsr_cand_d
+class slsr_cand_d
{
+public:
/* The candidate statement S1. */
gimple *cand_stmt;
@@ -296,8 +297,8 @@ struct slsr_cand_d
tree cached_basis;
};
-typedef struct slsr_cand_d slsr_cand, *slsr_cand_t;
-typedef const struct slsr_cand_d *const_slsr_cand_t;
+typedef class slsr_cand_d slsr_cand, *slsr_cand_t;
+typedef const class slsr_cand_d *const_slsr_cand_t;
/* Pointers to candidates are chained together as part of a mapping
from base expressions to the candidates that use them. */
@@ -329,8 +330,9 @@ typedef const struct cand_chain_d *const_cand_chain_t;
of the cost of initializers. The absolute value of the increment
is stored in the incr_info. */
-struct incr_info_d
+class incr_info_d
{
+public:
/* The increment that relates a candidate to its basis. */
widest_int incr;
@@ -352,7 +354,7 @@ struct incr_info_d
basic_block init_bb;
};
-typedef struct incr_info_d incr_info, *incr_info_t;
+typedef class incr_info_d incr_info, *incr_info_t;
/* Candidates are maintained in a vector. If candidate X dominates
candidate Y, then X appears before Y in the vector; but the
@@ -805,7 +807,7 @@ slsr_process_phi (gphi *phi, bool speed)
unsigned i;
tree arg0_base = NULL_TREE, base_type;
slsr_cand_t c;
- struct loop *cand_loop = gimple_bb (phi)->loop_father;
+ class loop *cand_loop = gimple_bb (phi)->loop_father;
unsigned savings = 0;
/* A CAND_PHI requires each of its arguments to have the same
diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c
index d804146..af39ff4 100644
--- a/gcc/gimple-ssa-warn-alloca.c
+++ b/gcc/gimple-ssa-warn-alloca.c
@@ -118,7 +118,8 @@ enum alloca_type {
};
// Type of an alloca call with its corresponding limit, if applicable.
-struct alloca_type_and_limit {
+class alloca_type_and_limit {
+public:
enum alloca_type type;
// For ALLOCA_BOUND_MAYBE_LARGE and ALLOCA_BOUND_DEFINITELY_LARGE
// types, this field indicates the assumed limit if known or
@@ -184,7 +185,7 @@ adjusted_warn_limit (bool idx)
// MAX_SIZE is WARN_ALLOCA= adjusted for VLAs. It is the maximum size
// in bytes we allow for arg.
-static struct alloca_type_and_limit
+static class alloca_type_and_limit
alloca_call_type_by_arg (tree arg, tree arg_casted, edge e,
unsigned HOST_WIDE_INT max_size)
{
@@ -325,7 +326,7 @@ is_max (tree x, wide_int max)
// type to an unsigned type, set *INVALID_CASTED_TYPE to the
// problematic signed type.
-static struct alloca_type_and_limit
+static class alloca_type_and_limit
alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
{
gcc_assert (gimple_alloca_call_p (stmt));
@@ -458,7 +459,7 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
// If we couldn't find anything, try a few heuristics for things we
// can easily determine. Check these misc cases but only accept
// them if all predecessors have a known bound.
- struct alloca_type_and_limit ret = alloca_type_and_limit (ALLOCA_OK);
+ class alloca_type_and_limit ret = alloca_type_and_limit (ALLOCA_OK);
FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->preds)
{
gcc_assert (!len_casted || TYPE_UNSIGNED (TREE_TYPE (len_casted)));
@@ -535,7 +536,7 @@ pass_walloca::execute (function *fun)
continue;
tree invalid_casted_type = NULL;
- struct alloca_type_and_limit t
+ class alloca_type_and_limit t
= alloca_call_type (stmt, is_vla, &invalid_casted_type);
unsigned HOST_WIDE_INT adjusted_alloca_limit
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index 0c571ef..64175f2 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -124,8 +124,9 @@ pass_wrestrict::execute (function *fun)
/* Description of a memory reference by a built-in function. This
is similar to ao_ref but made especially suitable for -Wrestrict
and not for optimization. */
-struct builtin_memref
+class builtin_memref
{
+public:
/* The original pointer argument to the built-in function. */
tree ptr;
/* The referenced subobject or NULL if not available, and the base
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index 3142b37..72a847d 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
the file being read. IB is the input block to use for reading. */
static gphi *
-input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in,
+input_phi (class lto_input_block *ib, basic_block bb, class data_in *data_in,
struct function *fn)
{
unsigned HOST_WIDE_INT ix;
@@ -83,7 +83,7 @@ input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in,
descriptors in DATA_IN. */
static gimple *
-input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
+input_gimple_stmt (class lto_input_block *ib, class data_in *data_in,
enum LTO_tags tag)
{
gimple *stmt;
@@ -249,8 +249,8 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
FN is the function being processed. */
void
-input_bb (struct lto_input_block *ib, enum LTO_tags tag,
- struct data_in *data_in, struct function *fn,
+input_bb (class lto_input_block *ib, enum LTO_tags tag,
+ class data_in *data_in, struct function *fn,
int count_materialization_scale)
{
unsigned int index;
diff --git a/gcc/gimple-streamer.h b/gcc/gimple-streamer.h
index d0d144e..ee36192 100644
--- a/gcc/gimple-streamer.h
+++ b/gcc/gimple-streamer.h
@@ -25,7 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-streamer.h"
/* In gimple-streamer-in.c */
-void input_bb (struct lto_input_block *, enum LTO_tags, struct data_in *,
+void input_bb (class lto_input_block *, enum LTO_tags, class data_in *,
struct function *, int);
/* In gimple-streamer-out.c */
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 47070e7..442a121 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -153,24 +153,22 @@ enum gf_mask {
GF_OMP_PARALLEL_GRID_PHONY = 1 << 1,
GF_OMP_TASK_TASKLOOP = 1 << 0,
GF_OMP_TASK_TASKWAIT = 1 << 1,
- GF_OMP_FOR_KIND_MASK = (1 << 4) - 1,
+ GF_OMP_FOR_KIND_MASK = (1 << 3) - 1,
GF_OMP_FOR_KIND_FOR = 0,
GF_OMP_FOR_KIND_DISTRIBUTE = 1,
GF_OMP_FOR_KIND_TASKLOOP = 2,
GF_OMP_FOR_KIND_OACC_LOOP = 4,
- GF_OMP_FOR_KIND_GRID_LOOP = 5,
- /* Flag for SIMD variants of OMP_FOR kinds. */
- GF_OMP_FOR_SIMD = 1 << 3,
- GF_OMP_FOR_KIND_SIMD = GF_OMP_FOR_SIMD | 0,
- GF_OMP_FOR_COMBINED = 1 << 4,
- GF_OMP_FOR_COMBINED_INTO = 1 << 5,
+ GF_OMP_FOR_KIND_GRID_LOOP = 5,
+ GF_OMP_FOR_KIND_SIMD = 6,
+ GF_OMP_FOR_COMBINED = 1 << 3,
+ GF_OMP_FOR_COMBINED_INTO = 1 << 4,
/* The following flag must not be used on GF_OMP_FOR_KIND_GRID_LOOP loop
statements. */
- GF_OMP_FOR_GRID_PHONY = 1 << 6,
+ GF_OMP_FOR_GRID_PHONY = 1 << 5,
/* The following two flags should only be set on GF_OMP_FOR_KIND_GRID_LOOP
loop statements. */
- GF_OMP_FOR_GRID_INTRA_GROUP = 1 << 6,
- GF_OMP_FOR_GRID_GROUP_ITER = 1 << 7,
+ GF_OMP_FOR_GRID_INTRA_GROUP = 1 << 5,
+ GF_OMP_FOR_GRID_GROUP_ITER = 1 << 6,
GF_OMP_TARGET_KIND_MASK = (1 << 4) - 1,
GF_OMP_TARGET_KIND_REGION = 0,
GF_OMP_TARGET_KIND_DATA = 1,
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 9e5e423..723897f 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -154,6 +154,7 @@ enum omp_region_type
/* Data region with offloading. */
ORT_TARGET = 0x80,
ORT_COMBINED_TARGET = ORT_TARGET | 1,
+ ORT_IMPLICIT_TARGET = ORT_TARGET | 2,
/* OpenACC variants. */
ORT_ACC = 0x100, /* A generic OpenACC region. */
@@ -221,11 +222,14 @@ struct gimplify_omp_ctx
bool combined_loop;
bool distribute;
bool target_firstprivatize_array_bases;
+ bool add_safelen1;
+ bool order_concurrent;
int defaultmap[4];
};
static struct gimplify_ctx *gimplify_ctxp;
static struct gimplify_omp_ctx *gimplify_omp_ctxp;
+static bool in_omp_construct;
/* Forward declaration. */
static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
@@ -1331,12 +1335,17 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
|| splay_tree_lookup (ctx->variables,
(splay_tree_key) t) == NULL)
{
+ int flag = GOVD_LOCAL;
if (ctx->region_type == ORT_SIMD
&& TREE_ADDRESSABLE (t)
&& !TREE_STATIC (t))
- omp_add_variable (ctx, t, GOVD_PRIVATE | GOVD_SEEN);
- else
- omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
+ {
+ if (TREE_CODE (DECL_SIZE_UNIT (t)) != INTEGER_CST)
+ ctx->add_safelen1 = true;
+ else
+ flag = GOVD_PRIVATE;
+ }
+ omp_add_variable (ctx, t, flag | GOVD_SEEN);
}
/* Static locals inside of target construct or offloaded
routines need to be "omp declare target". */
@@ -4999,7 +5008,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
one field to assign, initialize the target from a temporary. */
if (TREE_THIS_VOLATILE (object)
&& !TREE_ADDRESSABLE (type)
- && num_nonzero_elements > 0
+ && (num_nonzero_elements > 0 || !cleared)
&& vec_safe_length (elts) > 1)
{
tree temp = create_tmp_var (TYPE_MAIN_VARIANT (type));
@@ -5526,6 +5535,7 @@ is_gimple_stmt (tree t)
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
+ case OMP_LOOP:
case OACC_LOOP:
case OMP_SCAN:
case OMP_SECTIONS:
@@ -7019,14 +7029,24 @@ omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
struct gimplify_omp_ctx *octx;
for (octx = ctx; octx; octx = octx->outer_context)
- if ((octx->region_type & ORT_TARGET) != 0)
+ if ((octx->region_type & ORT_TARGET) != 0
+ || octx->order_concurrent)
{
n = splay_tree_lookup (octx->variables, (splay_tree_key)decl);
if (n == NULL)
{
- error ("threadprivate variable %qE used in target region",
- DECL_NAME (decl));
- error_at (octx->location, "enclosing target region");
+ if (octx->order_concurrent)
+ {
+ error ("threadprivate variable %qE used in a region with"
+ " %<order(concurrent)%> clause", DECL_NAME (decl));
+ error_at (octx->location, "enclosing region");
+ }
+ else
+ {
+ error ("threadprivate variable %qE used in target region",
+ DECL_NAME (decl));
+ error_at (octx->location, "enclosing target region");
+ }
splay_tree_insert (octx->variables, (splay_tree_key)decl, 0);
}
if (decl2)
@@ -8168,7 +8188,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
break;
}
flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
- check_non_private = "lastprivate";
+ if (code != OMP_LOOP)
+ check_non_private = "lastprivate";
decl = OMP_CLAUSE_DECL (c);
if (error_operand_p (decl))
goto do_add;
@@ -9125,15 +9146,20 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
" or private in outer context", DECL_NAME (decl));
}
do_notice:
- if (((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
- || (region_type == ORT_WORKSHARE
- && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
- && OMP_CLAUSE_REDUCTION_INSCAN (c)))
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
&& outer_ctx
- && outer_ctx->region_type == ORT_COMBINED_PARALLEL
- && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
- || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
- || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE))
+ && ((region_type & ORT_TASKLOOP) == ORT_TASKLOOP
+ || (region_type == ORT_WORKSHARE
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && (OMP_CLAUSE_REDUCTION_INSCAN (c)
+ || code == OMP_LOOP)))
+ && (outer_ctx->region_type == ORT_COMBINED_PARALLEL
+ || (code == OMP_LOOP
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
+ && ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
+ == ORT_COMBINED_TEAMS))))
{
splay_tree_node on
= splay_tree_lookup (outer_ctx->variables,
@@ -9257,10 +9283,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_NOGROUP:
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
break;
+ case OMP_CLAUSE_ORDER:
+ ctx->order_concurrent = true;
+ break;
+
case OMP_CLAUSE_DEFAULTMAP:
enum gimplify_defaultmap_kind gdmkmin, gdmkmax;
switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c))
@@ -9801,6 +9832,18 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
}
}
+ if (ctx->add_safelen1)
+ {
+ /* If there are VLAs in the body of simd loop, prevent
+ vectorization. */
+ gcc_assert (ctx->region_type == ORT_SIMD);
+ c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
+ OMP_CLAUSE_SAFELEN_EXPR (c) = integer_one_node;
+ OMP_CLAUSE_CHAIN (c) = *list_p;
+ *list_p = c;
+ list_p = &OMP_CLAUSE_CHAIN (c);
+ }
+
if (ctx->region_type == ORT_WORKSHARE
&& ctx->outer_context
&& ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
@@ -10205,6 +10248,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_HINT:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_USE_DEVICE_PTR:
case OMP_CLAUSE_IS_DEVICE_PTR:
case OMP_CLAUSE_ASYNC:
@@ -10730,9 +10775,12 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
}
+ bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
+ != NULL_TREE);
if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
- TREE_CODE (for_stmt));
+ loop_p && TREE_CODE (for_stmt) != OMP_SIMD
+ ? OMP_LOOP : TREE_CODE (for_stmt));
if (TREE_CODE (for_stmt) == OMP_DISTRIBUTE)
gimplify_omp_ctxp->distribute = true;
@@ -10963,7 +11011,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
}
}
- else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
+ else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1 && !loop_p)
{
c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
@@ -11706,6 +11754,259 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
return GS_ALL_DONE;
}
+/* Helper for gimplify_omp_loop, called through walk_tree. */
+
+static tree
+replace_reduction_placeholders (tree *tp, int *walk_subtrees, void *data)
+{
+ if (DECL_P (*tp))
+ {
+ tree *d = (tree *) data;
+ if (*tp == OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[0]))
+ {
+ *tp = OMP_CLAUSE_REDUCTION_PLACEHOLDER (d[1]);
+ *walk_subtrees = 0;
+ }
+ else if (*tp == OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[0]))
+ {
+ *tp = OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (d[1]);
+ *walk_subtrees = 0;
+ }
+ }
+ return NULL_TREE;
+}
+
+/* Gimplify the gross structure of an OMP_LOOP statement. */
+
+static enum gimplify_status
+gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
+{
+ tree for_stmt = *expr_p;
+ tree clauses = OMP_FOR_CLAUSES (for_stmt);
+ struct gimplify_omp_ctx *octx = gimplify_omp_ctxp;
+ enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
+ int i;
+
+ /* If order is not present, the behavior is as if order(concurrent)
+ appeared. */
+ tree order = omp_find_clause (clauses, OMP_CLAUSE_ORDER);
+ if (order == NULL_TREE)
+ {
+ order = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_ORDER);
+ OMP_CLAUSE_CHAIN (order) = clauses;
+ OMP_FOR_CLAUSES (for_stmt) = clauses = order;
+ }
+
+ tree bind = omp_find_clause (clauses, OMP_CLAUSE_BIND);
+ if (bind == NULL_TREE)
+ {
+ if (!flag_openmp) /* flag_openmp_simd */
+ ;
+ else if (octx && (octx->region_type & ORT_TEAMS) != 0)
+ kind = OMP_CLAUSE_BIND_TEAMS;
+ else if (octx && (octx->region_type & ORT_PARALLEL) != 0)
+ kind = OMP_CLAUSE_BIND_PARALLEL;
+ else
+ {
+ for (; octx; octx = octx->outer_context)
+ {
+ if ((octx->region_type & ORT_ACC) != 0
+ || octx->region_type == ORT_NONE
+ || octx->region_type == ORT_IMPLICIT_TARGET)
+ continue;
+ break;
+ }
+ if (octx == NULL && !in_omp_construct)
+ error_at (EXPR_LOCATION (for_stmt),
+ "%<bind%> clause not specified on a %<loop%> "
+ "construct not nested inside another OpenMP construct");
+ }
+ bind = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_BIND);
+ OMP_CLAUSE_CHAIN (bind) = clauses;
+ OMP_CLAUSE_BIND_KIND (bind) = kind;
+ OMP_FOR_CLAUSES (for_stmt) = bind;
+ }
+ else
+ switch (OMP_CLAUSE_BIND_KIND (bind))
+ {
+ case OMP_CLAUSE_BIND_THREAD:
+ break;
+ case OMP_CLAUSE_BIND_PARALLEL:
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
+ break;
+ }
+ for (; octx; octx = octx->outer_context)
+ if (octx->region_type == ORT_SIMD
+ && omp_find_clause (octx->clauses, OMP_CLAUSE_BIND) == NULL_TREE)
+ {
+ error_at (EXPR_LOCATION (for_stmt),
+ "%<bind(parallel)%> on a %<loop%> construct nested "
+ "inside %<simd%> construct");
+ OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
+ break;
+ }
+ kind = OMP_CLAUSE_BIND_PARALLEL;
+ break;
+ case OMP_CLAUSE_BIND_TEAMS:
+ if (!flag_openmp) /* flag_openmp_simd */
+ {
+ OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
+ break;
+ }
+ if ((octx
+ && octx->region_type != ORT_IMPLICIT_TARGET
+ && octx->region_type != ORT_NONE
+ && (octx->region_type & ORT_TEAMS) == 0)
+ || in_omp_construct)
+ {
+ error_at (EXPR_LOCATION (for_stmt),
+ "%<bind(teams)%> on a %<loop%> region not strictly "
+ "nested inside of a %<teams%> region");
+ OMP_CLAUSE_BIND_KIND (bind) = OMP_CLAUSE_BIND_THREAD;
+ break;
+ }
+ kind = OMP_CLAUSE_BIND_TEAMS;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ for (tree *pc = &OMP_FOR_CLAUSES (for_stmt); *pc; )
+ switch (OMP_CLAUSE_CODE (*pc))
+ {
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_INSCAN (*pc))
+ {
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<inscan%> %<reduction%> clause on "
+ "%qs construct", "loop");
+ OMP_CLAUSE_REDUCTION_INSCAN (*pc) = 0;
+ }
+ if (OMP_CLAUSE_REDUCTION_TASK (*pc))
+ {
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "invalid %<task%> reduction modifier on construct "
+ "other than %<parallel%>, %<for%> or %<sections%>");
+ OMP_CLAUSE_REDUCTION_TASK (*pc) = 0;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ break;
+ case OMP_CLAUSE_LASTPRIVATE:
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
+ {
+ tree t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
+ gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
+ if (OMP_CLAUSE_DECL (*pc) == TREE_OPERAND (t, 0))
+ break;
+ if (OMP_FOR_ORIG_DECLS (for_stmt)
+ && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
+ i)) == TREE_LIST
+ && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt),
+ i)))
+ {
+ tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
+ if (OMP_CLAUSE_DECL (*pc) == TREE_PURPOSE (orig))
+ break;
+ }
+ }
+ if (i == TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)))
+ {
+ error_at (OMP_CLAUSE_LOCATION (*pc),
+ "%<lastprivate%> clause on a %<loop%> construct refers "
+ "to a variable %qD which is not the loop iterator",
+ OMP_CLAUSE_DECL (*pc));
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ break;
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ break;
+ default:
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ break;
+ }
+
+ TREE_SET_CODE (for_stmt, OMP_SIMD);
+
+ int last;
+ switch (kind)
+ {
+ case OMP_CLAUSE_BIND_THREAD: last = 0; break;
+ case OMP_CLAUSE_BIND_PARALLEL: last = 1; break;
+ case OMP_CLAUSE_BIND_TEAMS: last = 2; break;
+ }
+ for (int pass = 1; pass <= last; pass++)
+ {
+ if (pass == 2)
+ {
+ tree bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+ append_to_statement_list (*expr_p, &BIND_EXPR_BODY (bind));
+ *expr_p = make_node (OMP_PARALLEL);
+ TREE_TYPE (*expr_p) = void_type_node;
+ OMP_PARALLEL_BODY (*expr_p) = bind;
+ OMP_PARALLEL_COMBINED (*expr_p) = 1;
+ SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
+ }
+ tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
+ tree *pc = &OMP_FOR_CLAUSES (t);
+ TREE_TYPE (t) = void_type_node;
+ OMP_FOR_BODY (t) = *expr_p;
+ SET_EXPR_LOCATION (t, EXPR_LOCATION (for_stmt));
+ for (tree c = OMP_FOR_CLAUSES (for_stmt); c; c = OMP_CLAUSE_CHAIN (c))
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_BIND:
+ case OMP_CLAUSE_ORDER:
+ case OMP_CLAUSE_COLLAPSE:
+ *pc = copy_node (c);
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ break;
+ case OMP_CLAUSE_PRIVATE:
+ /* Only needed on innermost. */
+ break;
+ case OMP_CLAUSE_LASTPRIVATE:
+ *pc = copy_node (c);
+ OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
+ TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ break;
+ case OMP_CLAUSE_REDUCTION:
+ *pc = copy_node (c);
+ OMP_CLAUSE_DECL (*pc) = unshare_expr (OMP_CLAUSE_DECL (c));
+ TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
+ OMP_CLAUSE_REDUCTION_INIT (*pc)
+ = unshare_expr (OMP_CLAUSE_REDUCTION_INIT (c));
+ OMP_CLAUSE_REDUCTION_MERGE (*pc)
+ = unshare_expr (OMP_CLAUSE_REDUCTION_MERGE (c));
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc))
+ {
+ OMP_CLAUSE_REDUCTION_PLACEHOLDER (*pc)
+ = copy_node (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c));
+ if (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc))
+ OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (*pc)
+ = copy_node (OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER (c));
+ tree nc = *pc;
+ tree data[2] = { c, nc };
+ walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_INIT (nc),
+ replace_reduction_placeholders,
+ data);
+ walk_tree_without_duplicates (&OMP_CLAUSE_REDUCTION_MERGE (nc),
+ replace_reduction_placeholders,
+ data);
+ }
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ *pc = NULL_TREE;
+ *expr_p = t;
+ }
+ return gimplify_omp_for (expr_p, pre_p);
+}
+
+
/* Helper function of optimize_target_teams, find OMP_TEAMS inside
of OMP_TARGET's body. */
@@ -11940,10 +12241,7 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
case OMP_TEAMS:
ort = OMP_TEAMS_COMBINED (expr) ? ORT_COMBINED_TEAMS : ORT_TEAMS;
if (gimplify_omp_ctxp == NULL
- || (gimplify_omp_ctxp->region_type == ORT_TARGET
- && gimplify_omp_ctxp->outer_context == NULL
- && lookup_attribute ("omp declare target",
- DECL_ATTRIBUTES (current_function_decl))))
+ || gimplify_omp_ctxp->region_type == ORT_IMPLICIT_TARGET)
ort = (enum omp_region_type) (ort | ORT_HOST_TEAMS);
break;
case OACC_HOST_DATA:
@@ -11952,6 +12250,10 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
default:
gcc_unreachable ();
}
+
+ bool save_in_omp_construct = in_omp_construct;
+ if ((ort & ORT_ACC) == 0)
+ in_omp_construct = false;
gimplify_scan_omp_clauses (&OMP_CLAUSES (expr), pre_p, ort,
TREE_CODE (expr));
if (TREE_CODE (expr) == OMP_TARGET)
@@ -11993,6 +12295,7 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
gimplify_and_add (OMP_BODY (expr), &body);
gimplify_adjust_omp_clauses (pre_p, body, &OMP_CLAUSES (expr),
TREE_CODE (expr));
+ in_omp_construct = save_in_omp_construct;
switch (TREE_CODE (expr))
{
@@ -13079,7 +13382,22 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
input_location = UNKNOWN_LOCATION;
eval = cleanup = NULL;
gimplify_and_add (TREE_OPERAND (*expr_p, 0), &eval);
- gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
+ if (TREE_CODE (*expr_p) == TRY_FINALLY_EXPR
+ && TREE_CODE (TREE_OPERAND (*expr_p, 1)) == EH_ELSE_EXPR)
+ {
+ gimple_seq n = NULL, e = NULL;
+ gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
+ 0), &n);
+ gimplify_and_add (TREE_OPERAND (TREE_OPERAND (*expr_p, 1),
+ 1), &e);
+ if (!gimple_seq_empty_p (n) && !gimple_seq_empty_p (e))
+ {
+ geh_else *stmt = gimple_build_eh_else (n, e);
+ gimple_seq_add_stmt (&cleanup, stmt);
+ }
+ }
+ else
+ gimplify_and_add (TREE_OPERAND (*expr_p, 1), &cleanup);
/* Don't create bogus GIMPLE_TRY with empty cleanup. */
if (gimple_seq_empty_p (cleanup))
{
@@ -13217,6 +13535,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
ret = gimplify_omp_for (expr_p, pre_p);
break;
+ case OMP_LOOP:
+ ret = gimplify_omp_loop (expr_p, pre_p);
+ break;
+
case OACC_CACHE:
gimplify_oacc_cache (expr_p, pre_p);
ret = GS_ALL_DONE;
@@ -13258,8 +13580,11 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
{
gimple_seq body = NULL;
gimple *g;
+ bool saved_in_omp_construct = in_omp_construct;
+ in_omp_construct = true;
gimplify_and_add (OMP_BODY (*expr_p), &body);
+ in_omp_construct = saved_in_omp_construct;
switch (TREE_CODE (*expr_p))
{
case OMP_SECTION:
@@ -13302,10 +13627,14 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
gimple_seq body = NULL;
tree *pclauses = &OMP_TASKGROUP_CLAUSES (*expr_p);
+ bool saved_in_omp_construct = in_omp_construct;
gimplify_scan_omp_clauses (pclauses, pre_p, ORT_TASKGROUP,
OMP_TASKGROUP);
gimplify_adjust_omp_clauses (pre_p, NULL, pclauses, OMP_TASKGROUP);
+
+ in_omp_construct = true;
gimplify_and_add (OMP_BODY (*expr_p), &body);
+ in_omp_construct = saved_in_omp_construct;
gimple_seq cleanup = NULL;
tree fn = builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_END);
gimple *g = gimple_build_call (fn, 0);
@@ -13637,6 +13966,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
&& code != LOOP_EXPR
&& code != SWITCH_EXPR
&& code != TRY_FINALLY_EXPR
+ && code != EH_ELSE_EXPR
&& code != OACC_PARALLEL
&& code != OACC_KERNELS
&& code != OACC_DATA
@@ -13927,7 +14257,7 @@ gimplify_body (tree fndecl, bool do_parms)
{
gcc_assert (gimplify_omp_ctxp == NULL);
if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)))
- gimplify_omp_ctxp = new_omp_context (ORT_TARGET);
+ gimplify_omp_ctxp = new_omp_context (ORT_IMPLICIT_TARGET);
}
/* Unshare most shared trees in the body and in that of any nested functions.
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 7ca79c8..ba7282e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-bf66d40bc7adb438dcfac85d73bfa7b17217eed9
+480477ca64c3001b9c7e92ef8b978dc92a5912d2
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc
index cb778a0..32ab498 100644
--- a/gcc/go/gofrontend/export.cc
+++ b/gcc/go/gofrontend/export.cc
@@ -111,7 +111,7 @@ class Collect_export_references : public Traverse
: Traverse(traverse_expressions
| traverse_types),
exp_(exp), exports_(exports), imports_(imports),
- inline_fcn_worklist_(NULL)
+ inline_fcn_worklist_(NULL), exports_finalized_(false)
{ }
// Initial entry point; performs a walk to expand the exports set.
@@ -121,7 +121,7 @@ class Collect_export_references : public Traverse
// Second entry point (called after the method above), to find
// all types referenced by exports.
void
- prepare_types();
+ prepare_types(const std::vector<Named_object*>& sorted_exports);
protected:
// Override of parent class method.
@@ -141,6 +141,13 @@ class Collect_export_references : public Traverse
traverse_named_type(Named_type*);
private:
+
+ // Add a named object to the exports set (during expand_exports()).
+ // Returns TRUE if a new object was added to the exports set,
+ // FALSE otherwise.
+ bool
+ add_to_exports(Named_object*);
+
// The exporter.
Export* exp_;
// The set of named objects to export.
@@ -152,6 +159,8 @@ class Collect_export_references : public Traverse
// Worklist of functions we are exporting with inline bodies that need
// to be checked.
std::vector<Named_object*>* inline_fcn_worklist_;
+ // Set to true if expand_exports() has been called and is complete.
+ bool exports_finalized_;
};
void
@@ -172,6 +181,18 @@ Collect_export_references::expand_exports(std::vector<Named_object*>* fcns)
}
}
this->inline_fcn_worklist_ = NULL;
+ this->exports_finalized_ = true;
+}
+
+bool
+Collect_export_references::add_to_exports(Named_object* no)
+{
+ std::pair<Unordered_set(Named_object*)::iterator, bool> ins =
+ this->exports_->insert(no);
+ // If the export list has been finalized, then we should not be
+ // adding anything new to the exports set.
+ go_assert(!this->exports_finalized_ || !ins.second);
+ return ins.second;
}
int
@@ -189,7 +210,7 @@ Collect_export_references::expression(Expression** pexpr)
if (var_package != NULL)
this->imports_->insert(var_package);
- this->exports_->insert(no);
+ this->add_to_exports(no);
no->var_value()->set_is_referenced_by_inline();
}
return TRAVERSE_CONTINUE;
@@ -210,17 +231,16 @@ Collect_export_references::expression(Expression** pexpr)
if (this->inline_fcn_worklist_ != NULL)
{
- std::pair<Unordered_set(Named_object*)::iterator, bool> ins =
- this->exports_->insert(no);
+ bool added = this->add_to_exports(no);
if (no->is_function())
no->func_value()->set_is_referenced_by_inline();
- // If ins.second is false then this object was already in
+ // If 'added' is false then this object was already in
// exports_, in which case it was already added to
// check_inline_refs_ the first time we added it to exports_, so
// we don't need to add it again.
- if (ins.second
+ if (added
&& no->is_function()
&& no->func_value()->export_for_inlining())
this->inline_fcn_worklist_->push_back(no);
@@ -238,11 +258,11 @@ Collect_export_references::expression(Expression** pexpr)
// exported inline function from another package).
void
-Collect_export_references::prepare_types()
+Collect_export_references::prepare_types(const std::vector<Named_object*>& sorted_exports)
{
// Iterate through the exported objects and traverse any types encountered.
- for (Unordered_set(Named_object*)::iterator p = this->exports_->begin();
- p != this->exports_->end();
+ for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
+ p != sorted_exports.end();
++p)
{
Named_object* no = *p;
@@ -506,7 +526,8 @@ Export::export_globals(const std::string& package_name,
const std::map<std::string, Package*>& imports,
const std::string& import_init_fn,
const Import_init_set& imported_init_fns,
- const Bindings* bindings)
+ const Bindings* bindings,
+ Unordered_set(Named_object*)* functions_marked_inline)
{
// If there have been any errors so far, don't try to export
// anything. That way the export code doesn't have to worry about
@@ -520,35 +541,21 @@ Export::export_globals(const std::string& package_name,
// CHECK_INLINE_REFS is also on EXPORTS.
Unordered_set(Named_object*) exports;
std::vector<Named_object*> check_inline_refs;
+ check_inline_refs.reserve(functions_marked_inline->size());
+
+ // Add all functions/methods from the "marked inlined" set to the
+ // CHECK_INLINE_REFS worklist.
+ for (Unordered_set(Named_object*)::const_iterator p = functions_marked_inline->begin();
+ p != functions_marked_inline->end();
+ ++p)
+ check_inline_refs.push_back(*p);
for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
p != bindings->end_definitions();
++p)
{
if (should_export(*p))
- {
- exports.insert(*p);
-
- if ((*p)->is_function()
- && (*p)->func_value()->export_for_inlining())
- check_inline_refs.push_back(*p);
- else if ((*p)->is_type())
- {
- const Bindings* methods = (*p)->type_value()->local_methods();
- if (methods != NULL)
- {
- for (Bindings::const_definitions_iterator pm =
- methods->begin_definitions();
- pm != methods->end_definitions();
- ++pm)
- {
- Function* fn = (*pm)->func_value();
- if (fn->export_for_inlining())
- check_inline_refs.push_back(*pm);
- }
- }
- }
- }
+ exports.insert(*p);
}
for (Bindings::const_declarations_iterator p =
@@ -593,7 +600,7 @@ Export::export_globals(const std::string& package_name,
// Collect up the set of types mentioned in things we're exporting,
// and any packages that may be referred to indirectly.
- collect.prepare_types();
+ collect.prepare_types(sorted_exports);
// Assign indexes to all exported types and types referenced by
// things we're exporting. Return value is index of first non-exported
diff --git a/gcc/go/gofrontend/export.h b/gcc/go/gofrontend/export.h
index 1af386c1..c93bced 100644
--- a/gcc/go/gofrontend/export.h
+++ b/gcc/go/gofrontend/export.h
@@ -158,7 +158,8 @@ class Export : public String_dump
const std::map<std::string, Package*>& imports,
const std::string& import_init_fn,
const Import_init_set& imported_init_fns,
- const Bindings* bindings);
+ const Bindings* bindings,
+ Unordered_set(Named_object*)* marked_inline_functions);
// Record a type that is mentioned in export data. Return value is
// TRUE for newly visited types, FALSE for types that have been seen
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 2c6a080..3b65e7a 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -1628,6 +1628,10 @@ class Set_and_use_temporary_expression : public Expression
}
bool
+ do_must_eval_in_order() const
+ { return true; }
+
+ bool
do_is_addressable() const
{ return true; }
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index fcf9a93..30523f7 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -3422,24 +3422,6 @@ Gogo::create_function_descriptors()
this->traverse(&cfd);
}
-// Look for interface types to finalize methods of inherited
-// interfaces.
-
-class Finalize_methods : public Traverse
-{
- public:
- Finalize_methods(Gogo* gogo)
- : Traverse(traverse_types),
- gogo_(gogo)
- { }
-
- int
- type(Type*);
-
- private:
- Gogo* gogo_;
-};
-
// Finalize the methods of an interface type.
int
@@ -4115,6 +4097,15 @@ Gogo::order_evaluations()
this->traverse(&order_eval);
}
+// Order evaluations in a block.
+
+void
+Gogo::order_block(Block* block)
+{
+ Order_eval order_eval(this);
+ block->traverse(&order_eval);
+}
+
// A traversal class used to find a single shortcut operator within an
// expression.
@@ -4324,6 +4315,15 @@ Gogo::remove_shortcuts()
this->traverse(&shortcuts);
}
+// Turn shortcut operators into explicit if statements in a block.
+
+void
+Gogo::remove_shortcuts_in_block(Block* block)
+{
+ Shortcuts shortcuts(this);
+ block->traverse(&shortcuts);
+}
+
// Traversal to flatten parse tree after order of evaluation rules are applied.
class Flatten : public Traverse
@@ -5078,9 +5078,10 @@ Inline_within_budget::expression(Expression** pexpr)
class Mark_inline_candidates : public Traverse
{
public:
- Mark_inline_candidates()
+ Mark_inline_candidates(Unordered_set(Named_object*)* marked)
: Traverse(traverse_functions
- | traverse_types)
+ | traverse_types),
+ marked_functions_(marked)
{ }
int
@@ -5097,6 +5098,9 @@ class Mark_inline_candidates : public Traverse
// budget is a heuristic. In the usual GCC spirit, we could
// consider setting this via a command line option.
const int budget_heuristic = 80;
+
+ // Set of named objects that are marked as inline candidates.
+ Unordered_set(Named_object*)* marked_functions_;
};
// Mark a function if it is an inline candidate.
@@ -5105,11 +5109,16 @@ int
Mark_inline_candidates::function(Named_object* no)
{
Function* func = no->func_value();
+ if ((func->pragmas() & GOPRAGMA_NOINLINE) != 0)
+ return TRAVERSE_CONTINUE;
int budget = budget_heuristic;
Inline_within_budget iwb(&budget);
func->block()->traverse(&iwb);
if (budget >= 0)
- func->set_export_for_inlining();
+ {
+ func->set_export_for_inlining();
+ this->marked_functions_->insert(no);
+ }
return TRAVERSE_CONTINUE;
}
@@ -5131,11 +5140,16 @@ Mark_inline_candidates::type(Type* t)
Named_object* no = *p;
go_assert(no->is_function());
Function *func = no->func_value();
+ if ((func->pragmas() & GOPRAGMA_NOINLINE) != 0)
+ continue;
int budget = budget_heuristic;
Inline_within_budget iwb(&budget);
func->block()->traverse(&iwb);
if (budget >= 0)
- func->set_export_for_inlining();
+ {
+ func->set_export_for_inlining();
+ this->marked_functions_->insert(no);
+ }
}
return TRAVERSE_CONTINUE;
}
@@ -5150,7 +5164,8 @@ Gogo::do_exports()
// Mark any functions whose body should be exported for inlining by
// other packages.
- Mark_inline_candidates mic;
+ Unordered_set(Named_object*) marked_functions;
+ Mark_inline_candidates mic(&marked_functions);
this->traverse(&mic);
// For now we always stream to a section. Later we may want to
@@ -5187,7 +5202,8 @@ Gogo::do_exports()
this->imports_,
init_fn_name,
this->imported_init_fns_,
- this->package_->bindings());
+ this->package_->bindings(),
+ &marked_functions);
if (!this->c_header_.empty() && !saw_errors())
this->write_c_header();
@@ -6262,7 +6278,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
if (this->asm_name_ == "runtime.gopanic"
|| this->asm_name_ == "__go_runtime_error"
- || this->asm_name_ == "runtime.panicdottype")
+ || this->asm_name_ == "runtime.panicdottype"
+ || this->asm_name_ == "runtime.block")
flags |= Backend::function_does_not_return;
}
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index c4d5bab..6ffdc59 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -749,10 +749,18 @@ class Gogo
void
remove_shortcuts();
+ // Turn short-cut operators into explicit if statements in a block.
+ void
+ remove_shortcuts_in_block(Block*);
+
// Use temporary variables to force order of evaluation.
void
order_evaluations();
+ // Order evaluations in a block.
+ void
+ order_block(Block*);
+
// Add write barriers as needed.
void
add_write_barriers();
@@ -3556,6 +3564,24 @@ class Traverse
Expressions_seen* expressions_seen_;
};
+// This class looks for interface types to finalize methods of inherited
+// interfaces.
+
+class Finalize_methods : public Traverse
+{
+ public:
+ Finalize_methods(Gogo* gogo)
+ : Traverse(traverse_types),
+ gogo_(gogo)
+ { }
+
+ int
+ type(Type*);
+
+ private:
+ Gogo* gogo_;
+};
+
// A class which makes it easier to insert new statements before the
// current statement during a traversal.
diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc
index abf0b54..64c1ef2 100644
--- a/gcc/go/gofrontend/import.cc
+++ b/gcc/go/gofrontend/import.cc
@@ -290,10 +290,16 @@ Import::Import(Stream* stream, Location location)
: gogo_(NULL), stream_(stream), location_(location), package_(NULL),
add_to_globals_(false), packages_(), type_data_(), type_pos_(0),
type_offsets_(), builtin_types_((- SMALLEST_BUILTIN_CODE) + 1),
- types_(), version_(EXPORT_FORMAT_UNKNOWN)
+ types_(), finalizer_(NULL), version_(EXPORT_FORMAT_UNKNOWN)
{
}
+Import::~Import()
+{
+ if (this->finalizer_ != NULL)
+ delete this->finalizer_;
+}
+
// Import the data in the associated stream.
Package*
@@ -444,6 +450,14 @@ Import::import(Gogo* gogo, const std::string& local_name,
this->require_c_string("\n");
}
+ // Finalize methods for any imported types. This call is made late in the
+ // import process so as to A) avoid finalization of a type whose methods
+ // refer to types that are only partially read in, and B) capture both the
+ // types imported by read_types() directly, and those imported indirectly
+ // because they are referenced by an imported function or variable.
+ // See issues #33013 and #33219 for more on why this is needed.
+ this->finalize_methods();
+
return this->package_;
}
@@ -675,6 +689,31 @@ Import::read_types()
return true;
}
+void
+Import::finalize_methods()
+{
+ if (this->finalizer_ == NULL)
+ this->finalizer_ = new Finalize_methods(gogo_);
+ Unordered_set(Type*) real_for_named;
+ for (size_t i = 1; i < this->types_.size(); i++)
+ {
+ Type* type = this->types_[i];
+ if (type != NULL && type->named_type() != NULL)
+ {
+ this->finalizer_->type(type);
+ real_for_named.insert(type->named_type()->real_type());
+ }
+ }
+ for (size_t i = 1; i < this->types_.size(); i++)
+ {
+ Type* type = this->types_[i];
+ if (type != NULL
+ && type->named_type() == NULL
+ && real_for_named.find(type) == real_for_named.end())
+ this->finalizer_->type(type);
+ }
+}
+
// Import a constant.
void
@@ -1498,6 +1537,26 @@ Stream_from_file::do_advance(size_t skip)
// Class Import_function_body.
+Import_function_body::Import_function_body(Gogo* gogo,
+ Import* imp,
+ Named_object* named_object,
+ const std::string& body,
+ size_t off,
+ Block* block,
+ int indent)
+ : gogo_(gogo), imp_(imp), named_object_(named_object), body_(body),
+ off_(off), indent_(indent), temporaries_(), labels_(),
+ saw_error_(false)
+{
+ this->blocks_.push_back(block);
+}
+
+Import_function_body::~Import_function_body()
+{
+ // At this point we should be left with the original outer block only.
+ go_assert(saw_errors() || this->blocks_.size() == 1);
+}
+
// The name of the function we are parsing.
const std::string&
diff --git a/gcc/go/gofrontend/import.h b/gcc/go/gofrontend/import.h
index db51f72..a78e48b 100644
--- a/gcc/go/gofrontend/import.h
+++ b/gcc/go/gofrontend/import.h
@@ -20,6 +20,7 @@ class Expression;
class Import_function_body;
class Temporary_statement;
class Unnamed_label;
+class Finalize_methods;
// Expressions can be imported either directly from import data (for
// simple constant expressions that can appear in a const declaration
@@ -207,8 +208,7 @@ class Import : public Import_expression
// Constructor.
Import(Stream*, Location);
- virtual ~Import()
- {}
+ virtual ~Import();
// Register the builtin types.
void
@@ -423,6 +423,10 @@ class Import : public Import_expression
return true;
}
+ // Finalize methods for newly imported types.
+ void
+ finalize_methods();
+
// The general IR.
Gogo* gogo_;
// The stream from which to read import data.
@@ -446,6 +450,8 @@ class Import : public Import_expression
std::vector<Named_type*> builtin_types_;
// Mapping from exported type codes to Type structures.
std::vector<Type*> types_;
+ // Helper for finalizing methods.
+ Finalize_methods* finalizer_;
// Version of export data we're reading.
Export_data_version version_;
};
@@ -587,11 +593,8 @@ class Import_function_body : public Import_expression
public:
Import_function_body(Gogo* gogo, Import* imp, Named_object* named_object,
const std::string& body, size_t off, Block* block,
- int indent)
- : gogo_(gogo), imp_(imp), named_object_(named_object), body_(body),
- off_(off), block_(block), indent_(indent), temporaries_(), labels_(),
- saw_error_(false)
- { }
+ int indent);
+ ~Import_function_body();
// The IR.
Gogo*
@@ -631,7 +634,17 @@ class Import_function_body : public Import_expression
// The current block.
Block*
block()
- { return this->block_; }
+ { return this->blocks_.back(); }
+
+ // Begin importing a new block BLOCK nested within the current block.
+ void
+ begin_block(Block *block)
+ { this->blocks_.push_back(block); }
+
+ // Record the fact that we're done importing the current block.
+ void
+ finish_block()
+ { this->blocks_.pop_back(); }
// The current indentation.
int
@@ -751,8 +764,8 @@ class Import_function_body : public Import_expression
const std::string& body_;
// The current offset into body_.
size_t off_;
- // Current block.
- Block* block_;
+ // Stack to record nesting of blocks being imported.
+ std::vector<Block *> blocks_;
// Current expected indentation level.
int indent_;
// Temporary statements by index.
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index f510a65..c754739 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -204,6 +204,22 @@ DEF_GO_RUNTIME(CHANRECV2, "runtime.chanrecv2", P2(CHAN, POINTER), R1(BOOL))
DEF_GO_RUNTIME(SELECTGO, "runtime.selectgo", P3(POINTER, POINTER, INT),
R2(INT, BOOL))
+// Non-blocking send a value on a channel, used for two-case select
+// statement with a default case.
+DEF_GO_RUNTIME(SELECTNBSEND, "runtime.selectnbsend", P2(CHAN, POINTER), R1(BOOL))
+
+// Non-blocking receive a value from a channel, used for two-case select
+// statement with a default case.
+DEF_GO_RUNTIME(SELECTNBRECV, "runtime.selectnbrecv", P2(POINTER, CHAN), R1(BOOL))
+
+// Non-blocking tuple receive from a channel, used for two-case select
+// statement with a default case.
+DEF_GO_RUNTIME(SELECTNBRECV2, "runtime.selectnbrecv2", P3(POINTER, POINTER, CHAN),
+ R1(BOOL))
+
+// Block execution. Used for zero-case select.
+DEF_GO_RUNTIME(BLOCK, "runtime.block", P0(), R0())
+
// Panic.
DEF_GO_RUNTIME(GOPANIC, "runtime.gopanic", P1(EFACE), R0())
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 968c8a0..6d9c0eb 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -2176,7 +2176,9 @@ Block_statement::do_import(Import_function_body* ifb, Location loc,
ifb->set_off(nl + 1);
ifb->increment_indent();
Block* block = new Block(ifb->block(), loc);
+ ifb->begin_block(block);
bool ok = Block::import_block(block, ifb, loc);
+ ifb->finish_block();
ifb->decrement_indent();
if (!ok)
return NULL;
@@ -5665,6 +5667,28 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
Block* b = new Block(enclosing, loc);
int ncases = this->clauses_->size();
+
+ // Zero-case select. Just block the execution.
+ if (ncases == 0)
+ {
+ Expression* call = Runtime::make_call(Runtime::BLOCK, loc, 0);
+ Statement *s = Statement::make_statement(call, false);
+ b->add_statement(s);
+ this->is_lowered_ = true;
+ return Statement::make_block_statement(b, loc);
+ }
+
+ // One-case select. It is mostly just to run the case.
+ if (ncases == 1)
+ return this->lower_one_case(b);
+
+ // Two-case select with one default case. It is a non-blocking
+ // send/receive.
+ if (ncases == 2
+ && (this->clauses_->at(0).is_default()
+ || this->clauses_->at(1).is_default()))
+ return this->lower_two_case(b);
+
Type* scase_type = Channel_type::select_case_type();
Expression* ncases_expr =
Expression::make_integer_ul(ncases, NULL,
@@ -5733,6 +5757,222 @@ Select_statement::do_lower(Gogo* gogo, Named_object* function,
return Statement::make_block_statement(b, loc);
}
+// Lower a one-case select statement.
+
+Statement*
+Select_statement::lower_one_case(Block* b)
+{
+ Select_clauses::Select_clause& scase = this->clauses_->at(0);
+ Location loc = this->location();
+ Expression* chan = scase.channel();
+ if (chan != NULL)
+ {
+ // Lower this to
+ // if chan == nil { block() }; send/recv; body
+ Temporary_statement* chantmp = Statement::make_temporary(NULL, chan, loc);
+ b->add_statement(chantmp);
+ Expression* chanref = Expression::make_temporary_reference(chantmp, loc);
+
+ Expression* nil = Expression::make_nil(loc);
+ Expression* cond = Expression::make_binary(OPERATOR_EQEQ, chanref, nil, loc);
+ Block* bnil = new Block(b, loc);
+ Expression* call = Runtime::make_call(Runtime::BLOCK, loc, 0);
+ Statement* s = Statement::make_statement(call, false);
+ bnil->add_statement(s);
+ Statement* ifs = Statement::make_if_statement(cond, bnil, NULL, loc);
+ b->add_statement(ifs);
+
+ chanref = chanref->copy();
+ Location cloc = scase.location();
+ if (scase.is_send())
+ {
+ s = Statement::make_send_statement(chanref, scase.val(), cloc);
+ b->add_statement(s);
+ }
+ else
+ {
+ if (scase.closed() == NULL && scase.closedvar() == NULL)
+ {
+ // Simple receive.
+ Expression* recv = Expression::make_receive(chanref, cloc);
+ if (scase.val() != NULL)
+ s = Statement::make_assignment(scase.val(), recv, cloc);
+ else if (scase.var() != NULL)
+ {
+ Temporary_statement *ts =
+ Statement::make_temporary(NULL, recv, cloc);
+ Expression* ref =
+ Expression::make_temporary_reference(ts, cloc);
+ s = ts;
+ scase.var()->var_value()->set_init(ref);
+ scase.var()->var_value()->clear_type_from_chan_element();
+ }
+ else
+ s = Statement::make_statement(recv, false);
+ b->add_statement(s);
+ }
+ else
+ {
+ // Tuple receive.
+ Expression* lhs;
+ if (scase.val() != NULL)
+ lhs = scase.val();
+ else
+ {
+ Type* valtype = chan->type()->channel_type()->element_type();
+ Temporary_statement *ts =
+ Statement::make_temporary(valtype, NULL, cloc);
+ lhs = Expression::make_temporary_reference(ts, cloc);
+ b->add_statement(ts);
+ }
+
+ Expression* lhs2;
+ if (scase.closed() != NULL)
+ lhs2 = scase.closed();
+ else
+ {
+ Type* booltype = Type::make_boolean_type();
+ Temporary_statement *ts =
+ Statement::make_temporary(booltype, NULL, cloc);
+ lhs2 = Expression::make_temporary_reference(ts, cloc);
+ b->add_statement(ts);
+ }
+
+ s = Statement::make_tuple_receive_assignment(lhs, lhs2, chanref, cloc);
+ b->add_statement(s);
+
+ if (scase.var() != NULL)
+ {
+ scase.var()->var_value()->set_init(lhs->copy());
+ scase.var()->var_value()->clear_type_from_chan_element();
+ }
+
+ if (scase.closedvar() != NULL)
+ scase.closedvar()->var_value()->set_init(lhs2->copy());
+ }
+ }
+ }
+
+ Statement* bs =
+ Statement::make_block_statement(scase.statements(), scase.location());
+ b->add_statement(bs);
+
+ Statement* label =
+ Statement::make_unnamed_label_statement(this->break_label());
+ b->add_statement(label);
+
+ this->is_lowered_ = true;
+ return Statement::make_block_statement(b, loc);
+}
+
+// Lower a two-case select statement with one default case.
+
+Statement*
+Select_statement::lower_two_case(Block* b)
+{
+ Select_clauses::Select_clause& chancase =
+ (this->clauses_->at(0).is_default()
+ ? this->clauses_->at(1)
+ : this->clauses_->at(0));
+ Select_clauses::Select_clause& defcase =
+ (this->clauses_->at(0).is_default()
+ ? this->clauses_->at(0)
+ : this->clauses_->at(1));
+ Location loc = this->location();
+ Expression* chan = chancase.channel();
+ Type* valtype = chan->type()->channel_type()->element_type();
+
+ Temporary_statement* chantmp = Statement::make_temporary(NULL, chan, loc);
+ b->add_statement(chantmp);
+ Expression* chanref = Expression::make_temporary_reference(chantmp, loc);
+
+ Block* bchan;
+ Expression* call;
+ if (chancase.is_send())
+ {
+ // if selectnbsend(chan, &val) { body } else { default body }
+
+ Temporary_statement* ts =
+ Statement::make_temporary(valtype, chancase.val(), loc);
+ // Tell the escape analysis that the value escapes, as it may be sent
+ // to a channel.
+ ts->set_value_escapes();
+ b->add_statement(ts);
+
+ Expression* ref = Expression::make_temporary_reference(ts, loc);
+ Expression* addr = Expression::make_unary(OPERATOR_AND, ref, loc);
+ call = Runtime::make_call(Runtime::SELECTNBSEND, loc, 2, chanref, addr);
+ bchan = chancase.statements();
+ }
+ else
+ {
+ Temporary_statement* ts = Statement::make_temporary(valtype, NULL, loc);
+ b->add_statement(ts);
+
+ Expression* ref = Expression::make_temporary_reference(ts, loc);
+ Expression* addr = Expression::make_unary(OPERATOR_AND, ref, loc);
+ Expression* okref = NULL;
+ if (chancase.closed() == NULL && chancase.closedvar() == NULL)
+ {
+ // Simple receive.
+ // if selectnbrecv(&lhs, chan) { body } else { default body }
+ call = Runtime::make_call(Runtime::SELECTNBRECV, loc, 2, addr, chanref);
+ }
+ else
+ {
+ // Tuple receive.
+ // if selectnbrecv2(&lhs, &ok, chan) { body } else { default body }
+
+ Type* booltype = Type::make_boolean_type();
+ Temporary_statement* ts = Statement::make_temporary(booltype, NULL, loc);
+ b->add_statement(ts);
+
+ okref = Expression::make_temporary_reference(ts, loc);
+ Expression* okaddr = Expression::make_unary(OPERATOR_AND, okref, loc);
+ call = Runtime::make_call(Runtime::SELECTNBRECV2, loc, 3, addr, okaddr,
+ chanref);
+ }
+
+ Location cloc = chancase.location();
+ bchan = new Block(b, loc);
+ if (chancase.val() != NULL && !chancase.val()->is_sink_expression())
+ {
+ Statement* as = Statement::make_assignment(chancase.val(), ref->copy(),
+ cloc);
+ bchan->add_statement(as);
+ }
+ else if (chancase.var() != NULL)
+ {
+ chancase.var()->var_value()->set_init(ref->copy());
+ chancase.var()->var_value()->clear_type_from_chan_element();
+ }
+
+ if (chancase.closed() != NULL && !chancase.closed()->is_sink_expression())
+ {
+ Statement* as = Statement::make_assignment(chancase.closed(),
+ okref->copy(), cloc);
+ bchan->add_statement(as);
+ }
+ else if (chancase.closedvar() != NULL)
+ chancase.closedvar()->var_value()->set_init(okref->copy());
+
+ Statement* bs = Statement::make_block_statement(chancase.statements(),
+ cloc);
+ bchan->add_statement(bs);
+ }
+
+ Statement* ifs =
+ Statement::make_if_statement(call, bchan, defcase.statements(), loc);
+ b->add_statement(ifs);
+
+ Statement* label =
+ Statement::make_unnamed_label_statement(this->break_label());
+ b->add_statement(label);
+
+ this->is_lowered_ = true;
+ return Statement::make_block_statement(b, loc);
+}
+
// Whether the select statement itself may fall through to the following
// statement.
@@ -5766,6 +6006,7 @@ Select_statement::do_dump_statement(Ast_dump_context* ast_dump_context) const
{
ast_dump_context->ostream() << " {" << dsuffix(location()) << std::endl;
this->clauses_->dump_clauses(ast_dump_context);
+ ast_dump_context->print_indent();
ast_dump_context->ostream() << "}";
}
ast_dump_context->ostream() << std::endl;
diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h
index 432da30..7c254d0 100644
--- a/gcc/go/gofrontend/statements.h
+++ b/gcc/go/gofrontend/statements.h
@@ -1061,7 +1061,7 @@ class Select_clauses
// for the variable to set, and CLOSED is either NULL or a
// Var_expression to set to whether the channel is closed. If VAL
// is NULL, VAR may be a variable to be initialized with the
- // received value, and CLOSEDVAR ma be a variable to be initialized
+ // received value, and CLOSEDVAR may be a variable to be initialized
// with whether the channel is closed. IS_DEFAULT is true if this
// is the default clause. STATEMENTS is the list of statements to
// execute.
@@ -1110,7 +1110,6 @@ class Select_clauses
void
dump_clauses(Ast_dump_context*) const;
- private:
// A single clause.
class Select_clause
{
@@ -1166,8 +1165,30 @@ class Select_clauses
return this->is_send_;
}
+ // Return the value to send or the lvalue to receive into.
+ Expression*
+ val() const
+ { return this->val_; }
+
+ // Return the lvalue to set to whether the channel is closed
+ // on a receive.
+ Expression*
+ closed() const
+ { return this->closed_; }
+
+ // Return the variable to initialize, for "case a := <-ch".
+ Named_object*
+ var() const
+ { return this->var_; }
+
+ // Return the variable to initialize to whether the channel
+ // is closed, for "case a, c := <-ch".
+ Named_object*
+ closedvar() const
+ { return this->closedvar_; }
+
// Return the statements.
- const Block*
+ Block*
statements() const
{ return this->statements_; }
@@ -1235,6 +1256,11 @@ class Select_clauses
bool is_lowered_;
};
+ Select_clause&
+ at(size_t i)
+ { return this->clauses_.at(i); }
+
+ private:
typedef std::vector<Select_clause> Clauses;
Clauses clauses_;
@@ -1288,6 +1314,14 @@ class Select_statement : public Statement
do_dump_statement(Ast_dump_context*) const;
private:
+ // Lower a one-case select statement.
+ Statement*
+ lower_one_case(Block*);
+
+ // Lower a two-case select statement with one defualt case.
+ Statement*
+ lower_two_case(Block*);
+
// The select clauses.
Select_clauses* clauses_;
// A temporary that holds the index value returned by selectgo.
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index cc65bd8..b46525d 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -2098,6 +2098,8 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name, int64_t size,
Block* b = gogo->finish_block(bloc);
gogo->add_block(b, bloc);
gogo->lower_block(hash_fn, b);
+ gogo->order_block(b);
+ gogo->remove_shortcuts_in_block(b);
gogo->finish_function(bloc);
Named_object *equal_fn = gogo->start_function(equal_name, equal_fntype,
@@ -2119,6 +2121,8 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name, int64_t size,
b = gogo->finish_block(bloc);
gogo->add_block(b, bloc);
gogo->lower_block(equal_fn, b);
+ gogo->order_block(b);
+ gogo->remove_shortcuts_in_block(b);
gogo->finish_function(bloc);
// Build the function descriptors for the type descriptor to refer to.
diff --git a/gcc/godump.c b/gcc/godump.c
index 617a9648..ddb19fd 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -535,8 +535,9 @@ go_type_decl (tree decl, int local)
/* A container for the data we pass around when generating information
at the end of the compilation. */
-struct godump_container
+class godump_container
{
+public:
/* DECLs that we have already seen. */
hash_set<tree> decls_seen;
@@ -679,7 +680,7 @@ go_force_record_alignment (struct obstack *ob, const char *type_string,
calls from go_format_type() itself. */
static bool
-go_format_type (struct godump_container *container, tree type,
+go_format_type (class godump_container *container, tree type,
bool use_type_name, bool is_func_ok, unsigned int *p_art_i,
bool is_anon_record_or_union)
{
@@ -1091,7 +1092,7 @@ go_format_type (struct godump_container *container, tree type,
it. */
static void
-go_output_type (struct godump_container *container)
+go_output_type (class godump_container *container)
{
struct obstack *ob;
@@ -1104,7 +1105,7 @@ go_output_type (struct godump_container *container)
/* Output a function declaration. */
static void
-go_output_fndecl (struct godump_container *container, tree decl)
+go_output_fndecl (class godump_container *container, tree decl)
{
if (!go_format_type (container, TREE_TYPE (decl), false, true, NULL, false))
fprintf (go_dump_file, "// ");
@@ -1118,7 +1119,7 @@ go_output_fndecl (struct godump_container *container, tree decl)
/* Output a typedef or something like a struct definition. */
static void
-go_output_typedef (struct godump_container *container, tree decl)
+go_output_typedef (class godump_container *container, tree decl)
{
/* If we have an enum type, output the enum constants
separately. */
@@ -1245,7 +1246,7 @@ go_output_typedef (struct godump_container *container, tree decl)
/* Output a variable. */
static void
-go_output_var (struct godump_container *container, tree decl)
+go_output_var (class godump_container *container, tree decl)
{
bool is_valid;
tree type_name;
@@ -1334,7 +1335,7 @@ static const char * const keywords[] = {
};
static void
-keyword_hash_init (struct godump_container *container)
+keyword_hash_init (class godump_container *container)
{
size_t i;
size_t count = sizeof (keywords) / sizeof (keywords[0]);
@@ -1354,7 +1355,7 @@ keyword_hash_init (struct godump_container *container)
bool
find_dummy_types (const char *const &ptr, godump_container *adata)
{
- struct godump_container *data = (struct godump_container *) adata;
+ class godump_container *data = (class godump_container *) adata;
const char *type = (const char *) ptr;
void **slot;
void **islot;
@@ -1371,7 +1372,7 @@ find_dummy_types (const char *const &ptr, godump_container *adata)
static void
go_finish (const char *filename)
{
- struct godump_container container;
+ class godump_container container;
unsigned int ix;
tree decl;
diff --git a/gcc/graph.c b/gcc/graph.c
index 33e4c03..5452822 100644
--- a/gcc/graph.c
+++ b/gcc/graph.c
@@ -197,7 +197,7 @@ draw_cfg_nodes_no_loops (pretty_printer *pp, struct function *fun)
static void
draw_cfg_nodes_for_loop (pretty_printer *pp, int funcdef_no,
- struct loop *loop)
+ class loop *loop)
{
basic_block *body;
unsigned int i;
@@ -217,7 +217,7 @@ draw_cfg_nodes_for_loop (pretty_printer *pp, int funcdef_no,
fillcolors[(loop_depth (loop) - 1) % 3],
loop->num);
- for (struct loop *inner = loop->inner; inner; inner = inner->next)
+ for (class loop *inner = loop->inner; inner; inner = inner->next)
draw_cfg_nodes_for_loop (pp, funcdef_no, inner);
if (loop->header == NULL)
diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h
index a728196..bd4249b 100644
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -613,8 +613,8 @@ hard_reg_set_iter_next (hard_reg_set_iterator *iter, unsigned *regno)
extern char global_regs[FIRST_PSEUDO_REGISTER];
-struct simplifiable_subreg;
-struct subreg_shape;
+class simplifiable_subreg;
+class subreg_shape;
struct simplifiable_subregs_hasher : nofree_ptr_hash <simplifiable_subreg>
{
diff --git a/gcc/hash-map-tests.c b/gcc/hash-map-tests.c
index 5888f25..f3b216b 100644
--- a/gcc/hash-map-tests.c
+++ b/gcc/hash-map-tests.c
@@ -103,8 +103,9 @@ test_map_of_strings_to_int ()
ASSERT_EQ (1, string_map.elements ());
}
-typedef struct hash_map_test_val_t
+typedef class hash_map_test_val_t
{
+public:
static int ndefault;
static int ncopy;
static int nassign;
diff --git a/gcc/hash-map.h b/gcc/hash-map.h
index f3f1f9a..ba20fe7 100644
--- a/gcc/hash-map.h
+++ b/gcc/hash-map.h
@@ -253,7 +253,8 @@ public:
/* Can't use std::pair here, because GCC before 4.3 don't handle
std::pair where template parameters are references well.
See PR86739. */
- struct reference_pair {
+ class reference_pair {
+ public:
const Key &first;
Value &second;
diff --git a/gcc/hash-set-tests.c b/gcc/hash-set-tests.c
index c96fe53..ce59059 100644
--- a/gcc/hash-set-tests.c
+++ b/gcc/hash-set-tests.c
@@ -134,8 +134,9 @@ test_set_of_strings ()
ASSERT_EQ (2, t.elements ());
}
-typedef struct hash_set_test_value_t
+typedef class hash_set_test_value_t
{
+public:
static int ndefault;
static int ncopy;
static int nassign;
diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c
index 016e61f..45f4149 100644
--- a/gcc/hsa-brig.c
+++ b/gcc/hsa-brig.c
@@ -150,9 +150,8 @@ struct hsa_brig_data_chunk
/* Structure representing a BRIG section, holding and writing its data. */
-class hsa_brig_section
+struct hsa_brig_section
{
-public:
/* Section name that will be output to the BRIG. */
const char *section_name;
/* Size in bytes of all data stored in the section. */
@@ -195,8 +194,9 @@ hash_table <hsa_internal_fn_hasher> *hsa_emitted_internal_decls;
/* List of sbr instructions. */
static vec <hsa_insn_sbr *> *switch_instructions;
-struct function_linkage_pair
+class function_linkage_pair
{
+public:
function_linkage_pair (tree decl, unsigned int off)
: function_decl (decl), offset (off) {}
@@ -578,7 +578,7 @@ static void emit_immediate_operand (hsa_op_immed *imm);
Return the offset of the directive. */
static unsigned
-emit_directive_variable (struct hsa_symbol *symbol)
+emit_directive_variable (class hsa_symbol *symbol)
{
struct BrigDirectiveVariable dirvar;
unsigned name_offset;
diff --git a/gcc/hsa-common.h b/gcc/hsa-common.h
index 9c61786..9122539 100644
--- a/gcc/hsa-common.h
+++ b/gcc/hsa-common.h
@@ -55,8 +55,9 @@ class hsa_bb;
/* Class representing an input argument, output argument (result) or a
variable, that will eventually end up being a symbol directive. */
-struct hsa_symbol
+class hsa_symbol
{
+public:
/* Constructor. */
hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
BrigLinkage8_t linkage, bool global_scope_p = false,
@@ -1067,7 +1068,7 @@ private:
static inline hsa_bb *
hsa_bb_for_bb (basic_block bb)
{
- return (struct hsa_bb *) bb->aux;
+ return (class hsa_bb *) bb->aux;
}
/* Class for hashing local hsa_symbols. */
@@ -1149,14 +1150,14 @@ public:
hash_map <tree, hsa_symbol *> m_string_constants_map;
/* Vector of pointers to spill symbols. */
- vec <struct hsa_symbol *> m_spill_symbols;
+ vec <class hsa_symbol *> m_spill_symbols;
/* Vector of pointers to global variables and transformed string constants
that are used by the function. */
- vec <struct hsa_symbol *> m_global_symbols;
+ vec <class hsa_symbol *> m_global_symbols;
/* Private function artificial variables. */
- vec <struct hsa_symbol *> m_private_variables;
+ vec <class hsa_symbol *> m_private_variables;
/* Vector of called function declarations. */
vec <tree> m_called_functions;
@@ -1213,8 +1214,9 @@ enum hsa_function_kind
HSA_FUNCTION
};
-struct hsa_function_summary
+class hsa_function_summary
{
+public:
/* Default constructor. */
hsa_function_summary ();
@@ -1316,7 +1318,7 @@ hsa_internal_fn_hasher::equal (const value_type a, const compare_type b)
}
/* in hsa-common.c */
-extern struct hsa_function_representation *hsa_cfun;
+extern class hsa_function_representation *hsa_cfun;
extern hash_map <tree, vec <const char *> *> *hsa_decl_kernel_dependencies;
extern hsa_summary_t *hsa_summaries;
extern hsa_symbol *hsa_num_threads;
diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c
index 332d89d..2d85601 100644
--- a/gcc/hsa-dump.c
+++ b/gcc/hsa-dump.c
@@ -1229,7 +1229,7 @@ dump_hsa_cfun (FILE *f)
FOR_ALL_BB_FN (bb, cfun)
{
- hsa_bb *hbb = (struct hsa_bb *) bb->aux;
+ hsa_bb *hbb = (class hsa_bb *) bb->aux;
dump_hsa_bb (f, hbb);
}
}
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index f52c49c..26e1e24 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -6070,7 +6070,7 @@ gen_function_def_parameters ()
for (parm = DECL_ARGUMENTS (cfun->decl); parm;
parm = DECL_CHAIN (parm))
{
- struct hsa_symbol **slot;
+ class hsa_symbol **slot;
hsa_symbol *arg
= new hsa_symbol (BRIG_TYPE_NONE, hsa_cfun->m_kern_p
@@ -6128,7 +6128,7 @@ gen_function_def_parameters ()
if (!VOID_TYPE_P (TREE_TYPE (TREE_TYPE (cfun->decl))))
{
- struct hsa_symbol **slot;
+ class hsa_symbol **slot;
hsa_cfun->m_output_arg = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_ARG,
BRIG_LINKAGE_FUNCTION);
@@ -6213,8 +6213,9 @@ transformable_switch_to_sbr_p (gswitch *s)
/* Structure hold connection between PHI nodes and immediate
values hold by there nodes. */
-struct phi_definition
+class phi_definition
{
+public:
phi_definition (unsigned phi_i, unsigned label_i, tree imm):
phi_index (phi_i), label_index (label_i), phi_value (imm)
{}
diff --git a/gcc/hsa-regalloc.c b/gcc/hsa-regalloc.c
index d0c1609..597bb66 100644
--- a/gcc/hsa-regalloc.c
+++ b/gcc/hsa-regalloc.c
@@ -256,7 +256,7 @@ dump_hsa_cfun_regalloc (FILE *f)
FOR_ALL_BB_FN (bb, cfun)
{
- hsa_bb *hbb = (struct hsa_bb *) bb->aux;
+ hsa_bb *hbb = (class hsa_bb *) bb->aux;
bitmap_print (dump_file, hbb->m_livein, "m_livein ", "\n");
dump_hsa_bb (f, hbb);
bitmap_print (dump_file, hbb->m_liveout, "m_liveout ", "\n");
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 7b2f6e6..e0c9522 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -5457,6 +5457,8 @@ if_convert (bool after_combine)
static unsigned int
rest_of_handle_if_conversion (void)
{
+ int flags = 0;
+
if (flag_if_conversion)
{
if (dump_file)
@@ -5466,9 +5468,12 @@ rest_of_handle_if_conversion (void)
}
cleanup_cfg (CLEANUP_EXPENSIVE);
if_convert (false);
+ if (num_updated_if_blocks)
+ /* Get rid of any dead CC-related instructions. */
+ flags |= CLEANUP_FORCE_FAST_DCE;
}
- cleanup_cfg (0);
+ cleanup_cfg (flags);
return 0;
}
diff --git a/gcc/input.c b/gcc/input.c
index 1e84d2e..00301ef 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -32,11 +32,13 @@ along with GCC; see the file COPYING3. If not see
/* This is a cache used by get_next_line to store the content of a
file to be searched for file lines. */
-struct fcache
+class fcache
{
+public:
/* These are information used to store a line boundary. */
- struct line_info
+ class line_info
{
+ public:
/* The line number. It starts from 1. */
size_t line_num;
@@ -122,14 +124,14 @@ struct fcache
location_t input_location = UNKNOWN_LOCATION;
-struct line_maps *line_table;
+class line_maps *line_table;
/* A stashed copy of "line_table" for use by selftest::line_table_test.
This needs to be a global so that it can be a GC root, and thus
prevent the stashed copy from being garbage-collected if the GC runs
during a line_table_test. */
-struct line_maps *saved_line_table;
+class line_maps *saved_line_table;
static fcache *fcache_tab;
static const size_t fcache_tab_size = 16;
@@ -978,7 +980,7 @@ dump_line_table_statistics (void)
/* Get location one beyond the final location in ordinary map IDX. */
static location_t
-get_end_location (struct line_maps *set, unsigned int idx)
+get_end_location (class line_maps *set, unsigned int idx)
{
if (idx == LINEMAPS_ORDINARY_USED (set) - 1)
return set->highest_location;
@@ -1691,8 +1693,9 @@ assert_loceq (const char *exp_filename, int exp_linenum, int exp_colnum,
The following struct describes a particular case within our test
matrix. */
-struct line_table_case
+class line_table_case
{
+public:
line_table_case (int default_range_bits, int base_location)
: m_default_range_bits (default_range_bits),
m_base_location (base_location)
@@ -2048,7 +2051,7 @@ test_lexer (const line_table_case &case_)
/* Forward decls. */
-struct lexer_test;
+class lexer_test;
class lexer_test_options;
/* A class for specifying options of a lexer_test.
@@ -2085,8 +2088,9 @@ class cpp_reader_ptr
/* A struct for writing lexer tests. */
-struct lexer_test
+class lexer_test
{
+public:
lexer_test (const line_table_case &case_, const char *content,
lexer_test_options *options);
~lexer_test ();
diff --git a/gcc/input.h b/gcc/input.h
index 3c7cf36..c459bf2 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -23,8 +23,8 @@ along with GCC; see the file COPYING3. If not see
#include "line-map.h"
-extern GTY(()) struct line_maps *line_table;
-extern GTY(()) struct line_maps *saved_line_table;
+extern GTY(()) class line_maps *line_table;
+extern GTY(()) class line_maps *saved_line_table;
/* A value which will never be used to represent a real location. */
#define UNKNOWN_LOCATION ((location_t) 0)
@@ -175,8 +175,9 @@ void diagnostics_file_cache_fini (void);
void diagnostics_file_cache_forcibly_evict_file (const char *file_path);
-struct GTY(()) string_concat
+class GTY(()) string_concat
{
+public:
string_concat (int num, location_t *locs);
int m_num;
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 90f8e56..1067376 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -149,7 +149,7 @@ get_multi_vector_move (tree array_type, convert_optab optab)
static void
expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
tree type, lhs, rhs;
rtx target, mem;
@@ -173,7 +173,7 @@ expand_load_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
static void
expand_store_lanes_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
tree type, lhs, rhs;
rtx target, reg;
@@ -227,7 +227,7 @@ expand_GOMP_SIMT_ENTER_ALLOC (internal_fn, gcall *stmt)
target = gen_reg_rtx (Pmode);
rtx size = expand_normal (gimple_call_arg (stmt, 0));
rtx align = expand_normal (gimple_call_arg (stmt, 1));
- struct expand_operand ops[3];
+ class expand_operand ops[3];
create_output_operand (&ops[0], target, Pmode);
create_input_operand (&ops[1], size, Pmode);
create_input_operand (&ops[2], align, Pmode);
@@ -242,7 +242,7 @@ expand_GOMP_SIMT_EXIT (internal_fn, gcall *stmt)
{
gcc_checking_assert (!gimple_call_lhs (stmt));
rtx arg = expand_normal (gimple_call_arg (stmt, 0));
- struct expand_operand ops[1];
+ class expand_operand ops[1];
create_input_operand (&ops[0], arg, Pmode);
gcc_assert (targetm.have_omp_simt_exit ());
expand_insn (targetm.code_for_omp_simt_exit, 1, ops);
@@ -285,7 +285,7 @@ expand_GOMP_SIMT_LAST_LANE (internal_fn, gcall *stmt)
rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
rtx cond = expand_normal (gimple_call_arg (stmt, 0));
machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
- struct expand_operand ops[2];
+ class expand_operand ops[2];
create_output_operand (&ops[0], target, mode);
create_input_operand (&ops[1], cond, mode);
gcc_assert (targetm.have_omp_simt_last_lane ());
@@ -304,7 +304,7 @@ expand_GOMP_SIMT_ORDERED_PRED (internal_fn, gcall *stmt)
rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
rtx ctr = expand_normal (gimple_call_arg (stmt, 0));
machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
- struct expand_operand ops[2];
+ class expand_operand ops[2];
create_output_operand (&ops[0], target, mode);
create_input_operand (&ops[1], ctr, mode);
gcc_assert (targetm.have_omp_simt_ordered ());
@@ -324,7 +324,7 @@ expand_GOMP_SIMT_VOTE_ANY (internal_fn, gcall *stmt)
rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
rtx cond = expand_normal (gimple_call_arg (stmt, 0));
machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
- struct expand_operand ops[2];
+ class expand_operand ops[2];
create_output_operand (&ops[0], target, mode);
create_input_operand (&ops[1], cond, mode);
gcc_assert (targetm.have_omp_simt_vote_any ());
@@ -345,7 +345,7 @@ expand_GOMP_SIMT_XCHG_BFLY (internal_fn, gcall *stmt)
rtx src = expand_normal (gimple_call_arg (stmt, 0));
rtx idx = expand_normal (gimple_call_arg (stmt, 1));
machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
- struct expand_operand ops[3];
+ class expand_operand ops[3];
create_output_operand (&ops[0], target, mode);
create_input_operand (&ops[1], src, mode);
create_input_operand (&ops[2], idx, SImode);
@@ -366,7 +366,7 @@ expand_GOMP_SIMT_XCHG_IDX (internal_fn, gcall *stmt)
rtx src = expand_normal (gimple_call_arg (stmt, 0));
rtx idx = expand_normal (gimple_call_arg (stmt, 1));
machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
- struct expand_operand ops[3];
+ class expand_operand ops[3];
create_output_operand (&ops[0], target, mode);
create_input_operand (&ops[1], src, mode);
create_input_operand (&ops[2], idx, SImode);
@@ -774,7 +774,7 @@ expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
: usubv4_optab, mode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
rtx_insn *last = get_last_insn ();
res = gen_reg_rtx (mode);
@@ -995,7 +995,7 @@ expand_addsub_overflow (location_t loc, tree_code code, tree lhs,
: subv4_optab, mode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
rtx_insn *last = get_last_insn ();
res = gen_reg_rtx (mode);
@@ -1146,7 +1146,7 @@ expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan,
enum insn_code icode = optab_handler (negv3_optab, mode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
rtx_insn *last = get_last_insn ();
res = gen_reg_rtx (mode);
@@ -1539,7 +1539,7 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1,
}
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
rtx_insn *last = get_last_insn ();
res = gen_reg_rtx (mode);
@@ -2475,7 +2475,7 @@ expand_call_mem_ref (tree type, gcall *stmt, int index)
static void
expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
tree type, lhs, rhs, maskt;
rtx mem, target, mask;
insn_code icode;
@@ -2510,7 +2510,7 @@ expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
static void
expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
tree type, lhs, rhs, maskt;
rtx mem, reg, mask;
insn_code icode;
@@ -2771,7 +2771,7 @@ expand_scatter_store_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
HOST_WIDE_INT scale_int = tree_to_shwi (scale);
rtx rhs_rtx = expand_normal (rhs);
- struct expand_operand ops[6];
+ class expand_operand ops[6];
int i = 0;
create_address_operand (&ops[i++], base_rtx);
create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
@@ -2805,7 +2805,7 @@ expand_gather_load_optab_fn (internal_fn, gcall *stmt, direct_optab optab)
HOST_WIDE_INT scale_int = tree_to_shwi (scale);
int i = 0;
- struct expand_operand ops[6];
+ class expand_operand ops[6];
create_output_operand (&ops[i++], lhs_rtx, TYPE_MODE (TREE_TYPE (lhs)));
create_address_operand (&ops[i++], base_rtx);
create_input_operand (&ops[i++], offset_rtx, TYPE_MODE (TREE_TYPE (offset)));
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index b6e781f..b20a6d0 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -130,7 +130,7 @@ template <typename valtype> class ipcp_value;
/* Describes a particular source for an IPA-CP value. */
template <typename valtype>
-class ipcp_value_source
+struct ipcp_value_source
{
public:
/* Aggregate offset of the source, negative if the source is scalar value of
@@ -209,7 +209,7 @@ public:
contains_variable flag should be disregarded. */
template <typename valtype>
-class ipcp_lattice
+struct ipcp_lattice
{
public:
/* The list of known values and types in this lattice. Note that values are
@@ -236,7 +236,7 @@ public:
/* Lattice of tree values with an offset to describe a part of an
aggregate. */
-class ipcp_agg_lattice : public ipcp_lattice<tree>
+struct ipcp_agg_lattice : public ipcp_lattice<tree>
{
public:
/* Offset that is being described by this lattice. */
@@ -381,8 +381,8 @@ static hash_map<const char *, unsigned> *clone_num_suffixes;
/* Return the param lattices structure corresponding to the Ith formal
parameter of the function described by INFO. */
-static inline struct ipcp_param_lattices *
-ipa_get_parm_lattices (struct ipa_node_params *info, int i)
+static inline class ipcp_param_lattices *
+ipa_get_parm_lattices (class ipa_node_params *info, int i)
{
gcc_assert (i >= 0 && i < ipa_get_param_count (info));
gcc_checking_assert (!info->ipcp_orig_node);
@@ -393,18 +393,18 @@ ipa_get_parm_lattices (struct ipa_node_params *info, int i)
/* Return the lattice corresponding to the scalar value of the Ith formal
parameter of the function described by INFO. */
static inline ipcp_lattice<tree> *
-ipa_get_scalar_lat (struct ipa_node_params *info, int i)
+ipa_get_scalar_lat (class ipa_node_params *info, int i)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
return &plats->itself;
}
/* Return the lattice corresponding to the scalar value of the Ith formal
parameter of the function described by INFO. */
static inline ipcp_lattice<ipa_polymorphic_call_context> *
-ipa_get_poly_ctx_lat (struct ipa_node_params *info, int i)
+ipa_get_poly_ctx_lat (class ipa_node_params *info, int i)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
return &plats->ctxlat;
}
@@ -539,7 +539,7 @@ print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
fprintf (f, "\nLattices:\n");
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
{
- struct ipa_node_params *info;
+ class ipa_node_params *info;
info = IPA_NODE_REF (node);
/* Skip constprop clones since we don't make lattices for them. */
@@ -550,7 +550,7 @@ print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
for (i = 0; i < count; i++)
{
struct ipcp_agg_lattice *aglat;
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
fprintf (f, " param [%d]: ", i);
plats->itself.print (f, dump_sources, dump_benefits);
fprintf (f, " ctxs: ");
@@ -585,7 +585,7 @@ print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
static void
determine_versionability (struct cgraph_node *node,
- struct ipa_node_params *info)
+ class ipa_node_params *info)
{
const char *reason = NULL;
@@ -823,7 +823,7 @@ ignore_edge_p (cgraph_edge *e)
/* Allocate the arrays in TOPO and topologically sort the nodes into order. */
static void
-build_toporder_info (struct ipa_topo_info *topo)
+build_toporder_info (class ipa_topo_info *topo)
{
topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
@@ -837,7 +837,7 @@ build_toporder_info (struct ipa_topo_info *topo)
TOPO. */
static void
-free_toporder_info (struct ipa_topo_info *topo)
+free_toporder_info (class ipa_topo_info *topo)
{
ipa_free_postorder_info ();
free (topo->order);
@@ -847,9 +847,9 @@ free_toporder_info (struct ipa_topo_info *topo)
/* Add NODE to the stack in TOPO, unless it is already there. */
static inline void
-push_node_to_stack (struct ipa_topo_info *topo, struct cgraph_node *node)
+push_node_to_stack (class ipa_topo_info *topo, struct cgraph_node *node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
if (info->node_enqueued)
return;
info->node_enqueued = 1;
@@ -860,7 +860,7 @@ push_node_to_stack (struct ipa_topo_info *topo, struct cgraph_node *node)
is empty. */
static struct cgraph_node *
-pop_node_from_stack (struct ipa_topo_info *topo)
+pop_node_from_stack (class ipa_topo_info *topo)
{
if (topo->stack_top)
{
@@ -902,7 +902,7 @@ ipcp_lattice<valtype>::set_contains_variable ()
not previously set as such. */
static inline bool
-set_agg_lats_to_bottom (struct ipcp_param_lattices *plats)
+set_agg_lats_to_bottom (class ipcp_param_lattices *plats)
{
bool ret = !plats->aggs_bottom;
plats->aggs_bottom = true;
@@ -913,7 +913,7 @@ set_agg_lats_to_bottom (struct ipcp_param_lattices *plats)
return true if they were not previously marked as such. */
static inline bool
-set_agg_lats_contain_variable (struct ipcp_param_lattices *plats)
+set_agg_lats_contain_variable (class ipcp_param_lattices *plats)
{
bool ret = !plats->aggs_contain_variable;
plats->aggs_contain_variable = true;
@@ -1123,7 +1123,7 @@ ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision,
return true is any of them has not been marked as such so far. */
static inline bool
-set_all_contains_variable (struct ipcp_param_lattices *plats)
+set_all_contains_variable (class ipcp_param_lattices *plats)
{
bool ret;
ret = plats->itself.set_contains_variable ();
@@ -1173,7 +1173,7 @@ set_single_call_flag (cgraph_node *node, void *)
static void
initialize_node_lattices (struct cgraph_node *node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
struct cgraph_edge *ie;
bool disable = false, variable = false;
int i;
@@ -1203,7 +1203,7 @@ initialize_node_lattices (struct cgraph_node *node)
for (i = 0; i < ipa_get_param_count (info); i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
plats->m_value_range.init ();
}
@@ -1211,7 +1211,7 @@ initialize_node_lattices (struct cgraph_node *node)
{
for (i = 0; i < ipa_get_param_count (info); i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
if (disable)
{
plats->itself.set_to_bottom ();
@@ -1304,7 +1304,7 @@ ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
passed. */
tree
-ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc,
+ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
tree parm_type)
{
if (jfunc->type == IPA_JF_CONST)
@@ -1422,7 +1422,7 @@ ipcp_verify_propagated_values (void)
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
int i, count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
@@ -1674,7 +1674,7 @@ propagate_scalar_across_jump_function (struct cgraph_edge *cs,
else if (jfunc->type == IPA_JF_PASS_THROUGH
|| jfunc->type == IPA_JF_ANCESTOR)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
ipcp_lattice<tree> *src_lat;
int src_idx;
bool ret;
@@ -1736,7 +1736,7 @@ propagate_context_across_jump_function (cgraph_edge *cs,
if (jfunc->type == IPA_JF_PASS_THROUGH
|| jfunc->type == IPA_JF_ANCESTOR)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
int src_idx;
ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
@@ -1812,7 +1812,7 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
enum availability availability;
cgraph_node *callee = cs->callee->function_symbol (&availability);
- struct ipa_node_params *callee_info = IPA_NODE_REF (callee);
+ class ipa_node_params *callee_info = IPA_NODE_REF (callee);
tree parm_type = ipa_get_type (callee_info, idx);
/* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
@@ -1835,7 +1835,7 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
if (jfunc->type == IPA_JF_PASS_THROUGH
|| jfunc->type == IPA_JF_ANCESTOR)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
tree operand = NULL_TREE;
enum tree_code code;
unsigned src_idx;
@@ -1855,7 +1855,7 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
operand = build_int_cstu (size_type_node, offset);
}
- struct ipcp_param_lattices *src_lats
+ class ipcp_param_lattices *src_lats
= ipa_get_parm_lattices (caller_info, src_idx);
/* Try to propagate bits if src_lattice is bottom, but jfunc is known.
@@ -1909,7 +1909,7 @@ ipa_vr_operation_and_type_effects (value_range_base *dst_vr,
static bool
propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
- struct ipcp_param_lattices *dest_plats,
+ class ipcp_param_lattices *dest_plats,
tree param_type)
{
ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
@@ -1928,10 +1928,10 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
if (TREE_CODE_CLASS (operation) == tcc_unary)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
tree operand_type = ipa_get_type (caller_info, src_idx);
- struct ipcp_param_lattices *src_lats
+ class ipcp_param_lattices *src_lats
= ipa_get_parm_lattices (caller_info, src_idx);
if (src_lats->m_value_range.bottom_p ())
@@ -1974,7 +1974,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
aggs_by_ref to NEW_AGGS_BY_REF. */
static bool
-set_check_aggs_by_ref (struct ipcp_param_lattices *dest_plats,
+set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
bool new_aggs_by_ref)
{
if (dest_plats->aggs)
@@ -2001,7 +2001,7 @@ set_check_aggs_by_ref (struct ipcp_param_lattices *dest_plats,
true. */
static bool
-merge_agg_lats_step (struct ipcp_param_lattices *dest_plats,
+merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
struct ipcp_agg_lattice ***aglat,
bool pre_existing, bool *change)
@@ -2079,8 +2079,8 @@ set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
static bool
merge_aggregate_lattices (struct cgraph_edge *cs,
- struct ipcp_param_lattices *dest_plats,
- struct ipcp_param_lattices *src_plats,
+ class ipcp_param_lattices *dest_plats,
+ class ipcp_param_lattices *src_plats,
int src_idx, HOST_WIDE_INT offset_delta)
{
bool pre_existing = dest_plats->aggs != NULL;
@@ -2134,7 +2134,7 @@ merge_aggregate_lattices (struct cgraph_edge *cs,
rules about propagating values passed by reference. */
static bool
-agg_pass_through_permissible_p (struct ipcp_param_lattices *src_plats,
+agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
struct ipa_jump_func *jfunc)
{
return src_plats->aggs
@@ -2148,7 +2148,7 @@ agg_pass_through_permissible_p (struct ipcp_param_lattices *src_plats,
static bool
propagate_aggs_across_jump_function (struct cgraph_edge *cs,
struct ipa_jump_func *jfunc,
- struct ipcp_param_lattices *dest_plats)
+ class ipcp_param_lattices *dest_plats)
{
bool ret = false;
@@ -2158,9 +2158,9 @@ propagate_aggs_across_jump_function (struct cgraph_edge *cs,
if (jfunc->type == IPA_JF_PASS_THROUGH
&& ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
- struct ipcp_param_lattices *src_plats;
+ class ipcp_param_lattices *src_plats;
src_plats = ipa_get_parm_lattices (caller_info, src_idx);
if (agg_pass_through_permissible_p (src_plats, jfunc))
@@ -2177,9 +2177,9 @@ propagate_aggs_across_jump_function (struct cgraph_edge *cs,
else if (jfunc->type == IPA_JF_ANCESTOR
&& ipa_get_jf_ancestor_agg_preserved (jfunc))
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
- struct ipcp_param_lattices *src_plats;
+ class ipcp_param_lattices *src_plats;
src_plats = ipa_get_parm_lattices (caller_info, src_idx);
if (src_plats->aggs && src_plats->aggs_by_ref)
@@ -2250,10 +2250,10 @@ call_passes_through_thunk_p (cgraph_edge *cs)
static bool
propagate_constants_across_call (struct cgraph_edge *cs)
{
- struct ipa_node_params *callee_info;
+ class ipa_node_params *callee_info;
enum availability availability;
cgraph_node *callee;
- struct ipa_edge_args *args;
+ class ipa_edge_args *args;
bool ret = false;
int i, args_count, parms_count;
@@ -2284,7 +2284,7 @@ propagate_constants_across_call (struct cgraph_edge *cs)
for (; (i < args_count) && (i < parms_count); i++)
{
struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
- struct ipcp_param_lattices *dest_plats;
+ class ipcp_param_lattices *dest_plats;
tree param_type = ipa_get_type (callee_info, i);
dest_plats = ipa_get_parm_lattices (callee_info, i);
@@ -2563,7 +2563,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
for (ie = node->indirect_calls; ie; ie = ie->next_callee)
{
struct cgraph_node *callee;
- struct ipa_fn_summary *isummary;
+ class ipa_fn_summary *isummary;
enum availability avail;
tree target;
bool speculative;
@@ -2607,8 +2607,6 @@ hint_time_bonus (ipa_hints hints)
int result = 0;
if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS);
- if (hints & INLINE_HINT_array_index)
- result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);
return result;
}
@@ -2645,7 +2643,7 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
gcc_assert (size_cost > 0);
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
if (max_count > profile_count::zero ())
{
int factor = RDIV (count_sum.probability_in
@@ -2692,7 +2690,7 @@ good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
vector. Return NULL if there are none. */
static vec<ipa_agg_jf_item, va_gc> *
-context_independent_aggregate_values (struct ipcp_param_lattices *plats)
+context_independent_aggregate_values (class ipcp_param_lattices *plats)
{
vec<ipa_agg_jf_item, va_gc> *res = NULL;
@@ -2721,7 +2719,7 @@ context_independent_aggregate_values (struct ipcp_param_lattices *plats)
it. */
static bool
-gather_context_independent_values (struct ipa_node_params *info,
+gather_context_independent_values (class ipa_node_params *info,
vec<tree> *known_csts,
vec<ipa_polymorphic_call_context>
*known_contexts,
@@ -2746,7 +2744,7 @@ gather_context_independent_values (struct ipa_node_params *info,
for (i = 0; i < count; i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
ipcp_lattice<tree> *lat = &plats->itself;
if (lat->is_single_const ())
@@ -2863,7 +2861,7 @@ perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
static void
estimate_local_effects (struct cgraph_node *node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
int i, count = ipa_get_param_count (info);
vec<tree> known_csts;
vec<ipa_polymorphic_call_context> known_contexts;
@@ -2943,7 +2941,7 @@ estimate_local_effects (struct cgraph_node *node)
for (i = 0; i < count; i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
ipcp_lattice<tree> *lat = &plats->itself;
ipcp_value<tree> *val;
@@ -2977,7 +2975,7 @@ estimate_local_effects (struct cgraph_node *node)
for (i = 0; i < count; i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
if (!plats->virt_call)
continue;
@@ -3012,7 +3010,7 @@ estimate_local_effects (struct cgraph_node *node)
for (i = 0; i < count; i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
struct ipa_agg_jump_function *ajf;
struct ipcp_agg_lattice *aglat;
@@ -3129,12 +3127,12 @@ value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
static void
add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
int i, count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
ipcp_lattice<tree> *lat = &plats->itself;
struct ipcp_agg_lattice *aglat;
@@ -3169,7 +3167,7 @@ add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
connected components. */
static void
-propagate_constants_topo (struct ipa_topo_info *topo)
+propagate_constants_topo (class ipa_topo_info *topo)
{
int i;
@@ -3272,7 +3270,7 @@ value_topo_info<valtype>::propagate_effects ()
summaries interprocedurally. */
static void
-ipcp_propagate_stage (struct ipa_topo_info *topo)
+ipcp_propagate_stage (class ipa_topo_info *topo)
{
struct cgraph_node *node;
@@ -3283,12 +3281,12 @@ ipcp_propagate_stage (struct ipa_topo_info *topo)
FOR_EACH_DEFINED_FUNCTION (node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
determine_versionability (node, info);
if (node->has_gimple_body_p ())
{
- info->lattices = XCNEWVEC (struct ipcp_param_lattices,
+ info->lattices = XCNEWVEC (class ipcp_param_lattices,
ipa_get_param_count (info));
initialize_node_lattices (node);
}
@@ -3352,7 +3350,7 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
if (cs && !agg_contents && !polymorphic)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
int c = ipa_get_controlled_uses (info, param_index);
if (c != IPA_UNDESCRIBED_USE)
{
@@ -3385,8 +3383,9 @@ static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
/* Edge clone summary. */
-struct edge_clone_summary
+class edge_clone_summary
{
+public:
/* Default constructor. */
edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
@@ -3460,7 +3459,7 @@ same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest)
if (node == dest)
return true;
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
}
@@ -3471,7 +3470,7 @@ static bool
cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
cgraph_node *dest, ipcp_value<tree> *dest_val)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
enum availability availability;
cgraph_node *real_dest = cs->callee->function_symbol (&availability);
@@ -3502,7 +3501,7 @@ cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
return true;
struct ipcp_agg_lattice *aglat;
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
src->index);
if (src->offset == -1)
return (plats->itself.is_single_const ()
@@ -3531,7 +3530,7 @@ cgraph_edge_brings_value_p (cgraph_edge *cs,
cgraph_node *dest,
ipcp_value<ipa_polymorphic_call_context> *)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
cgraph_node *real_dest = cs->callee->function_symbol ();
if (!same_node_or_its_all_contexts_clone_p (real_dest, dest)
@@ -3545,7 +3544,7 @@ cgraph_edge_brings_value_p (cgraph_edge *cs,
&& values_equal_for_ipcp_p (src->val->value,
caller_info->known_contexts[src->index]);
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
src->index);
return plats->ctxlat.is_single_const ()
&& values_equal_for_ipcp_p (src->val->value,
@@ -3638,7 +3637,7 @@ gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
Return it or NULL if for some reason it cannot be created. */
static struct ipa_replace_map *
-get_replacement_map (struct ipa_node_params *info, tree value, int parm_num)
+get_replacement_map (class ipa_node_params *info, tree value, int parm_num)
{
struct ipa_replace_map *replace_map;
@@ -3807,7 +3806,7 @@ create_specialized_node (struct cgraph_node *node,
struct ipa_agg_replacement_value *aggvals,
vec<cgraph_edge *> callers)
{
- struct ipa_node_params *new_info, *info = IPA_NODE_REF (node);
+ class ipa_node_params *new_info, *info = IPA_NODE_REF (node);
vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
struct ipa_agg_replacement_value *av;
struct cgraph_node *new_node;
@@ -3941,7 +3940,7 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
vec<tree> known_csts,
vec<cgraph_edge *> callers)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
int i, count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
@@ -4074,7 +4073,7 @@ find_more_contexts_for_caller_subset (cgraph_node *node,
offsets (minus OFFSET) of lattices that contain only a single value. */
static vec<ipa_agg_jf_item>
-copy_plats_to_inter (struct ipcp_param_lattices *plats, HOST_WIDE_INT offset)
+copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset)
{
vec<ipa_agg_jf_item> res = vNULL;
@@ -4096,7 +4095,7 @@ copy_plats_to_inter (struct ipcp_param_lattices *plats, HOST_WIDE_INT offset)
subtracting OFFSET). */
static void
-intersect_with_plats (struct ipcp_param_lattices *plats,
+intersect_with_plats (class ipcp_param_lattices *plats,
vec<ipa_agg_jf_item> *inter,
HOST_WIDE_INT offset)
{
@@ -4216,13 +4215,13 @@ intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
if (jfunc->type == IPA_JF_PASS_THROUGH
&& ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
if (caller_info->ipcp_orig_node)
{
struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
- struct ipcp_param_lattices *orig_plats;
+ class ipcp_param_lattices *orig_plats;
orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
src_idx);
if (agg_pass_through_permissible_p (orig_plats, jfunc))
@@ -4241,7 +4240,7 @@ intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
}
else
{
- struct ipcp_param_lattices *src_plats;
+ class ipcp_param_lattices *src_plats;
src_plats = ipa_get_parm_lattices (caller_info, src_idx);
if (agg_pass_through_permissible_p (src_plats, jfunc))
{
@@ -4263,9 +4262,9 @@ intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
else if (jfunc->type == IPA_JF_ANCESTOR
&& ipa_get_jf_ancestor_agg_preserved (jfunc))
{
- struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
+ class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
- struct ipcp_param_lattices *src_plats;
+ class ipcp_param_lattices *src_plats;
HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
if (caller_info->ipcp_orig_node)
@@ -4340,7 +4339,7 @@ static struct ipa_agg_replacement_value *
find_aggregate_values_for_callers_subset (struct cgraph_node *node,
vec<cgraph_edge *> callers)
{
- struct ipa_node_params *dest_info = IPA_NODE_REF (node);
+ class ipa_node_params *dest_info = IPA_NODE_REF (node);
struct ipa_agg_replacement_value *res;
struct ipa_agg_replacement_value **tail = &res;
struct cgraph_edge *cs;
@@ -4358,7 +4357,7 @@ find_aggregate_values_for_callers_subset (struct cgraph_node *node,
struct cgraph_edge *cs;
vec<ipa_agg_jf_item> inter = vNULL;
struct ipa_agg_jf_item *item;
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
int j;
/* Among other things, the following check should deal with all by_ref
@@ -4411,10 +4410,10 @@ static bool
cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
struct cgraph_node *node)
{
- struct ipa_node_params *dest_info = IPA_NODE_REF (node);
+ class ipa_node_params *dest_info = IPA_NODE_REF (node);
int count = ipa_get_param_count (dest_info);
- struct ipa_node_params *caller_info;
- struct ipa_edge_args *args;
+ class ipa_node_params *caller_info;
+ class ipa_edge_args *args;
int i;
caller_info = IPA_NODE_REF (cs->caller);
@@ -4445,7 +4444,7 @@ static bool
cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
struct cgraph_node *node)
{
- struct ipa_node_params *orig_node_info;
+ class ipa_node_params *orig_node_info;
struct ipa_agg_replacement_value *aggval;
int i, ec, count;
@@ -4465,7 +4464,7 @@ cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
for (i = 0; i < count; i++)
{
static vec<ipa_agg_jf_item> values = vec<ipa_agg_jf_item>();
- struct ipcp_param_lattices *plats;
+ class ipcp_param_lattices *plats;
bool interesting = false;
for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
if (aggval->index == i)
@@ -4721,7 +4720,7 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
static bool
decide_whether_version_node (struct cgraph_node *node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
int i, count = ipa_get_param_count (info);
vec<tree> known_csts;
vec<ipa_polymorphic_call_context> known_contexts;
@@ -4741,7 +4740,7 @@ decide_whether_version_node (struct cgraph_node *node)
for (i = 0; i < count;i++)
{
- struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
+ class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
ipcp_lattice<tree> *lat = &plats->itself;
ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
@@ -4831,7 +4830,7 @@ spread_undeadness (struct cgraph_node *node)
if (ipa_edge_within_scc (cs))
{
struct cgraph_node *callee;
- struct ipa_node_params *info;
+ class ipa_node_params *info;
callee = cs->callee->function_symbol (NULL);
info = IPA_NODE_REF (callee);
@@ -4894,7 +4893,7 @@ identify_dead_nodes (struct cgraph_node *node)
TOPO and make specialized clones if deemed beneficial. */
static void
-ipcp_decision_stage (struct ipa_topo_info *topo)
+ipcp_decision_stage (class ipa_topo_info *topo)
{
int i;
@@ -5068,7 +5067,7 @@ ipcp_store_vr_results (void)
static unsigned int
ipcp_driver (void)
{
- struct ipa_topo_info topo;
+ class ipa_topo_info topo;
if (edge_clone_summaries == NULL)
edge_clone_summaries = new edge_clone_summary_t (symtab);
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 252d920..95e2d95 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2626,8 +2626,9 @@ possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes,
polymorphic calls in the program, so we memoize all the previous
queries and avoid duplicated work. */
-struct polymorphic_call_target_d
+class polymorphic_call_target_d
{
+public:
HOST_WIDE_INT otr_token;
ipa_polymorphic_call_context context;
odr_type type;
@@ -2949,8 +2950,9 @@ struct decl_warn_count
/* Information about type and decl warnings. */
-struct final_warning_record
+class final_warning_record
{
+public:
/* If needed grow type_warnings vector and initialize new decl_warn_count
to have dyn_count set to profile_count::zero (). */
void grow_type_warnings (unsigned newlen);
@@ -2972,7 +2974,7 @@ final_warning_record::grow_type_warnings (unsigned newlen)
}
}
-struct final_warning_record *final_warning_records;
+class final_warning_record *final_warning_records;
/* Return vector containing possible targets of polymorphic call of type
OTR_TYPE calling method OTR_TOKEN within type of OTR_OUTER_TYPE and OFFSET.
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 160261d..fe125ac 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -134,11 +134,6 @@ ipa_dump_hints (FILE *f, ipa_hints hints)
hints &= ~INLINE_HINT_declared_inline;
fprintf (f, " declared_inline");
}
- if (hints & INLINE_HINT_array_index)
- {
- hints &= ~INLINE_HINT_array_index;
- fprintf (f, " array_index");
- }
if (hints & INLINE_HINT_known_hot)
{
hints &= ~INLINE_HINT_known_hot;
@@ -212,7 +207,7 @@ ipa_fn_summary::account_size_time (int size, sreal time,
}
if (!found)
{
- struct size_time_entry new_entry;
+ class size_time_entry new_entry;
new_entry.size = size;
new_entry.time = time;
new_entry.exec_predicate = exec_pred;
@@ -241,7 +236,7 @@ redirect_to_unreachable (struct cgraph_edge *e)
e->make_direct (target);
else
e->redirect_callee (target);
- struct ipa_call_summary *es = ipa_call_summaries->get (e);
+ class ipa_call_summary *es = ipa_call_summaries->get (e);
e->inline_failed = CIF_UNREACHABLE;
e->count = profile_count::zero ();
es->call_stmt_size = 0;
@@ -266,7 +261,7 @@ edge_set_predicate (struct cgraph_edge *e, predicate *predicate)
&& (!e->speculative || e->callee))
e = redirect_to_unreachable (e);
- struct ipa_call_summary *es = ipa_call_summaries->get (e);
+ class ipa_call_summary *es = ipa_call_summaries->get (e);
if (predicate && *predicate != true)
{
if (!es->predicate)
@@ -328,7 +323,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
{
clause_t clause = inline_p ? 0 : 1 << predicate::not_inlined_condition;
clause_t nonspec_clause = 1 << predicate::not_inlined_condition;
- struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
+ class ipa_fn_summary *info = ipa_fn_summaries->get (node);
int i;
struct condition *c;
@@ -428,7 +423,7 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
vec<ipa_agg_jump_function_p> *known_aggs_ptr)
{
struct cgraph_node *callee = e->callee->ultimate_alias_target ();
- struct ipa_fn_summary *info = ipa_fn_summaries->get (callee);
+ class ipa_fn_summary *info = ipa_fn_summaries->get (callee);
vec<tree> known_vals = vNULL;
vec<ipa_agg_jump_function_p> known_aggs = vNULL;
@@ -443,9 +438,9 @@ evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
&& !e->call_stmt_cannot_inline_p
&& ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr))
{
- struct ipa_node_params *caller_parms_info, *callee_pi;
- struct ipa_edge_args *args = IPA_EDGE_REF (e);
- struct ipa_call_summary *es = ipa_call_summaries->get (e);
+ class ipa_node_params *caller_parms_info, *callee_pi;
+ class ipa_edge_args *args = IPA_EDGE_REF (e);
+ class ipa_call_summary *es = ipa_call_summaries->get (e);
int i, count = ipa_get_cs_argument_count (args);
if (e->caller->global.inlined_to)
@@ -549,8 +544,6 @@ ipa_fn_summary::~ipa_fn_summary ()
edge_predicate_pool.remove (loop_iterations);
if (loop_stride)
edge_predicate_pool.remove (loop_stride);
- if (array_index)
- edge_predicate_pool.remove (array_index);
vec_free (conds);
vec_free (size_time_table);
}
@@ -604,7 +597,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
{
vec<size_time_entry, va_gc> *entry = info->size_time_table;
/* Use SRC parm info since it may not be copied yet. */
- struct ipa_node_params *parms_info = IPA_NODE_REF (src);
+ class ipa_node_params *parms_info = IPA_NODE_REF (src);
vec<tree> known_vals = vNULL;
int count = ipa_get_param_count (parms_info);
int i, j;
@@ -668,7 +661,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
for (edge = dst->callees; edge; edge = next)
{
predicate new_predicate;
- struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get_create (edge);
next = edge->next_callee;
if (!edge->inline_failed)
@@ -687,7 +680,7 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
for (edge = dst->indirect_calls; edge; edge = next)
{
predicate new_predicate;
- struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get_create (edge);
next = edge->next_callee;
gcc_checking_assert (edge->inline_failed);
@@ -703,8 +696,6 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
possible_truths);
remap_hint_predicate_after_duplication (&info->loop_stride,
possible_truths);
- remap_hint_predicate_after_duplication (&info->array_index,
- possible_truths);
/* If inliner or someone after inliner will ever start producing
non-trivial clones, we will get trouble with lack of information
@@ -727,12 +718,6 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
info->loop_stride = NULL;
set_hint_predicate (&info->loop_stride, p);
}
- if (info->array_index)
- {
- predicate p = *info->array_index;
- info->array_index = NULL;
- set_hint_predicate (&info->array_index, p);
- }
}
if (!dst->global.inlined_to)
ipa_update_overall_fn_summary (dst);
@@ -744,8 +729,8 @@ ipa_fn_summary_t::duplicate (cgraph_node *src,
void
ipa_call_summary_t::duplicate (struct cgraph_edge *src,
struct cgraph_edge *dst,
- struct ipa_call_summary *srcinfo,
- struct ipa_call_summary *info)
+ class ipa_call_summary *srcinfo,
+ class ipa_call_summary *info)
{
new (info) ipa_call_summary (*srcinfo);
info->predicate = NULL;
@@ -765,12 +750,12 @@ ipa_call_summary_t::duplicate (struct cgraph_edge *src,
static void
dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
- struct ipa_fn_summary *info)
+ class ipa_fn_summary *info)
{
struct cgraph_edge *edge;
for (edge = node->callees; edge; edge = edge->next_callee)
{
- struct ipa_call_summary *es = ipa_call_summaries->get (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get (edge);
struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
int i;
@@ -821,7 +806,7 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
}
for (edge = node->indirect_calls; edge; edge = edge->next_callee)
{
- struct ipa_call_summary *es = ipa_call_summaries->get (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get (edge);
fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
" time: %2i",
indent, "",
@@ -844,7 +829,7 @@ ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
{
if (node->definition)
{
- struct ipa_fn_summary *s = ipa_fn_summaries->get (node);
+ class ipa_fn_summary *s = ipa_fn_summaries->get (node);
if (s != NULL)
{
size_time_entry *e;
@@ -894,11 +879,6 @@ ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
fprintf (f, " loop stride:");
s->loop_stride->dump (f, s->conds);
}
- if (s->array_index)
- {
- fprintf (f, " array index:");
- s->array_index->dump (f, s->conds);
- }
fprintf (f, " calls:\n");
dump_ipa_call_summary (f, 4, node, s);
fprintf (f, "\n");
@@ -1183,7 +1163,7 @@ eliminated_by_inlining_prob (ipa_func_body_info *fbi, gimple *stmt)
static void
set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
- struct ipa_fn_summary *summary,
+ class ipa_fn_summary *summary,
basic_block bb)
{
gimple *last;
@@ -1268,7 +1248,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
static void
set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
- struct ipa_fn_summary *summary,
+ class ipa_fn_summary *summary,
basic_block bb)
{
gimple *lastg;
@@ -1322,8 +1302,8 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
unshare_expr_without_location (max));
p = p1 & p2;
}
- *(struct predicate *) e->aux
- = p.or_with (summary->conds, *(struct predicate *) e->aux);
+ *(class predicate *) e->aux
+ = p.or_with (summary->conds, *(class predicate *) e->aux);
}
}
@@ -1334,7 +1314,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
static void
compute_bb_predicates (struct ipa_func_body_info *fbi,
struct cgraph_node *node,
- struct ipa_fn_summary *summary)
+ class ipa_fn_summary *summary)
{
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
bool done = false;
@@ -1368,7 +1348,7 @@ compute_bb_predicates (struct ipa_func_body_info *fbi,
predicate this_bb_predicate
= *(predicate *) e->src->aux;
if (e->aux)
- this_bb_predicate &= (*(struct predicate *) e->aux);
+ this_bb_predicate &= (*(class predicate *) e->aux);
p = p.or_with (summary->conds, this_bb_predicate);
if (p == true)
break;
@@ -1407,7 +1387,7 @@ compute_bb_predicates (struct ipa_func_body_info *fbi,
static predicate
will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
- struct ipa_fn_summary *summary,
+ class ipa_fn_summary *summary,
tree expr,
vec<predicate> nonconstant_names)
{
@@ -1478,7 +1458,7 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
static predicate
will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
- struct ipa_fn_summary *summary,
+ class ipa_fn_summary *summary,
gimple *stmt,
vec<predicate> nonconstant_names)
{
@@ -1586,7 +1566,7 @@ struct record_modified_bb_info
static basic_block
get_minimal_bb (basic_block init_bb, basic_block use_bb)
{
- struct loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father);
+ class loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father);
if (l && l->header->count < init_bb->count)
return l->header;
return init_bb;
@@ -1797,7 +1777,7 @@ phi_result_unknown_predicate (ipa_func_body_info *fbi,
NONCONSTANT_NAMES, if possible. */
static void
-predicate_for_phi_result (struct ipa_fn_summary *summary, gphi *phi,
+predicate_for_phi_result (class ipa_fn_summary *summary, gphi *phi,
predicate *p,
vec<predicate> nonconstant_names)
{
@@ -1824,27 +1804,6 @@ predicate_for_phi_result (struct ipa_fn_summary *summary, gphi *phi,
nonconstant_names[SSA_NAME_VERSION (gimple_phi_result (phi))] = *p;
}
-/* Return predicate specifying when array index in access OP becomes non-constant. */
-
-static predicate
-array_index_predicate (ipa_fn_summary *info,
- vec< predicate> nonconstant_names, tree op)
-{
- predicate p = false;
- while (handled_component_p (op))
- {
- if (TREE_CODE (op) == ARRAY_REF || TREE_CODE (op) == ARRAY_RANGE_REF)
- {
- if (TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
- p = p.or_with (info->conds,
- nonconstant_names[SSA_NAME_VERSION
- (TREE_OPERAND (op, 1))]);
- }
- op = TREE_OPERAND (op, 0);
- }
- return p;
-}
-
/* For a typical usage of __builtin_expect (a<b, 1), we
may introduce an extra relation stmt:
With the builtin, we have
@@ -1995,13 +1954,12 @@ analyze_function_body (struct cgraph_node *node, bool early)
basic_block bb;
struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
sreal freq;
- struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
+ class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
predicate bb_predicate;
struct ipa_func_body_info fbi;
vec<predicate> nonconstant_names = vNULL;
int nblocks, n;
int *order;
- predicate array_index = true;
gimple *fix_builtin_expect_stmt;
gcc_assert (my_function && my_function->cfg);
@@ -2120,8 +2078,8 @@ analyze_function_body (struct cgraph_node *node, bool early)
fix_builtin_expect_stmt = find_foldable_builtin_expect (bb);
- for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
- gsi_next (&bsi))
+ for (gimple_stmt_iterator bsi = gsi_start_nondebug_bb (bb);
+ !gsi_end_p (bsi); gsi_next_nondebug (&bsi))
{
gimple *stmt = gsi_stmt (bsi);
int this_size = estimate_num_insns (stmt, &eni_size_weights);
@@ -2146,26 +2104,6 @@ analyze_function_body (struct cgraph_node *node, bool early)
this_time);
}
- if (gimple_assign_load_p (stmt) && nonconstant_names.exists ())
- {
- predicate this_array_index;
- this_array_index =
- array_index_predicate (info, nonconstant_names,
- gimple_assign_rhs1 (stmt));
- if (this_array_index != false)
- array_index &= this_array_index;
- }
- if (gimple_store_p (stmt) && nonconstant_names.exists ())
- {
- predicate this_array_index;
- this_array_index =
- array_index_predicate (info, nonconstant_names,
- gimple_get_lhs (stmt));
- if (this_array_index != false)
- array_index &= this_array_index;
- }
-
-
if (is_gimple_call (stmt)
&& !gimple_call_internal_p (stmt))
{
@@ -2236,7 +2174,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
- struct predicate p = bb_predicate & will_be_nonconstant;
+ class predicate p = bb_predicate & will_be_nonconstant;
/* We can ignore statement when we proved it is never going
to happen, but we cannot do that for call statements
@@ -2273,19 +2211,45 @@ analyze_function_body (struct cgraph_node *node, bool early)
if (dump_file)
fprintf (dump_file, " fp_expression set\n");
}
+ }
- gcc_assert (time >= 0);
- gcc_assert (size >= 0);
+ /* Account cost of address calculations in the statements. */
+ for (unsigned int i = 0; i < gimple_num_ops (stmt); i++)
+ {
+ for (tree op = gimple_op (stmt, i);
+ op && handled_component_p (op);
+ op = TREE_OPERAND (op, 0))
+ if ((TREE_CODE (op) == ARRAY_REF
+ || TREE_CODE (op) == ARRAY_RANGE_REF)
+ && TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
+ {
+ predicate p = bb_predicate;
+ if (fbi.info)
+ p = p & will_be_nonconstant_expr_predicate
+ (&fbi, info, TREE_OPERAND (op, 1),
+ nonconstant_names);
+ if (p != false)
+ {
+ time += freq;
+ size += 1;
+ if (dump_file)
+ fprintf (dump_file,
+ "\t\tAccounting address calculation.\n");
+ info->account_size_time (ipa_fn_summary::size_scale,
+ freq,
+ bb_predicate,
+ p);
+ }
+ }
}
+
}
}
- set_hint_predicate (&ipa_fn_summaries->get_create (node)->array_index,
- array_index);
free (order);
if (nonconstant_names.exists () && !early)
{
- struct loop *loop;
+ class loop *loop;
predicate loop_iterations = true;
predicate loop_stride = true;
@@ -2297,7 +2261,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
vec<edge> exits;
edge ex;
unsigned int j;
- struct tree_niter_desc niter_desc;
+ class tree_niter_desc niter_desc;
bb_predicate = *(predicate *) loop->header->aux;
exits = get_loop_exit_edges (loop);
@@ -2413,7 +2377,7 @@ compute_fn_summary (struct cgraph_node *node, bool early)
{
HOST_WIDE_INT self_stack_size;
struct cgraph_edge *e;
- struct ipa_fn_summary *info;
+ class ipa_fn_summary *info;
gcc_assert (!node->global.inlined_to);
@@ -2539,7 +2503,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
{
tree target;
struct cgraph_node *callee;
- struct ipa_fn_summary *isummary;
+ class ipa_fn_summary *isummary;
enum availability avail;
bool speculative;
@@ -2587,7 +2551,7 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
vec<ipa_agg_jump_function_p> known_aggs,
ipa_hints *hints)
{
- struct ipa_call_summary *es = ipa_call_summaries->get (e);
+ class ipa_call_summary *es = ipa_call_summaries->get (e);
int call_size = es->call_stmt_size;
int call_time = es->call_stmt_time;
int cur_size;
@@ -2624,7 +2588,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size,
struct cgraph_edge *e;
for (e = node->callees; e; e = e->next_callee)
{
- struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+ class ipa_call_summary *es = ipa_call_summaries->get_create (e);
/* Do not care about zero sized builtins. */
if (e->inline_failed && !es->call_stmt_size)
@@ -2655,7 +2619,7 @@ estimate_calls_size_and_time (struct cgraph_node *node, int *size,
}
for (e = node->indirect_calls; e; e = e->next_callee)
{
- struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
+ class ipa_call_summary *es = ipa_call_summaries->get_create (e);
if (!es->predicate
|| es->predicate->evaluate (possible_truths))
estimate_edge_size_and_time (e, size,
@@ -2690,7 +2654,7 @@ estimate_node_size_and_time (struct cgraph_node *node,
vec<inline_param_summary>
inline_param_summary)
{
- struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
+ class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
size_time_entry *e;
int size = 0;
sreal time = 0;
@@ -2783,9 +2747,6 @@ estimate_node_size_and_time (struct cgraph_node *node,
if (info->loop_stride
&& !info->loop_stride->evaluate (possible_truths))
hints |= INLINE_HINT_loop_stride;
- if (info->array_index
- && !info->array_index->evaluate (possible_truths))
- hints |= INLINE_HINT_array_index;
if (info->scc_no)
hints |= INLINE_HINT_in_scc;
if (DECL_DECLARED_INLINE_P (node->decl))
@@ -2881,9 +2842,9 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
if (ipa_node_params_sum)
{
int i;
- struct ipa_edge_args *args = IPA_EDGE_REF (edge);
- struct ipa_call_summary *es = ipa_call_summaries->get (edge);
- struct ipa_call_summary *inlined_es
+ class ipa_edge_args *args = IPA_EDGE_REF (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get (edge);
+ class ipa_call_summary *inlined_es
= ipa_call_summaries->get (inlined_edge);
if (es->param.length () == 0)
@@ -2924,8 +2885,8 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge,
static void
remap_edge_summaries (struct cgraph_edge *inlined_edge,
struct cgraph_node *node,
- struct ipa_fn_summary *info,
- struct ipa_fn_summary *callee_info,
+ class ipa_fn_summary *info,
+ class ipa_fn_summary *callee_info,
vec<int> operand_map,
vec<int> offset_map,
clause_t possible_truths,
@@ -2934,7 +2895,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
struct cgraph_edge *e, *next;
for (e = node->callees; e; e = next)
{
- struct ipa_call_summary *es = ipa_call_summaries->get (e);
+ class ipa_call_summary *es = ipa_call_summaries->get (e);
predicate p;
next = e->next_callee;
@@ -2960,7 +2921,7 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
}
for (e = node->indirect_calls; e; e = next)
{
- struct ipa_call_summary *es = ipa_call_summaries->get (e);
+ class ipa_call_summary *es = ipa_call_summaries->get (e);
predicate p;
next = e->next_callee;
@@ -2980,8 +2941,8 @@ remap_edge_summaries (struct cgraph_edge *inlined_edge,
/* Same as remap_predicate, but set result into hint *HINT. */
static void
-remap_hint_predicate (struct ipa_fn_summary *info,
- struct ipa_fn_summary *callee_info,
+remap_hint_predicate (class ipa_fn_summary *info,
+ class ipa_fn_summary *callee_info,
predicate **hint,
vec<int> operand_map,
vec<int> offset_map,
@@ -3013,7 +2974,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee);
struct cgraph_node *to = (edge->caller->global.inlined_to
? edge->caller->global.inlined_to : edge->caller);
- struct ipa_fn_summary *info = ipa_fn_summaries->get (to);
+ class ipa_fn_summary *info = ipa_fn_summaries->get (to);
clause_t clause = 0; /* not_inline is known to be false. */
size_time_entry *e;
vec<int> operand_map = vNULL;
@@ -3021,7 +2982,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
int i;
predicate toplev_predicate;
predicate true_p = true;
- struct ipa_call_summary *es = ipa_call_summaries->get (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get (edge);
if (es->predicate)
toplev_predicate = *es->predicate;
@@ -3034,7 +2995,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL, NULL);
if (ipa_node_params_sum && callee_info->conds)
{
- struct ipa_edge_args *args = IPA_EDGE_REF (edge);
+ class ipa_edge_args *args = IPA_EDGE_REF (edge);
int count = ipa_get_cs_argument_count (args);
int i;
@@ -3106,9 +3067,6 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
remap_hint_predicate (info, callee_info,
&callee_info->loop_stride,
operand_map, offset_map, clause, &toplev_predicate);
- remap_hint_predicate (info, callee_info,
- &callee_info->array_index,
- operand_map, offset_map, clause, &toplev_predicate);
ipa_call_summary *s = ipa_call_summaries->get (edge);
inline_update_callee_summaries (edge->callee, s->loop_depth);
@@ -3127,7 +3085,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
void
ipa_update_overall_fn_summary (struct cgraph_node *node)
{
- struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
+ class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
size_time_entry *e;
int i;
@@ -3223,10 +3181,10 @@ ipa_fn_summary_generate (void)
/* Write inline summary for edge E to OB. */
static void
-read_ipa_call_summary (struct lto_input_block *ib, struct cgraph_edge *e,
+read_ipa_call_summary (class lto_input_block *ib, struct cgraph_edge *e,
bool prevails)
{
- struct ipa_call_summary *es = prevails
+ class ipa_call_summary *es = prevails
? ipa_call_summaries->get_create (e) : NULL;
predicate p;
int length, i;
@@ -3277,7 +3235,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
const int cfg_offset = sizeof (struct lto_function_header);
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
- struct data_in *data_in;
+ class data_in *data_in;
unsigned int i, count2, j;
unsigned int f_count;
@@ -3292,7 +3250,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
{
unsigned int index;
struct cgraph_node *node;
- struct ipa_fn_summary *info;
+ class ipa_fn_summary *info;
lto_symtab_encoder_t encoder;
struct bitpack_d bp;
struct cgraph_edge *e;
@@ -3349,7 +3307,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
gcc_assert (!info || !info->size_time_table);
for (j = 0; j < count2; j++)
{
- struct size_time_entry e;
+ class size_time_entry e;
e.size = streamer_read_uhwi (&ib);
e.time = sreal::stream_in (&ib);
@@ -3366,9 +3324,6 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
p.stream_in (&ib);
if (info)
set_hint_predicate (&info->loop_stride, p);
- p.stream_in (&ib);
- if (info)
- set_hint_predicate (&info->array_index, p);
for (e = node->callees; e; e = e->next_callee)
read_ipa_call_summary (&ib, e, info != NULL);
for (e = node->indirect_calls; e; e = e->next_callee)
@@ -3423,7 +3378,7 @@ ipa_fn_summary_read (void)
static void
write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
{
- struct ipa_call_summary *es = ipa_call_summaries->get (e);
+ class ipa_call_summary *es = ipa_call_summaries->get (e);
int i;
streamer_write_uhwi (ob, es->call_stmt_size);
@@ -3471,7 +3426,7 @@ ipa_fn_summary_write (void)
cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
if (cnode && cnode->definition && !cnode->alias)
{
- struct ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
+ class ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
struct bitpack_d bp;
struct cgraph_edge *edge;
int i;
@@ -3517,10 +3472,6 @@ ipa_fn_summary_write (void)
info->loop_stride->stream_out (ob);
else
streamer_write_uhwi (ob, 0);
- if (info->array_index)
- info->array_index->stream_out (ob);
- else
- streamer_write_uhwi (ob, 0);
for (edge = cnode->callees; edge; edge = edge->next_callee)
write_ipa_call_summary (ob, edge);
for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
diff --git a/gcc/ipa-fnsummary.h b/gcc/ipa-fnsummary.h
index 0f08e84..173d3f2 100644
--- a/gcc/ipa-fnsummary.h
+++ b/gcc/ipa-fnsummary.h
@@ -48,11 +48,8 @@ enum ipa_hints_vals {
if functions are in different modules, inlining may not be so important.
Set by simple_edge_hints in ipa-inline-analysis.c. */
INLINE_HINT_cross_module = 64,
- /* If array indexes of loads/stores become known there may be room for
- further optimization. */
- INLINE_HINT_array_index = 128,
/* We know that the callee is hot by profile. */
- INLINE_HINT_known_hot = 256
+ INLINE_HINT_known_hot = 128
};
typedef int ipa_hints;
@@ -72,8 +69,9 @@ struct agg_position_info
/* Representation of function body size and time depending on the call
context. We keep simple array of record, every containing of predicate
and time/size to account. */
-struct GTY(()) size_time_entry
+class GTY(()) size_time_entry
{
+public:
/* Predicate for code to be executed. */
predicate exec_predicate;
/* Predicate for value to be constant and optimized out in a specialized copy.
@@ -85,8 +83,9 @@ struct GTY(()) size_time_entry
};
/* Function inlining information. */
-struct GTY(()) ipa_fn_summary
+class GTY(()) ipa_fn_summary
{
+public:
/* Keep all field empty so summary dumping works during its computation.
This is useful for debugging. */
ipa_fn_summary ()
@@ -95,7 +94,7 @@ struct GTY(()) ipa_fn_summary
fp_expressions (false), estimated_stack_size (false),
stack_frame_offset (false), time (0), size (0), conds (NULL),
size_time_table (NULL), loop_iterations (NULL), loop_stride (NULL),
- array_index (NULL), growth (0), scc_no (0)
+ growth (0), scc_no (0)
{
}
@@ -109,7 +108,7 @@ struct GTY(()) ipa_fn_summary
stack_frame_offset (s.stack_frame_offset), time (s.time), size (s.size),
conds (s.conds), size_time_table (s.size_time_table),
loop_iterations (s.loop_iterations), loop_stride (s.loop_stride),
- array_index (s.array_index), growth (s.growth), scc_no (s.scc_no)
+ growth (s.growth), scc_no (s.scc_no)
{}
/* Default constructor. */
@@ -155,8 +154,6 @@ struct GTY(()) ipa_fn_summary
/* Predicate on when some loop in the function becomes to have known
stride. */
predicate * GTY((skip)) loop_stride;
- /* Predicate on when some array indexes become constants. */
- predicate * GTY((skip)) array_index;
/* Estimated growth for inlining all copies of the function before start
of small functions inlining.
This value will get out of date as the callers are duplicated, but
@@ -182,7 +179,7 @@ public:
static ipa_fn_summary_t *create_ggc (symbol_table *symtab)
{
- struct ipa_fn_summary_t *summary = new (ggc_alloc <ipa_fn_summary_t> ())
+ class ipa_fn_summary_t *summary = new (ggc_alloc <ipa_fn_summary_t> ())
ipa_fn_summary_t (symtab);
summary->disable_insertion_hook ();
return summary;
@@ -205,8 +202,9 @@ extern GTY(()) fast_function_summary <ipa_fn_summary *, va_gc>
*ipa_fn_summaries;
/* Information kept about callgraph edges. */
-struct ipa_call_summary
+class ipa_call_summary
{
+public:
/* Keep all field empty so summary dumping works during its computation.
This is useful for debugging. */
ipa_call_summary ()
diff --git a/gcc/ipa-hsa.c b/gcc/ipa-hsa.c
index b48f94b..8af1d73 100644
--- a/gcc/ipa-hsa.c
+++ b/gcc/ipa-hsa.c
@@ -221,7 +221,7 @@ ipa_hsa_read_section (struct lto_file_decl_data *file_data, const char *data,
const int cfg_offset = sizeof (struct lto_function_header);
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
- struct data_in *data_in;
+ class data_in *data_in;
unsigned int i;
unsigned int count;
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 0713e12..4060c0e 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -614,8 +614,8 @@ func_checker::compare_loops (basic_block bb1, basic_block bb2)
if ((bb1->loop_father == NULL) != (bb2->loop_father == NULL))
return return_false ();
- struct loop *l1 = bb1->loop_father;
- struct loop *l2 = bb2->loop_father;
+ class loop *l1 = bb1->loop_father;
+ class loop *l2 = bb2->loop_father;
if (l1 == NULL)
return true;
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 7c486ed..2174fb7 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -482,7 +482,7 @@ sem_function::param_used_p (unsigned int i)
if (ipa_node_params_sum == NULL)
return true;
- struct ipa_node_params *parms_info = IPA_NODE_REF (get_node ());
+ class ipa_node_params *parms_info = IPA_NODE_REF (get_node ());
if (vec_safe_length (parms_info->descriptors) <= i)
return true;
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 6c77f32..a66af27 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -128,7 +128,7 @@ do_estimate_edge_time (struct cgraph_edge *edge)
vec<tree> known_vals;
vec<ipa_polymorphic_call_context> known_contexts;
vec<ipa_agg_jump_function_p> known_aggs;
- struct ipa_call_summary *es = ipa_call_summaries->get (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get (edge);
int min_size;
callee = edge->callee->ultimate_alias_target ();
@@ -264,7 +264,7 @@ int
estimate_size_after_inlining (struct cgraph_node *node,
struct cgraph_edge *edge)
{
- struct ipa_call_summary *es = ipa_call_summaries->get (edge);
+ class ipa_call_summary *es = ipa_call_summaries->get (edge);
ipa_fn_summary *s = ipa_fn_summaries->get (node);
if (!es->predicate || *es->predicate != false)
{
@@ -321,7 +321,7 @@ int
estimate_growth (struct cgraph_node *node)
{
struct growth_data d = { node, false, false, 0 };
- struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
+ class ipa_fn_summary *info = ipa_fn_summaries->get (node);
node->call_for_symbol_and_aliases (do_estimate_growth_1, &d, true);
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 3475258..5862d00 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -807,7 +807,6 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
|| (!(hints & (INLINE_HINT_indirect_call
| INLINE_HINT_known_hot
| INLINE_HINT_loop_iterations
- | INLINE_HINT_array_index
| INLINE_HINT_loop_stride))
&& !(big_speedup = big_speedup_p (e)))))
{
@@ -833,7 +832,6 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
&& !(hints & INLINE_HINT_known_hot)
&& growth >= ((hints & (INLINE_HINT_indirect_call
| INLINE_HINT_loop_iterations
- | INLINE_HINT_array_index
| INLINE_HINT_loop_stride))
? MAX (MAX_INLINE_INSNS_AUTO,
MAX_INLINE_INSNS_SINGLE)
@@ -1037,7 +1035,7 @@ edge_badness (struct cgraph_edge *edge, bool dump)
int growth;
sreal edge_time, unspec_edge_time;
struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
- struct ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
+ class ipa_fn_summary *callee_info = ipa_fn_summaries->get (callee);
ipa_hints hints;
cgraph_node *caller = (edge->caller->global.inlined_to
? edge->caller->global.inlined_to
@@ -1227,7 +1225,6 @@ edge_badness (struct cgraph_edge *edge, bool dump)
badness = badness.shift (badness > 0 ? 4 : -4);
if ((hints & (INLINE_HINT_indirect_call
| INLINE_HINT_loop_iterations
- | INLINE_HINT_array_index
| INLINE_HINT_loop_stride))
|| callee_info->growth <= 0)
badness = badness.shift (badness > 0 ? -2 : 2);
@@ -1507,7 +1504,7 @@ recursive_inlining (struct cgraph_edge *edge,
struct cgraph_node *cnode, *dest = curr->callee;
if (!can_inline_edge_p (curr, true)
- || can_inline_edge_by_limits_p (curr, true))
+ || !can_inline_edge_by_limits_p (curr, true))
continue;
/* MASTER_CLONE is produced in the case we already started modified
@@ -1799,7 +1796,7 @@ inline_small_functions (void)
&& (node->has_gimple_body_p () || node->thunk.thunk_p)
&& opt_for_fn (node->decl, optimize))
{
- struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
+ class ipa_fn_summary *info = ipa_fn_summaries->get (node);
struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->aux;
/* Do not account external functions, they will be optimized out
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index f6eb677..18c8e1e 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -23,8 +23,9 @@ along with GCC; see the file COPYING3. If not see
/* Data we cache about callgraph edges during inlining to avoid expensive
re-computations during the greedy algorithm. */
-struct edge_growth_cache_entry
+class edge_growth_cache_entry
{
+public:
sreal time, nonspec_time;
int size;
ipa_hints hints;
diff --git a/gcc/ipa-polymorphic-call.c b/gcc/ipa-polymorphic-call.c
index 75d8ebc..705af03 100644
--- a/gcc/ipa-polymorphic-call.c
+++ b/gcc/ipa-polymorphic-call.c
@@ -688,8 +688,8 @@ ipa_polymorphic_call_context::stream_out (struct output_block *ob) const
/* Stream in the context from IB and DATA_IN. */
void
-ipa_polymorphic_call_context::stream_in (struct lto_input_block *ib,
- struct data_in *data_in)
+ipa_polymorphic_call_context::stream_in (class lto_input_block *ib,
+ class data_in *data_in)
{
struct bitpack_d bp = streamer_read_bitpack (ib);
diff --git a/gcc/ipa-predicate.c b/gcc/ipa-predicate.c
index 3b7c4df..49622e9 100644
--- a/gcc/ipa-predicate.c
+++ b/gcc/ipa-predicate.c
@@ -398,8 +398,8 @@ predicate::remap_after_duplication (clause_t possible_truths)
for other purposes). */
predicate
-predicate::remap_after_inlining (struct ipa_fn_summary *info,
- struct ipa_fn_summary *callee_info,
+predicate::remap_after_inlining (class ipa_fn_summary *info,
+ class ipa_fn_summary *callee_info,
vec<int> operand_map,
vec<int> offset_map,
clause_t possible_truths,
@@ -483,7 +483,7 @@ predicate::remap_after_inlining (struct ipa_fn_summary *info,
/* Read predicate from IB. */
void
-predicate::stream_in (struct lto_input_block *ib)
+predicate::stream_in (class lto_input_block *ib)
{
clause_t clause;
int k = 0;
@@ -522,7 +522,7 @@ predicate::stream_out (struct output_block *ob)
It can be NULL, which means this not a load from an aggregate. */
predicate
-add_condition (struct ipa_fn_summary *summary, int operand_num,
+add_condition (class ipa_fn_summary *summary, int operand_num,
HOST_WIDE_INT size, struct agg_position_info *aggpos,
enum tree_code code, tree val)
{
diff --git a/gcc/ipa-predicate.h b/gcc/ipa-predicate.h
index e97754c..c2adba3 100644
--- a/gcc/ipa-predicate.h
+++ b/gcc/ipa-predicate.h
@@ -205,11 +205,11 @@ public:
predicate remap_after_duplication (clause_t);
/* Return predicate equal to THIS after inlining. */
- predicate remap_after_inlining (struct ipa_fn_summary *,
- struct ipa_fn_summary *,
+ predicate remap_after_inlining (class ipa_fn_summary *,
+ class ipa_fn_summary *,
vec<int>, vec<int>, clause_t, const predicate &);
- void stream_in (struct lto_input_block *);
+ void stream_in (class lto_input_block *);
void stream_out (struct output_block *);
private:
@@ -227,6 +227,6 @@ private:
};
void dump_condition (FILE *f, conditions conditions, int cond);
-predicate add_condition (struct ipa_fn_summary *summary, int operand_num,
+predicate add_condition (class ipa_fn_summary *summary, int operand_num,
HOST_WIDE_INT size, struct agg_position_info *aggpos,
enum tree_code code, tree val);
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index c80ea7a..1fb939b 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -258,7 +258,7 @@ ipa_profile_read_summary (void)
{
const char *data;
size_t len;
- struct lto_input_block *ib
+ class lto_input_block *ib
= lto_create_simple_input_block (file_data,
LTO_section_ipa_profile,
&data, &len);
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index a53a6ec..344b78e 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -203,7 +203,7 @@ ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
to INFO. */
int
-ipa_get_param_decl_index (struct ipa_node_params *info, tree ptree)
+ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
{
return ipa_get_param_decl_index_1 (info->descriptors, ptree);
}
@@ -253,7 +253,7 @@ count_formal_params (tree fndecl)
using ipa_initialize_node_params. */
void
-ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
+ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
{
fprintf (file, "param #%i", i);
if ((*info->descriptors)[i].decl_or_type)
@@ -269,7 +269,7 @@ ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
static bool
ipa_alloc_node_params (struct cgraph_node *node, int param_count)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
if (!info->descriptors && param_count)
{
@@ -287,7 +287,7 @@ ipa_alloc_node_params (struct cgraph_node *node, int param_count)
void
ipa_initialize_node_params (struct cgraph_node *node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
if (!info->descriptors
&& ipa_alloc_node_params (node, count_formal_params (node->decl)))
@@ -375,7 +375,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
}
}
- struct ipa_polymorphic_call_context *ctx
+ class ipa_polymorphic_call_context *ctx
= ipa_get_ith_polymorhic_call_context (IPA_EDGE_REF (cs), i);
if (ctx && !ctx->useless_p ())
{
@@ -432,7 +432,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
for (cs = node->indirect_calls; cs; cs = cs->next_callee)
{
- struct cgraph_indirect_call_info *ii;
+ class cgraph_indirect_call_info *ii;
if (!ipa_edge_args_info_available_for_edge_p (cs))
continue;
@@ -1190,7 +1190,7 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
static void
compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
- struct ipa_node_params *info,
+ class ipa_node_params *info,
struct ipa_jump_func *jfunc,
gcall *call, gimple *stmt, tree name,
tree param_type)
@@ -1346,7 +1346,7 @@ get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
static void
compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
- struct ipa_node_params *info,
+ class ipa_node_params *info,
struct ipa_jump_func *jfunc,
gcall *call, gphi *phi)
{
@@ -1678,7 +1678,8 @@ determine_known_aggregate_parts (gcall *call, tree arg,
if (gimple_code (stmt) == GIMPLE_PHI)
{
- dom_vuse = get_continuation_for_phi (stmt, &r, *aa_walk_budget_p,
+ dom_vuse = get_continuation_for_phi (stmt, &r, true,
+ *aa_walk_budget_p,
&visited, false, NULL, NULL);
continue;
}
@@ -1854,8 +1855,8 @@ static void
ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
struct cgraph_edge *cs)
{
- struct ipa_node_params *info = IPA_NODE_REF (cs->caller);
- struct ipa_edge_args *args = IPA_EDGE_REF (cs);
+ class ipa_node_params *info = IPA_NODE_REF (cs->caller);
+ class ipa_edge_args *args = IPA_EDGE_REF (cs);
gcall *call = cs->call_stmt;
int n, arg_num = gimple_call_num_args (call);
bool useful_context = false;
@@ -1879,7 +1880,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
{
tree instance;
- struct ipa_polymorphic_call_context context (cs->caller->decl,
+ class ipa_polymorphic_call_context context (cs->caller->decl,
arg, cs->call_stmt,
&instance);
context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
@@ -2196,7 +2197,7 @@ static void
ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
tree target)
{
- struct ipa_node_params *info = fbi->info;
+ class ipa_node_params *info = fbi->info;
HOST_WIDE_INT offset;
bool by_ref;
@@ -2347,7 +2348,7 @@ ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
if (TREE_CODE (obj) != SSA_NAME)
return;
- struct ipa_node_params *info = fbi->info;
+ class ipa_node_params *info = fbi->info;
if (SSA_NAME_IS_DEFAULT_DEF (obj))
{
struct ipa_jump_func jfunc;
@@ -2379,7 +2380,7 @@ ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
}
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
- struct cgraph_indirect_call_info *ii = cs->indirect_info;
+ class cgraph_indirect_call_info *ii = cs->indirect_info;
ii->offset = anc_offset;
ii->otr_token = tree_to_uhwi (OBJ_TYPE_REF_TOKEN (target));
ii->otr_type = obj_type_ref_class (target);
@@ -2451,7 +2452,7 @@ ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
static bool
visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
{
- struct ipa_node_params *info = (struct ipa_node_params *) data;
+ class ipa_node_params *info = (class ipa_node_params *) data;
op = get_base_address (op);
if (op
@@ -2499,7 +2500,7 @@ ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
static void
ipa_analyze_controlled_uses (struct cgraph_node *node)
{
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
for (int i = 0; i < ipa_get_param_count (info); i++)
{
@@ -2591,7 +2592,7 @@ void
ipa_analyze_node (struct cgraph_node *node)
{
struct ipa_func_body_info fbi;
- struct ipa_node_params *info;
+ class ipa_node_params *info;
ipa_check_create_node_params ();
ipa_check_create_edge_args ();
@@ -2651,22 +2652,22 @@ static void
update_jump_functions_after_inlining (struct cgraph_edge *cs,
struct cgraph_edge *e)
{
- struct ipa_edge_args *top = IPA_EDGE_REF (cs);
- struct ipa_edge_args *args = IPA_EDGE_REF (e);
+ class ipa_edge_args *top = IPA_EDGE_REF (cs);
+ class ipa_edge_args *args = IPA_EDGE_REF (e);
int count = ipa_get_cs_argument_count (args);
int i;
for (i = 0; i < count; i++)
{
struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
- struct ipa_polymorphic_call_context *dst_ctx
+ class ipa_polymorphic_call_context *dst_ctx
= ipa_get_ith_polymorhic_call_context (args, i);
if (dst->type == IPA_JF_ANCESTOR)
{
struct ipa_jump_func *src;
int dst_fid = dst->value.ancestor.formal_id;
- struct ipa_polymorphic_call_context *src_ctx
+ class ipa_polymorphic_call_context *src_ctx
= ipa_get_ith_polymorhic_call_context (top, dst_fid);
/* Variable number of arguments can cause havoc if we try to access
@@ -2682,7 +2683,7 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
if (src_ctx && !src_ctx->useless_p ())
{
- struct ipa_polymorphic_call_context ctx = *src_ctx;
+ class ipa_polymorphic_call_context ctx = *src_ctx;
/* TODO: Make type preserved safe WRT contexts. */
if (!ipa_get_jf_ancestor_type_preserved (dst))
@@ -2752,12 +2753,12 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
int dst_fid = dst->value.pass_through.formal_id;
src = ipa_get_ith_jump_func (top, dst_fid);
bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
- struct ipa_polymorphic_call_context *src_ctx
+ class ipa_polymorphic_call_context *src_ctx
= ipa_get_ith_polymorhic_call_context (top, dst_fid);
if (src_ctx && !src_ctx->useless_p ())
{
- struct ipa_polymorphic_call_context ctx = *src_ctx;
+ class ipa_polymorphic_call_context ctx = *src_ctx;
/* TODO: Make type preserved safe WRT contexts. */
if (!ipa_get_jf_pass_through_type_preserved (dst))
@@ -3230,7 +3231,7 @@ try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
static struct cgraph_edge *
try_make_edge_direct_simple_call (struct cgraph_edge *ie,
struct ipa_jump_func *jfunc, tree target_type,
- struct ipa_node_params *new_root_info)
+ class ipa_node_params *new_root_info)
{
struct cgraph_edge *cs;
tree target;
@@ -3301,7 +3302,7 @@ ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
static struct cgraph_edge *
try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
struct ipa_jump_func *jfunc,
- struct ipa_polymorphic_call_context ctx)
+ class ipa_polymorphic_call_context ctx)
{
tree target = NULL;
bool speculative = false;
@@ -3411,9 +3412,9 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
struct cgraph_node *node,
vec<cgraph_edge *> *new_edges)
{
- struct ipa_edge_args *top;
+ class ipa_edge_args *top;
struct cgraph_edge *ie, *next_ie, *new_direct_edge;
- struct ipa_node_params *new_root_info, *inlined_node_info;
+ class ipa_node_params *new_root_info, *inlined_node_info;
bool res = false;
ipa_check_create_edge_args ();
@@ -3425,7 +3426,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
for (ie = node->indirect_calls; ie; ie = next_ie)
{
- struct cgraph_indirect_call_info *ici = ie->indirect_info;
+ class cgraph_indirect_call_info *ici = ie->indirect_info;
struct ipa_jump_func *jfunc;
int param_index;
cgraph_node *spec_target = NULL;
@@ -3582,11 +3583,11 @@ combine_controlled_uses_counters (int c, int d)
static void
propagate_controlled_uses (struct cgraph_edge *cs)
{
- struct ipa_edge_args *args = IPA_EDGE_REF (cs);
+ class ipa_edge_args *args = IPA_EDGE_REF (cs);
struct cgraph_node *new_root = cs->caller->global.inlined_to
? cs->caller->global.inlined_to : cs->caller;
- struct ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
- struct ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
+ class ipa_node_params *new_root_info = IPA_NODE_REF (new_root);
+ class ipa_node_params *old_root_info = IPA_NODE_REF (cs->callee);
int count, i;
count = MIN (ipa_get_cs_argument_count (args),
@@ -3880,7 +3881,7 @@ ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
{
struct cgraph_node *inline_root = dst->caller->global.inlined_to
? dst->caller->global.inlined_to : dst->caller;
- struct ipa_node_params *root_info = IPA_NODE_REF (inline_root);
+ class ipa_node_params *root_info = IPA_NODE_REF (inline_root);
int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
int c = ipa_get_controlled_uses (root_info, idx);
@@ -4024,7 +4025,7 @@ void
ipa_print_node_params (FILE *f, struct cgraph_node *node)
{
int i, count;
- struct ipa_node_params *info;
+ class ipa_node_params *info;
if (!node->definition)
return;
@@ -4172,10 +4173,10 @@ ipa_write_jump_function (struct output_block *ob,
/* Read in jump function JUMP_FUNC from IB. */
static void
-ipa_read_jump_function (struct lto_input_block *ib,
+ipa_read_jump_function (class lto_input_block *ib,
struct ipa_jump_func *jump_func,
struct cgraph_edge *cs,
- struct data_in *data_in,
+ class data_in *data_in,
bool prevails)
{
enum jump_func_type jftype;
@@ -4284,7 +4285,7 @@ static void
ipa_write_indirect_edge_info (struct output_block *ob,
struct cgraph_edge *cs)
{
- struct cgraph_indirect_call_info *ii = cs->indirect_info;
+ class cgraph_indirect_call_info *ii = cs->indirect_info;
struct bitpack_d bp;
streamer_write_hwi (ob, ii->param_index);
@@ -4313,11 +4314,11 @@ ipa_write_indirect_edge_info (struct output_block *ob,
relevant to indirect inlining from IB. */
static void
-ipa_read_indirect_edge_info (struct lto_input_block *ib,
- struct data_in *data_in,
+ipa_read_indirect_edge_info (class lto_input_block *ib,
+ class data_in *data_in,
struct cgraph_edge *cs)
{
- struct cgraph_indirect_call_info *ii = cs->indirect_info;
+ class cgraph_indirect_call_info *ii = cs->indirect_info;
struct bitpack_d bp;
ii->param_index = (int) streamer_read_hwi (ib);
@@ -4347,7 +4348,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
{
int node_ref;
lto_symtab_encoder_t encoder;
- struct ipa_node_params *info = IPA_NODE_REF (node);
+ class ipa_node_params *info = IPA_NODE_REF (node);
int j;
struct cgraph_edge *e;
struct bitpack_d bp;
@@ -4374,7 +4375,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
}
for (e = node->callees; e; e = e->next_callee)
{
- struct ipa_edge_args *args = IPA_EDGE_REF (e);
+ class ipa_edge_args *args = IPA_EDGE_REF (e);
streamer_write_uhwi (ob,
ipa_get_cs_argument_count (args) * 2
@@ -4388,7 +4389,7 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
}
for (e = node->indirect_calls; e; e = e->next_callee)
{
- struct ipa_edge_args *args = IPA_EDGE_REF (e);
+ class ipa_edge_args *args = IPA_EDGE_REF (e);
streamer_write_uhwi (ob,
ipa_get_cs_argument_count (args) * 2
@@ -4406,8 +4407,8 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
/* Stream in edge E from IB. */
static void
-ipa_read_edge_info (struct lto_input_block *ib,
- struct data_in *data_in,
+ipa_read_edge_info (class lto_input_block *ib,
+ class data_in *data_in,
struct cgraph_edge *e, bool prevails)
{
int count = streamer_read_uhwi (ib);
@@ -4418,7 +4419,7 @@ ipa_read_edge_info (struct lto_input_block *ib,
return;
if (prevails && e->possibly_call_in_translation_unit_p ())
{
- struct ipa_edge_args *args = IPA_EDGE_REF (e);
+ class ipa_edge_args *args = IPA_EDGE_REF (e);
vec_safe_grow_cleared (args->jump_functions, count);
if (contexts_computed)
vec_safe_grow_cleared (args->polymorphic_call_contexts, count);
@@ -4440,7 +4441,7 @@ ipa_read_edge_info (struct lto_input_block *ib,
data_in, prevails);
if (contexts_computed)
{
- struct ipa_polymorphic_call_context ctx;
+ class ipa_polymorphic_call_context ctx;
ctx.stream_in (ib, data_in);
}
}
@@ -4450,14 +4451,14 @@ ipa_read_edge_info (struct lto_input_block *ib,
/* Stream in NODE info from IB. */
static void
-ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
- struct data_in *data_in)
+ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
+ class data_in *data_in)
{
int k;
struct cgraph_edge *e;
struct bitpack_d bp;
bool prevails = node->prevailing_p ();
- struct ipa_node_params *info = prevails ? IPA_NODE_REF (node) : NULL;
+ class ipa_node_params *info = prevails ? IPA_NODE_REF (node) : NULL;
int param_count = streamer_read_uhwi (ib);
if (prevails)
@@ -4554,7 +4555,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
const int cfg_offset = sizeof (struct lto_function_header);
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
- struct data_in *data_in;
+ class data_in *data_in;
unsigned int i;
unsigned int count;
@@ -4802,7 +4803,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
const int cfg_offset = sizeof (struct lto_function_header);
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
- struct data_in *data_in;
+ class data_in *data_in;
unsigned int i;
unsigned int count;
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 7257a6d..6470c93 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -144,8 +144,9 @@ struct GTY(()) ipa_agg_jump_function
typedef struct ipa_agg_jump_function *ipa_agg_jump_function_p;
/* Information about zero/non-zero bits. */
-struct GTY(()) ipa_bits
+class GTY(()) ipa_bits
{
+public:
/* The propagated value. */
widest_int value;
/* Mask corresponding to the value.
@@ -156,8 +157,9 @@ struct GTY(()) ipa_bits
/* Info about value ranges. */
-struct GTY(()) ipa_vr
+class GTY(()) ipa_vr
{
+public:
/* The data fields below are valid only if known is true. */
bool known;
enum value_range_kind type;
@@ -177,12 +179,12 @@ struct GTY (()) ipa_jump_func
/* Information about zero/non-zero bits. The pointed to structure is shared
betweed different jump functions. Use ipa_set_jfunc_bits to set this
field. */
- struct ipa_bits *bits;
+ class ipa_bits *bits;
/* Information about value range, containing valid data only when vr_known is
true. The pointed to structure is shared betweed different jump
functions. Use ipa_set_jfunc_vr to set this field. */
- struct value_range_base *m_vr;
+ class value_range_base *m_vr;
enum jump_func_type type;
/* Represents a value of a jump function. pass_through is used only in jump
@@ -319,8 +321,9 @@ struct GTY(()) ipa_param_descriptor
and some other information for interprocedural passes that operate on
parameters (such as ipa-cp). */
-struct GTY((for_user)) ipa_node_params
+class GTY((for_user)) ipa_node_params
{
+public:
/* Default constructor. */
ipa_node_params ();
@@ -332,7 +335,7 @@ struct GTY((for_user)) ipa_node_params
vec<ipa_param_descriptor, va_gc> *descriptors;
/* Pointer to an array of structures describing individual formal
parameters. */
- struct ipcp_param_lattices * GTY((skip)) lattices;
+ class ipcp_param_lattices * GTY((skip)) lattices;
/* Only for versioned nodes this field would not be NULL,
it points to the node that IPA cp cloned from. */
struct cgraph_node * GTY((skip)) ipcp_orig_node;
@@ -420,7 +423,7 @@ struct ipa_func_body_info
cgraph_node *node;
/* Its info. */
- struct ipa_node_params *info;
+ class ipa_node_params *info;
/* Information about individual BBs. */
vec<ipa_bb_info> bb_infos;
@@ -439,7 +442,7 @@ struct ipa_func_body_info
/* Return the number of formal parameters. */
static inline int
-ipa_get_param_count (struct ipa_node_params *info)
+ipa_get_param_count (class ipa_node_params *info)
{
return vec_safe_length (info->descriptors);
}
@@ -450,7 +453,7 @@ ipa_get_param_count (struct ipa_node_params *info)
WPA. */
static inline tree
-ipa_get_param (struct ipa_node_params *info, int i)
+ipa_get_param (class ipa_node_params *info, int i)
{
gcc_checking_assert (info->descriptors);
gcc_checking_assert (!flag_wpa);
@@ -463,7 +466,7 @@ ipa_get_param (struct ipa_node_params *info, int i)
to INFO if it is known or NULL if not. */
static inline tree
-ipa_get_type (struct ipa_node_params *info, int i)
+ipa_get_type (class ipa_node_params *info, int i)
{
if (vec_safe_length (info->descriptors) <= (unsigned) i)
return NULL;
@@ -480,7 +483,7 @@ ipa_get_type (struct ipa_node_params *info, int i)
to INFO. */
static inline int
-ipa_get_param_move_cost (struct ipa_node_params *info, int i)
+ipa_get_param_move_cost (class ipa_node_params *info, int i)
{
gcc_checking_assert (info->descriptors);
return (*info->descriptors)[i].move_cost;
@@ -490,7 +493,7 @@ ipa_get_param_move_cost (struct ipa_node_params *info, int i)
associated with INFO to VAL. */
static inline void
-ipa_set_param_used (struct ipa_node_params *info, int i, bool val)
+ipa_set_param_used (class ipa_node_params *info, int i, bool val)
{
gcc_checking_assert (info->descriptors);
(*info->descriptors)[i].used = val;
@@ -500,7 +503,7 @@ ipa_set_param_used (struct ipa_node_params *info, int i, bool val)
IPA_UNDESCRIBED_USE if there is a use that is not described by these
structures. */
static inline int
-ipa_get_controlled_uses (struct ipa_node_params *info, int i)
+ipa_get_controlled_uses (class ipa_node_params *info, int i)
{
/* FIXME: introducing speculation causes out of bounds access here. */
if (vec_safe_length (info->descriptors) > (unsigned)i)
@@ -511,7 +514,7 @@ ipa_get_controlled_uses (struct ipa_node_params *info, int i)
/* Set the controlled counter of a given parameter. */
static inline void
-ipa_set_controlled_uses (struct ipa_node_params *info, int i, int val)
+ipa_set_controlled_uses (class ipa_node_params *info, int i, int val)
{
gcc_checking_assert (info->descriptors);
(*info->descriptors)[i].controlled_uses = val;
@@ -521,7 +524,7 @@ ipa_set_controlled_uses (struct ipa_node_params *info, int i, int val)
function associated with INFO. */
static inline bool
-ipa_is_param_used (struct ipa_node_params *info, int i)
+ipa_is_param_used (class ipa_node_params *info, int i)
{
gcc_checking_assert (info->descriptors);
return (*info->descriptors)[i].used;
@@ -589,7 +592,7 @@ class GTY((for_user)) ipa_edge_args
/* Return the number of actual arguments. */
static inline int
-ipa_get_cs_argument_count (struct ipa_edge_args *args)
+ipa_get_cs_argument_count (class ipa_edge_args *args)
{
return vec_safe_length (args->jump_functions);
}
@@ -599,15 +602,15 @@ ipa_get_cs_argument_count (struct ipa_edge_args *args)
ipa_compute_jump_functions. */
static inline struct ipa_jump_func *
-ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
+ipa_get_ith_jump_func (class ipa_edge_args *args, int i)
{
return &(*args->jump_functions)[i];
}
/* Returns a pointer to the polymorphic call context for the ith argument.
NULL if contexts are not computed. */
-static inline struct ipa_polymorphic_call_context *
-ipa_get_ith_polymorhic_call_context (struct ipa_edge_args *args, int i)
+static inline class ipa_polymorphic_call_context *
+ipa_get_ith_polymorhic_call_context (class ipa_edge_args *args, int i)
{
if (!args->polymorphic_call_contexts)
return NULL;
@@ -778,11 +781,11 @@ extern object_allocator<ipcp_value<ipa_polymorphic_call_context> >
ipcp_poly_ctx_values_pool;
template <typename valtype>
-class ipcp_value_source;
+struct ipcp_value_source;
extern object_allocator<ipcp_value_source<tree> > ipcp_sources_pool;
-class ipcp_agg_lattice;
+struct ipcp_agg_lattice;
extern object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool;
@@ -792,15 +795,15 @@ void ipa_prop_write_jump_functions (void);
void ipa_prop_read_jump_functions (void);
void ipcp_write_transformation_summaries (void);
void ipcp_read_transformation_summaries (void);
-int ipa_get_param_decl_index (struct ipa_node_params *, tree);
-tree ipa_value_from_jfunc (struct ipa_node_params *info,
+int ipa_get_param_decl_index (class ipa_node_params *, tree);
+tree ipa_value_from_jfunc (class ipa_node_params *info,
struct ipa_jump_func *jfunc, tree type);
unsigned int ipcp_transform_function (struct cgraph_node *node);
ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *,
cgraph_edge *,
int,
ipa_jump_func *);
-void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
+void ipa_dump_param (FILE *, class ipa_node_params *info, int i);
void ipa_release_body_info (struct ipa_func_body_info *);
tree ipa_get_callee_param_type (struct cgraph_edge *e, int i);
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index f5e5396..db91d2c1 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -122,7 +122,7 @@ public:
enum malloc_state_e malloc_state;
};
-typedef struct funct_state_d * funct_state;
+typedef class funct_state_d * funct_state;
/* The storage of the funct_state is abstracted because there is the
possibility that it may be desirable to move this to the cgraph
@@ -1014,7 +1014,7 @@ analyze_function (struct cgraph_node *fn, bool ipa)
funct_state l;
basic_block this_block;
- l = XCNEW (struct funct_state_d);
+ l = XCNEW (class funct_state_d);
l->pure_const_state = IPA_CONST;
l->state_previously_known = IPA_NEITHER;
l->looping_previously_known = true;
@@ -1086,7 +1086,7 @@ end:
}
else
{
- struct loop *loop;
+ class loop *loop;
scev_initialize ();
FOR_EACH_LOOP (loop, 0)
if (!finite_loop_p (loop))
@@ -1279,7 +1279,7 @@ pure_const_read_summary (void)
{
const char *data;
size_t len;
- struct lto_input_block *ib
+ class lto_input_block *ib
= lto_create_simple_input_block (file_data,
LTO_section_ipa_pure_const,
&data, &len);
diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h
index 05e1058..0d8e509 100644
--- a/gcc/ipa-ref.h
+++ b/gcc/ipa-ref.h
@@ -22,8 +22,8 @@ along with GCC; see the file COPYING3. If not see
#define GCC_IPA_REF_H
struct cgraph_node;
-class varpool_node;
-class symtab_node;
+struct varpool_node;
+struct symtab_node;
/* How the reference is done. */
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 7b2614f..78737aa 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -1069,7 +1069,7 @@ ipa_reference_read_optimization_summary (void)
{
const char *data;
size_t len;
- struct lto_input_block *ib
+ class lto_input_block *ib
= lto_create_simple_input_block (file_data,
LTO_section_ipa_reference,
&data, &len);
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 5eaf825..86b26d3 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -108,8 +108,9 @@ along with GCC; see the file COPYING3. If not see
/* Per basic block info. */
-struct split_bb_info
+class split_bb_info
{
+public:
unsigned int size;
sreal time;
};
@@ -118,8 +119,9 @@ static vec<split_bb_info> bb_info_vec;
/* Description of split point. */
-struct split_point
+class split_point
{
+public:
/* Size of the partitions. */
sreal header_time, split_time;
unsigned int header_size, split_size;
@@ -144,7 +146,7 @@ struct split_point
/* Best split point found. */
-struct split_point best_split_point;
+class split_point best_split_point;
/* Set of basic blocks that are not allowed to dominate a split point. */
@@ -191,7 +193,7 @@ test_nonssa_use (gimple *, tree t, tree, void *data)
/* Dump split point CURRENT. */
static void
-dump_split_point (FILE * file, struct split_point *current)
+dump_split_point (FILE * file, class split_point *current)
{
fprintf (file,
"Split point at BB %i\n"
@@ -210,7 +212,7 @@ dump_split_point (FILE * file, struct split_point *current)
Parameters are the same as for consider_split. */
static bool
-verify_non_ssa_vars (struct split_point *current, bitmap non_ssa_vars,
+verify_non_ssa_vars (class split_point *current, bitmap non_ssa_vars,
basic_block return_bb)
{
bitmap seen = BITMAP_ALLOC (NULL);
@@ -404,7 +406,7 @@ dominated_by_forbidden (basic_block bb)
/* For give split point CURRENT and return block RETURN_BB return 1
if ssa name VAL is set by split part and 0 otherwise. */
static bool
-split_part_set_ssa_name_p (tree val, struct split_point *current,
+split_part_set_ssa_name_p (tree val, class split_point *current,
basic_block return_bb)
{
if (TREE_CODE (val) != SSA_NAME)
@@ -421,7 +423,7 @@ split_part_set_ssa_name_p (tree val, struct split_point *current,
See if we can split function here. */
static void
-consider_split (struct split_point *current, bitmap non_ssa_vars,
+consider_split (class split_point *current, bitmap non_ssa_vars,
basic_block return_bb)
{
tree parm;
@@ -979,8 +981,9 @@ visit_bb (basic_block bb, basic_block return_bb,
/* Stack entry for recursive DFS walk in find_split_point. */
-struct stack_entry
+class stack_entry
{
+public:
/* Basic block we are examining. */
basic_block bb;
@@ -1032,7 +1035,7 @@ find_split_points (basic_block return_bb, sreal overall_time, int overall_size)
stack_entry first;
vec<stack_entry> stack = vNULL;
basic_block bb;
- struct split_point current;
+ class split_point current;
current.header_time = overall_time;
current.header_size = overall_size;
@@ -1178,7 +1181,7 @@ find_split_points (basic_block return_bb, sreal overall_time, int overall_size)
/* Split function at SPLIT_POINT. */
static void
-split_function (basic_block return_bb, struct split_point *split_point,
+split_function (basic_block return_bb, class split_point *split_point,
bool add_tsan_func_exit)
{
vec<tree> args_to_pass = vNULL;
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 83caa3a..c7457fa4 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -253,10 +253,10 @@ finish_loop_tree_nodes (void)
loop designating the whole function when CFG loops are not
built. */
static void
-add_loop_to_tree (struct loop *loop)
+add_loop_to_tree (class loop *loop)
{
int loop_num;
- struct loop *parent;
+ class loop *parent;
ira_loop_tree_node_t loop_node, parent_node;
/* We cannot use loop node access macros here because of potential
@@ -331,7 +331,7 @@ static void
form_loop_tree (void)
{
basic_block bb;
- struct loop *parent;
+ class loop *parent;
ira_loop_tree_node_t bb_node, loop_node;
/* We cannot use loop/bb node access macros because of potential
@@ -2168,7 +2168,7 @@ low_pressure_loop_node_p (ira_loop_tree_node_t node)
form a region from such loop if the target use stack register
because reg-stack.c cannot deal with such edges. */
static bool
-loop_with_complex_edge_p (struct loop *loop)
+loop_with_complex_edge_p (class loop *loop)
{
int i;
edge_iterator ei;
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 8a90ae1..9923699 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -4557,7 +4557,7 @@ ira_reuse_stack_slot (int regno, poly_uint64 inherent_size,
ira_allocno_t another_allocno, allocno = ira_regno_allocno_map[regno];
rtx x;
bitmap_iterator bi;
- struct ira_spilled_reg_stack_slot *slot = NULL;
+ class ira_spilled_reg_stack_slot *slot = NULL;
ira_assert (! ira_use_lra_p);
@@ -4669,7 +4669,7 @@ ira_reuse_stack_slot (int regno, poly_uint64 inherent_size,
void
ira_mark_new_stack_slot (rtx x, int regno, poly_uint64 total_size)
{
- struct ira_spilled_reg_stack_slot *slot;
+ class ira_spilled_reg_stack_slot *slot;
int slot_num;
ira_allocno_t allocno;
diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index 51bf9c8..255af30 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -997,23 +997,30 @@ emit_moves (void)
basic_block bb;
edge_iterator ei;
edge e;
- rtx_insn *insns, *tmp;
+ rtx_insn *insns, *tmp, *next;
FOR_EACH_BB_FN (bb, cfun)
{
if (at_bb_start[bb->index] != NULL)
{
at_bb_start[bb->index] = modify_move_list (at_bb_start[bb->index]);
- insns = emit_move_list (at_bb_start[bb->index],
- REG_FREQ_FROM_BB (bb));
+ insns
+ = emit_move_list (at_bb_start[bb->index], REG_FREQ_FROM_BB (bb));
tmp = BB_HEAD (bb);
if (LABEL_P (tmp))
tmp = NEXT_INSN (tmp);
if (NOTE_INSN_BASIC_BLOCK_P (tmp))
tmp = NEXT_INSN (tmp);
+ /* Make sure to put the location of TMP or a subsequent instruction
+ to avoid inheriting the location of the previous instruction. */
+ next = tmp;
+ while (next && !NONDEBUG_INSN_P (next))
+ next = NEXT_INSN (next);
+ if (next)
+ set_insn_locations (insns, INSN_LOCATION (next));
if (tmp == BB_HEAD (bb))
emit_insn_before (insns, tmp);
- else if (tmp != NULL_RTX)
+ else if (tmp)
emit_insn_after (insns, PREV_INSN (tmp));
else
emit_insn_after (insns, get_last_insn ());
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 1ea35f7..92b7dfb 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -82,7 +82,7 @@ struct ira_loop_tree_node
/* The node represents basic block if children == NULL. */
basic_block bb; /* NULL for loop. */
/* NULL for BB or for loop tree root if we did not build CFG loop tree. */
- struct loop *loop;
+ class loop *loop;
/* NEXT/SUBLOOP_NEXT is the next node/loop-node of the same parent.
SUBLOOP_NEXT is always NULL for BBs. */
ira_loop_tree_node_t subloop_next, next;
@@ -597,8 +597,9 @@ extern int ira_copies_num;
/* The following structure describes a stack slot used for spilled
pseudo-registers. */
-struct ira_spilled_reg_stack_slot
+class ira_spilled_reg_stack_slot
{
+public:
/* pseudo-registers assigned to the stack slot. */
bitmap_head spilled_regs;
/* RTL representation of the stack slot. */
@@ -612,7 +613,7 @@ extern int ira_spilled_reg_stack_slots_num;
/* The following array contains info about spilled pseudo-registers
stack slots used in current function so far. */
-extern struct ira_spilled_reg_stack_slot *ira_spilled_reg_stack_slots;
+extern class ira_spilled_reg_stack_slot *ira_spilled_reg_stack_slots;
/* Correspondingly overall cost of the allocation, cost of the
allocnos assigned to hard-registers, cost of the allocnos assigned
@@ -774,7 +775,8 @@ minmax_set_iter_next (minmax_set_iterator *i)
minmax_set_iter_cond (&(ITER), &(N)); \
minmax_set_iter_next (&(ITER)))
-struct target_ira_int {
+class target_ira_int {
+public:
~target_ira_int ();
void free_ira_costs ();
@@ -907,9 +909,9 @@ struct target_ira_int {
bool x_ira_prohibited_mode_move_regs_initialized_p;
};
-extern struct target_ira_int default_target_ira_int;
+extern class target_ira_int default_target_ira_int;
#if SWITCHABLE_TARGET
-extern struct target_ira_int *this_target_ira_int;
+extern class target_ira_int *this_target_ira_int;
#else
#define this_target_ira_int (&default_target_ira_int)
#endif
diff --git a/gcc/ira.c b/gcc/ira.c
index 214fdff..c58daba 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -394,10 +394,10 @@ along with GCC; see the file COPYING3. If not see
#include "print-rtl.h"
struct target_ira default_target_ira;
-struct target_ira_int default_target_ira_int;
+class target_ira_int default_target_ira_int;
#if SWITCHABLE_TARGET
struct target_ira *this_target_ira = &default_target_ira;
-struct target_ira_int *this_target_ira_int = &default_target_ira_int;
+class target_ira_int *this_target_ira_int = &default_target_ira_int;
#endif
/* A modified value of flag `-fira-verbose' used internally. */
@@ -411,7 +411,7 @@ int ira_spilled_reg_stack_slots_num;
/* The following array contains info about spilled pseudo-registers
stack slots used in current function so far. */
-struct ira_spilled_reg_stack_slot *ira_spilled_reg_stack_slots;
+class ira_spilled_reg_stack_slot *ira_spilled_reg_stack_slots;
/* Correspondingly overall cost of the allocation, overall cost before
reload, cost of the allocnos assigned to hard-registers, cost of
@@ -4061,7 +4061,7 @@ setup_reg_equiv (void)
/* Print chain C to FILE. */
static void
-print_insn_chain (FILE *file, struct insn_chain *c)
+print_insn_chain (FILE *file, class insn_chain *c)
{
fprintf (file, "insn=%d, ", INSN_UID (c->insn));
bitmap_print (file, &c->live_throughout, "live_throughout: ", ", ");
@@ -4073,7 +4073,7 @@ print_insn_chain (FILE *file, struct insn_chain *c)
static void
print_insn_chains (FILE *file)
{
- struct insn_chain *c;
+ class insn_chain *c;
for (c = reload_insn_chain; c ; c = c->next)
print_insn_chain (file, c);
}
@@ -4134,10 +4134,10 @@ static void
build_insn_chain (void)
{
unsigned int i;
- struct insn_chain **p = &reload_insn_chain;
+ class insn_chain **p = &reload_insn_chain;
basic_block bb;
- struct insn_chain *c = NULL;
- struct insn_chain *next = NULL;
+ class insn_chain *c = NULL;
+ class insn_chain *next = NULL;
auto_bitmap live_relevant_regs;
auto_bitmap elim_regset;
/* live_subregs is a vector used to keep accurate information about
@@ -5467,11 +5467,11 @@ ira (FILE *f)
{
ira_spilled_reg_stack_slots_num = 0;
ira_spilled_reg_stack_slots
- = ((struct ira_spilled_reg_stack_slot *)
+ = ((class ira_spilled_reg_stack_slot *)
ira_allocate (max_regno
- * sizeof (struct ira_spilled_reg_stack_slot)));
+ * sizeof (class ira_spilled_reg_stack_slot)));
memset ((void *)ira_spilled_reg_stack_slots, 0,
- max_regno * sizeof (struct ira_spilled_reg_stack_slot));
+ max_regno * sizeof (class ira_spilled_reg_stack_slot));
}
}
allocate_initial_values ();
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index 9958db1..af3f6b7 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,50 @@
+2019-07-22 Andrea Corallo <andrea.corallo@arm.com>
+
+ * jit-recording.c (unary_op_reproducer_strings): Make it extern.
+ (binary_op_reproducer_strings): Likewise.
+ * jit-recording.h (unary_op_reproducer_strings): Likewise.
+ (binary_op_reproducer_strings): Likewise.
+ * libgccjit.c (gcc_jit_context_new_unary_op): Check result_type to be a
+ numeric type.
+ * libgccjit.c (gcc_jit_context_new_binary_op): Improve error message.
+
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+
+ * libgccjit.c (gcc_jit_context_new_binary_op): Check result_type to be a
+ numeric type.
+
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+
+ * docs/topics/compatibility.rst (LIBGCCJIT_ABI_12): New ABI tag.
+ * docs/topics/types.rst: Add gcc_jit_context_new_bitfield.
+ * jit-common.h (namespace recording): Add class bitfield.
+ * jit-playback.c:
+ (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): Add macros.
+ (playback::context::new_bitfield): New method.
+ (playback::compound_type::set_fields): Add bitfield support.
+ (playback::lvalue::mark_addressable): Was jit_mark_addressable make this
+ a method of lvalue plus return a bool to communicate success.
+ (playback::lvalue::get_address): Check for jit_mark_addressable return
+ value.
+ * jit-playback.h (new_bitfield): New method.
+ (class bitfield): New class.
+ (class lvalue): Add jit_mark_addressable method.
+ * jit-recording.c (recording::context::new_bitfield): New method.
+ (recording::bitfield::replay_into): New method.
+ (recording::bitfield::write_to_dump): Likewise.
+ (recording::bitfield::make_debug_string): Likewise.
+ (recording::bitfield::write_reproducer): Likewise.
+ * jit-recording.h (class context): Add new_bitfield method.
+ (class field): Make it derivable by class bitfield.
+ (class bitfield): Add new class.
+ * libgccjit++.h (class context): Add new_bitfield method.
+ * libgccjit.c (struct gcc_jit_bitfield): New structure.
+ (gcc_jit_context_new_bitfield): New function.
+ * libgccjit.h
+ (LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield) New macro.
+ (gcc_jit_context_new_bitfield): New function.
+ * libgccjit.map (LIBGCCJIT_ABI_12) New ABI tag.
+
2019-03-21 Jakub Jelinek <jakub@redhat.com>
* jit-recording.c (reproducer::m_set_identifiers): Use false as Lazy
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index abefa56..da64920 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -177,3 +177,8 @@ entrypoints:
--------------------
``LIBGCCJIT_ABI_11`` covers the addition of
:func:`gcc_jit_context_add_driver_option`
+
+``LIBGCCJIT_ABI_12``
+--------------------
+``LIBGCCJIT_ABI_12`` covers the addition of
+:func:`gcc_jit_context_new_bitfield`
diff --git a/gcc/jit/docs/topics/types.rst b/gcc/jit/docs/topics/types.rst
index 1d2dcd4..37d9d01 100644
--- a/gcc/jit/docs/topics/types.rst
+++ b/gcc/jit/docs/topics/types.rst
@@ -247,6 +247,30 @@ You can model C `struct` types by creating :c:type:`gcc_jit_struct *` and
underlying string, so it is valid to pass in a pointer to an on-stack
buffer.
+.. function:: gcc_jit_field *\
+ gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_type *type,\
+ int width,\
+ const char *name)
+
+ Construct a new bit field, with the given type width and name.
+
+ The parameter ``name`` must be non-NULL. The call takes a copy of the
+ underlying string, so it is valid to pass in a pointer to an on-stack
+ buffer.
+
+ The parameter ``type`` must be an integer type.
+
+ The parameter ``width`` must be a positive integer that does not exceed the
+ size of ``type``.
+
+ This API entrypoint was added in :ref:`LIBGCCJIT_ABI_12`; you can test
+ for its presence using
+ .. code-block:: c
+
+ #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
+
.. function:: gcc_jit_object *\
gcc_jit_field_as_object (gcc_jit_field *field)
diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
index 1d96cc3..e747d96 100644
--- a/gcc/jit/jit-common.h
+++ b/gcc/jit/jit-common.h
@@ -119,6 +119,7 @@ namespace recording {
class union_;
class vector_type;
class field;
+ class bitfield;
class fields;
class function;
class block;
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index b74495c..942c730 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -47,6 +47,13 @@ along with GCC; see the file COPYING3. If not see
#include "jit-builtins.h"
#include "jit-tempdir.h"
+/* Compare with gcc/c-family/c-common.h: DECL_C_BIT_FIELD,
+ SET_DECL_C_BIT_FIELD.
+ These are redefined here to avoid depending from the C frontend. */
+#define DECL_JIT_BIT_FIELD(NODE) \
+ (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1)
+#define SET_DECL_JIT_BIT_FIELD(NODE) \
+ (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1)
/* gcc::jit::playback::context::build_cast uses the convert.h API,
which in turn requires the frontend to provide a "convert"
@@ -263,6 +270,46 @@ new_field (location *loc,
return new field (decl);
}
+/* Construct a playback::bitfield instance (wrapping a tree). */
+
+playback::field *
+playback::context::
+new_bitfield (location *loc,
+ type *type,
+ int width,
+ const char *name)
+{
+ gcc_assert (type);
+ gcc_assert (name);
+ gcc_assert (width);
+
+ /* compare with c/c-decl.c:grokfield, grokdeclarator and
+ check_bitfield_type_and_width. */
+
+ tree tree_type = type->as_tree ();
+ gcc_assert (INTEGRAL_TYPE_P (tree_type));
+ tree tree_width = build_int_cst (integer_type_node, width);
+ if (compare_tree_int (tree_width, TYPE_PRECISION (tree_type)) > 0)
+ {
+ add_error (
+ loc,
+ "width of bit-field %s (width: %i) is wider than its type (width: %i)",
+ name, width, TYPE_PRECISION (tree_type));
+ return NULL;
+ }
+
+ tree decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
+ get_identifier (name), type->as_tree ());
+ DECL_NONADDRESSABLE_P (decl) = true;
+ DECL_INITIAL (decl) = tree_width;
+ SET_DECL_JIT_BIT_FIELD (decl);
+
+ if (loc)
+ set_tree_location (decl, loc);
+
+ return new field (decl);
+}
+
/* Construct a playback::compound_type instance (wrapping a tree). */
playback::compound_type *
@@ -295,8 +342,15 @@ playback::compound_type::set_fields (const auto_vec<playback::field *> *fields)
for (unsigned i = 0; i < fields->length (); i++)
{
field *f = (*fields)[i];
- DECL_CONTEXT (f->as_tree ()) = t;
- fieldlist = chainon (f->as_tree (), fieldlist);
+ tree x = f->as_tree ();
+ DECL_CONTEXT (x) = t;
+ if (DECL_JIT_BIT_FIELD (x))
+ {
+ unsigned HOST_WIDE_INT width = tree_to_uhwi (DECL_INITIAL (x));
+ DECL_SIZE (x) = bitsize_int (width);
+ DECL_BIT_FIELD (x) = 1;
+ }
+ fieldlist = chainon (x, fieldlist);
}
fieldlist = nreverse (fieldlist);
TYPE_FIELDS (t) = fieldlist;
@@ -1197,20 +1251,31 @@ dereference (location *loc)
return new lvalue (get_context (), datum);
}
-/* Mark EXP saying that we need to be able to take the
+/* Mark the lvalue saying that we need to be able to take the
address of it; it should not be allocated in a register.
- Compare with e.g. c/c-typeck.c: c_mark_addressable. */
+ Compare with e.g. c/c-typeck.c: c_mark_addressable really_atomic_lvalue.
+ Returns false if a failure occurred (an error will already have been
+ added to the active context for this case). */
-static void
-jit_mark_addressable (tree exp)
+bool
+playback::lvalue::
+mark_addressable (location *loc)
{
- tree x = exp;
+ tree x = as_tree ();;
while (1)
switch (TREE_CODE (x))
{
case COMPONENT_REF:
- /* (we don't yet support bitfields) */
+ if (DECL_JIT_BIT_FIELD (TREE_OPERAND (x, 1)))
+ {
+ gcc_assert (gcc::jit::active_playback_ctxt);
+ gcc::jit::
+ active_playback_ctxt->add_error (loc,
+ "cannot take address of "
+ "bit-field");
+ return false;
+ }
/* fallthrough */
case ADDR_EXPR:
case ARRAY_REF:
@@ -1222,7 +1287,7 @@ jit_mark_addressable (tree exp)
case COMPOUND_LITERAL_EXPR:
case CONSTRUCTOR:
TREE_ADDRESSABLE (x) = 1;
- return;
+ return true;
case VAR_DECL:
case CONST_DECL:
@@ -1234,7 +1299,7 @@ jit_mark_addressable (tree exp)
TREE_ADDRESSABLE (x) = 1;
/* fallthrough */
default:
- return;
+ return true;
}
}
@@ -1251,8 +1316,10 @@ get_address (location *loc)
tree ptr = build1 (ADDR_EXPR, t_ptrtype, t_lvalue);
if (loc)
get_context ()->set_tree_location (ptr, loc);
- jit_mark_addressable (t_lvalue);
- return new rvalue (get_context (), ptr);
+ if (mark_addressable (loc))
+ return new rvalue (get_context (), ptr);
+ else
+ return NULL;
}
/* The wrapper subclasses are GC-managed, but can own non-GC memory.
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index bc4de9c..d4b148e 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -75,6 +75,12 @@ public:
type *type,
const char *name);
+ field *
+ new_bitfield (location *loc,
+ type *type,
+ int width,
+ const char *name);
+
compound_type *
new_compound_type (location *loc,
const char *name,
@@ -426,6 +432,8 @@ private:
tree m_inner;
};
+class bitfield : public field {};
+
class function : public wrapper
{
public:
@@ -614,6 +622,8 @@ public:
rvalue *
get_address (location *loc);
+private:
+ bool mark_addressable (location *loc);
};
class param : public lvalue
@@ -703,4 +713,3 @@ extern playback::context *active_playback_ctxt;
} // namespace gcc
#endif /* JIT_PLAYBACK_H */
-
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index a332fe8..2f75395 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -872,6 +872,24 @@ recording::context::new_field (recording::location *loc,
return result;
}
+/* Create a recording::bitfield instance and add it to this context's list
+ of mementos.
+
+ Implements the post-error-checking part of
+ gcc_jit_context_new_bitfield. */
+
+recording::field *
+recording::context::new_bitfield (recording::location *loc,
+ recording::type *type,
+ int width,
+ const char *name)
+{
+ recording::field *result =
+ new recording::bitfield (this, loc, type, width, new_string (name));
+ record (result);
+ return result;
+}
+
/* Create a recording::struct_ instance and add it to this context's
list of mementos and list of compound types.
@@ -2962,7 +2980,7 @@ recording::field::replay_into (replayer *r)
recording::memento::write_to_dump. Dump each field
by dumping a line of the form:
TYPE NAME;
- so that we can build up a struct/union field-byfield. */
+ so that we can build up a struct/union field by field. */
void
recording::field::write_to_dump (dump &d)
@@ -2999,6 +3017,66 @@ recording::field::write_reproducer (reproducer &r)
m_name->get_debug_string ());
}
+/* The implementation of class gcc::jit::recording::bitfield. */
+
+/* Implementation of pure virtual hook recording::memento::replay_into
+ for recording::bitfield. */
+
+void
+recording::bitfield::replay_into (replayer *r)
+{
+ set_playback_obj (r->new_bitfield (playback_location (r, m_loc),
+ m_type->playback_type (),
+ m_width,
+ playback_string (m_name)));
+}
+
+/* Override the default implementation of
+ recording::memento::write_to_dump. Dump each bit field
+ by dumping a line of the form:
+ TYPE NAME:WIDTH;
+ so that we can build up a struct/union field by field. */
+
+void
+recording::bitfield::write_to_dump (dump &d)
+{
+ d.write (" %s %s:%d;\n",
+ m_type->get_debug_string (),
+ m_name->c_str (),
+ m_width);
+}
+
+/* Implementation of recording::memento::make_debug_string for
+ results of new_bitfield. */
+
+recording::string *
+recording::bitfield::make_debug_string ()
+{
+ return string::from_printf (m_ctxt,
+ "%s:%d",
+ m_name->c_str (), m_width);
+}
+
+/* Implementation of recording::memento::write_reproducer for bitfields. */
+
+void
+recording::bitfield::write_reproducer (reproducer &r)
+{
+ const char *id = r.make_identifier (this, "bitfield");
+ r.write (" gcc_jit_field *%s =\n"
+ " gcc_jit_context_new_bitfield (%s,\n"
+ " %s, /* gcc_jit_location *loc */\n"
+ " %s, /* gcc_jit_type *type, */\n"
+ " %d, /* int width, */\n"
+ " %s); /* const char *name */\n",
+ id,
+ r.get_identifier (get_context ()),
+ r.get_identifier (m_loc),
+ r.get_identifier_as_type (m_type),
+ m_width,
+ m_name->get_debug_string ());
+}
+
/* The implementation of class gcc::jit::recording::compound_type */
/* The constructor for gcc::jit::recording::compound_type. */
@@ -4810,7 +4888,7 @@ recording::unary_op::make_debug_string ()
m_a->get_debug_string ());
}
-static const char * const unary_op_reproducer_strings[] = {
+const char * const unary_op_reproducer_strings[] = {
"GCC_JIT_UNARY_OP_MINUS",
"GCC_JIT_UNARY_OP_BITWISE_NEGATE",
"GCC_JIT_UNARY_OP_LOGICAL_NEGATE",
@@ -4890,7 +4968,7 @@ recording::binary_op::make_debug_string ()
m_b->get_debug_string_parens (prec));
}
-static const char * const binary_op_reproducer_strings[] = {
+const char * const binary_op_reproducer_strings[] = {
"GCC_JIT_BINARY_OP_PLUS",
"GCC_JIT_BINARY_OP_MINUS",
"GCC_JIT_BINARY_OP_MULT",
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index b9f2250..4bd346e 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -30,6 +30,9 @@ namespace gcc {
namespace jit {
+extern const char * const unary_op_reproducer_strings[];
+extern const char * const binary_op_reproducer_strings[];
+
class result;
class dump;
class reproducer;
@@ -95,6 +98,12 @@ public:
type *type,
const char *name);
+ field *
+ new_bitfield (location *loc,
+ type *type,
+ int width,
+ const char *name);
+
struct_ *
new_struct_type (location *loc,
const char *name);
@@ -822,9 +831,9 @@ public:
compound_type * get_container () const { return m_container; }
void set_container (compound_type *c) { m_container = c; }
- void replay_into (replayer *) FINAL OVERRIDE;
+ void replay_into (replayer *) OVERRIDE;
- void write_to_dump (dump &d) FINAL OVERRIDE;
+ void write_to_dump (dump &d) OVERRIDE;
playback::field *
playback_field () const
@@ -833,16 +842,41 @@ public:
}
private:
- string * make_debug_string () FINAL OVERRIDE;
- void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ string * make_debug_string () OVERRIDE;
+ void write_reproducer (reproducer &r) OVERRIDE;
-private:
+protected:
location *m_loc;
type *m_type;
string *m_name;
compound_type *m_container;
};
+
+class bitfield : public field
+{
+public:
+ bitfield (context *ctxt,
+ location *loc,
+ type *type,
+ int width,
+ string *name)
+ : field (ctxt, loc, type, name),
+ m_width (width)
+ {}
+
+ void replay_into (replayer *) FINAL OVERRIDE;
+
+ void write_to_dump (dump &d) FINAL OVERRIDE;
+
+private:
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+
+private:
+ int m_width;
+};
+
/* Base class for struct_ and union_ */
class compound_type : public type
{
diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h
index 55aebca..0c5be5a 100644
--- a/gcc/jit/libgccjit++.h
+++ b/gcc/jit/libgccjit++.h
@@ -152,6 +152,9 @@ namespace gccjit
field new_field (type type_, const std::string &name,
location loc = location ());
+ field new_bitfield (type type_, int width, const std::string &name,
+ location loc = location ());
+
struct_ new_struct_type (const std::string &name,
std::vector<field> &fields,
location loc = location ());
@@ -757,6 +760,17 @@ context::new_field (type type_, const std::string &name, location loc)
name.c_str ()));
}
+inline field
+context::new_bitfield (type type_, int width, const std::string &name,
+ location loc)
+{
+ return field (gcc_jit_context_new_bitfield (m_inner_ctxt,
+ loc.get_inner_location (),
+ type_.get_inner_type (),
+ width,
+ name.c_str ()));
+}
+
inline struct_
context::new_struct_type (const std::string &name,
std::vector<field> &fields,
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index e4f17f8..eec2f00 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -62,6 +62,10 @@ struct gcc_jit_field : public gcc::jit::recording::field
{
};
+struct gcc_jit_bitfield : public gcc::jit::recording::bitfield
+{
+};
+
struct gcc_jit_function : public gcc::jit::recording::function
{
};
@@ -556,6 +560,42 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
/* Public entrypoint. See description in libgccjit.h.
+ After error-checking, the real work is done by the
+ gcc::jit::recording::context::new_bitfield method, in
+ jit-recording.c. */
+
+gcc_jit_field *
+gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
+ gcc_jit_location *loc,
+ gcc_jit_type *type,
+ int width,
+ const char *name)
+{
+ RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ /* LOC can be NULL. */
+ RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name");
+ RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type");
+ RETURN_NULL_IF_FAIL_PRINTF2 (type->is_int () || type->is_bool (),
+ ctxt, loc,
+ "bit-field %s has non integral type %s",
+ name, type->get_debug_string ());
+ RETURN_NULL_IF_FAIL_PRINTF2 (
+ width > 0, ctxt, loc,
+ "invalid width %d for bitfield \"%s\" (must be > 0)",
+ width, name);
+ RETURN_NULL_IF_FAIL_PRINTF2 (
+ type->has_known_size (),
+ ctxt, loc,
+ "unknown size for field \"%s\" (type: %s)",
+ name,
+ type->get_debug_string ());
+
+ return (gcc_jit_field *)ctxt->new_bitfield (loc, type, width, name);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
After error-checking, this calls the trivial
gcc::jit::recording::memento::as_object method (a field is a
memento), in jit-recording.h. */
@@ -1296,6 +1336,13 @@ gcc_jit_context_new_unary_op (gcc_jit_context *ctxt,
"unrecognized value for enum gcc_jit_unary_op: %i",
op);
RETURN_NULL_IF_FAIL (result_type, ctxt, loc, "NULL result_type");
+ RETURN_NULL_IF_FAIL_PRINTF3 (
+ result_type->is_numeric (), ctxt, loc,
+ "gcc_jit_unary_op %s with operand %s "
+ "has non-numeric result_type: %s",
+ gcc::jit::unary_op_reproducer_strings[op],
+ rvalue->get_debug_string (),
+ result_type->get_debug_string ());
RETURN_NULL_IF_FAIL (rvalue, ctxt, loc, "NULL rvalue");
return (gcc_jit_rvalue *)ctxt->new_unary_op (loc, op, result_type, rvalue);
@@ -1345,6 +1392,13 @@ gcc_jit_context_new_binary_op (gcc_jit_context *ctxt,
a->get_type ()->get_debug_string (),
b->get_debug_string (),
b->get_type ()->get_debug_string ());
+ RETURN_NULL_IF_FAIL_PRINTF4 (
+ result_type->is_numeric (), ctxt, loc,
+ "gcc_jit_binary_op %s with operands a: %s b: %s "
+ "has non-numeric result_type: %s",
+ gcc::jit::binary_op_reproducer_strings[op],
+ a->get_debug_string (), b->get_debug_string (),
+ result_type->get_debug_string ());
return (gcc_jit_rvalue *)ctxt->new_binary_op (loc, op, result_type, a, b);
}
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index beeb747..9c5f23b 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -602,6 +602,21 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt,
gcc_jit_type *type,
const char *name);
+#define LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
+
+/* Create a bit field, for use within a struct or union.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_12; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_bitfield
+*/
+extern gcc_jit_field *
+gcc_jit_context_new_bitfield (gcc_jit_context *ctxt,
+ gcc_jit_location *loc,
+ gcc_jit_type *type,
+ int width,
+ const char *name);
+
/* Upcasting from field to object. */
extern gcc_jit_object *
gcc_jit_field_as_object (gcc_jit_field *field);
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 16f5253..40e1c78 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -174,4 +174,9 @@ LIBGCCJIT_ABI_10 {
LIBGCCJIT_ABI_11 {
global:
gcc_jit_context_add_driver_option;
-} LIBGCCJIT_ABI_10; \ No newline at end of file
+} LIBGCCJIT_ABI_10;
+
+LIBGCCJIT_ABI_12 {
+ global:
+ gcc_jit_context_new_bitfield;
+} LIBGCCJIT_ABI_11; \ No newline at end of file
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 89714be..0efe7b4 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -263,7 +263,7 @@ doloop_condition_get (rtx_insn *doloop_pat)
describes the number of iterations of the loop. */
static bool
-doloop_valid_p (struct loop *loop, struct niter_desc *desc)
+doloop_valid_p (class loop *loop, class niter_desc *desc)
{
basic_block *body = get_loop_body (loop), bb;
rtx_insn *insn;
@@ -405,7 +405,7 @@ add_test (rtx cond, edge *e, basic_block dest)
DOLOOP_SEQ. COUNT is the number of iterations of the LOOP. */
static void
-doloop_modify (struct loop *loop, struct niter_desc *desc,
+doloop_modify (class loop *loop, class niter_desc *desc,
rtx_insn *doloop_seq, rtx condition, rtx count)
{
rtx counter_reg;
@@ -603,7 +603,7 @@ record_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
modified. */
static bool
-doloop_optimize (struct loop *loop)
+doloop_optimize (class loop *loop)
{
scalar_int_mode mode;
rtx doloop_reg;
@@ -614,7 +614,7 @@ doloop_optimize (struct loop *loop)
unsigned level;
HOST_WIDE_INT est_niter;
int max_cost;
- struct niter_desc *desc;
+ class niter_desc *desc;
unsigned word_mode_size;
unsigned HOST_WIDE_INT word_mode_max;
int entered_at_top;
@@ -754,7 +754,7 @@ doloop_optimize (struct loop *loop)
void
doloop_optimize_loops (void)
{
- struct loop *loop;
+ class loop *loop;
if (optimize == 1)
{
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index bdfa385..4b3bbcc 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -135,7 +135,7 @@ loop_optimizer_init (unsigned flags)
void
loop_optimizer_finalize (struct function *fn)
{
- struct loop *loop;
+ class loop *loop;
basic_block bb;
timevar_push (TV_LOOP_FINI);
@@ -194,7 +194,7 @@ fix_loop_structure (bitmap changed_bbs)
{
basic_block bb;
int record_exits = 0;
- struct loop *loop;
+ class loop *loop;
unsigned old_nloops, i;
timevar_push (TV_LOOP_INIT);
@@ -237,7 +237,7 @@ fix_loop_structure (bitmap changed_bbs)
while (loop->inner)
{
- struct loop *ploop = loop->inner;
+ class loop *ploop = loop->inner;
flow_loop_tree_node_remove (ploop);
flow_loop_tree_node_add (loop_outer (loop), ploop);
}
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index b880ead..644ecfc 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -58,9 +58,10 @@ along with GCC; see the file COPYING3. If not see
/* The data stored for the loop. */
-struct loop_data
+class loop_data
{
- struct loop *outermost_exit; /* The outermost exit of the loop. */
+public:
+ class loop *outermost_exit; /* The outermost exit of the loop. */
bool has_call; /* True if the loop contains a call. */
/* Maximal register pressure inside loop for given register class
(defined only for the pressure classes). */
@@ -70,7 +71,7 @@ struct loop_data
bitmap_head regs_live;
};
-#define LOOP_DATA(LOOP) ((struct loop_data *) (LOOP)->aux)
+#define LOOP_DATA(LOOP) ((class loop_data *) (LOOP)->aux)
/* The description of an use. */
@@ -143,7 +144,7 @@ struct invariant
};
/* Currently processed loop. */
-static struct loop *curr_loop;
+static class loop *curr_loop;
/* Table of invariants indexed by the df_ref uid field. */
@@ -557,7 +558,7 @@ merge_identical_invariants (void)
get_loop_body_in_dom_order. */
static void
-compute_always_reached (struct loop *loop, basic_block *body,
+compute_always_reached (class loop *loop, basic_block *body,
bitmap may_exit, bitmap always_reached)
{
unsigned i;
@@ -577,13 +578,13 @@ compute_always_reached (struct loop *loop, basic_block *body,
additionally mark blocks that may exit due to a call. */
static void
-find_exits (struct loop *loop, basic_block *body,
+find_exits (class loop *loop, basic_block *body,
bitmap may_exit, bitmap has_exit)
{
unsigned i;
edge_iterator ei;
edge e;
- struct loop *outermost_exit = loop, *aexit;
+ class loop *outermost_exit = loop, *aexit;
bool has_call = false;
rtx_insn *insn;
@@ -644,7 +645,7 @@ find_exits (struct loop *loop, basic_block *body,
if (loop->aux == NULL)
{
- loop->aux = xcalloc (1, sizeof (struct loop_data));
+ loop->aux = xcalloc (1, sizeof (class loop_data));
bitmap_initialize (&LOOP_DATA (loop)->regs_ref, &reg_obstack);
bitmap_initialize (&LOOP_DATA (loop)->regs_live, &reg_obstack);
}
@@ -672,7 +673,7 @@ may_assign_reg_p (rtx x)
BODY. */
static void
-find_defs (struct loop *loop)
+find_defs (class loop *loop)
{
if (dump_file)
{
@@ -1209,7 +1210,7 @@ find_invariants_bb (basic_block bb, bool always_reached, bool always_executed)
ends due to a function call. */
static void
-find_invariants_body (struct loop *loop, basic_block *body,
+find_invariants_body (class loop *loop, basic_block *body,
bitmap always_reached, bitmap always_executed)
{
unsigned i;
@@ -1223,7 +1224,7 @@ find_invariants_body (struct loop *loop, basic_block *body,
/* Finds invariants in LOOP. */
static void
-find_invariants (struct loop *loop)
+find_invariants (class loop *loop)
{
auto_bitmap may_exit;
auto_bitmap always_reached;
@@ -1686,7 +1687,7 @@ replace_uses (struct invariant *inv, rtx reg, bool in_group)
the block preceding its header. */
static bool
-can_move_invariant_reg (struct loop *loop, struct invariant *inv, rtx reg)
+can_move_invariant_reg (class loop *loop, struct invariant *inv, rtx reg)
{
df_ref def, use;
unsigned int dest_regno, defs_in_loop_count = 0;
@@ -1759,7 +1760,7 @@ can_move_invariant_reg (struct loop *loop, struct invariant *inv, rtx reg)
otherwise. */
static bool
-move_invariant_reg (struct loop *loop, unsigned invno)
+move_invariant_reg (class loop *loop, unsigned invno)
{
struct invariant *inv = invariants[invno];
struct invariant *repr = invariants[inv->eqto];
@@ -1865,7 +1866,7 @@ fail:
in TEMPORARY_REGS. */
static void
-move_invariants (struct loop *loop)
+move_invariants (class loop *loop)
{
struct invariant *inv;
unsigned i;
@@ -1938,7 +1939,7 @@ free_inv_motion_data (void)
/* Move the invariants out of the LOOP. */
static void
-move_single_loop_invariants (struct loop *loop)
+move_single_loop_invariants (class loop *loop)
{
init_inv_motion_data ();
@@ -1953,9 +1954,9 @@ move_single_loop_invariants (struct loop *loop)
/* Releases the auxiliary data for LOOP. */
static void
-free_loop_data (struct loop *loop)
+free_loop_data (class loop *loop)
{
- struct loop_data *data = LOOP_DATA (loop);
+ class loop_data *data = LOOP_DATA (loop);
if (!data)
return;
@@ -2034,7 +2035,7 @@ change_pressure (int regno, bool incr_p)
static void
mark_regno_live (int regno)
{
- struct loop *loop;
+ class loop *loop;
for (loop = curr_loop;
loop != current_loops->tree_root;
@@ -2103,7 +2104,7 @@ mark_ref_regs (rtx x)
code = GET_CODE (x);
if (code == REG)
{
- struct loop *loop;
+ class loop *loop;
for (loop = curr_loop;
loop != current_loops->tree_root;
@@ -2135,12 +2136,12 @@ calculate_loop_reg_pressure (void)
basic_block bb;
rtx_insn *insn;
rtx link;
- struct loop *loop, *parent;
+ class loop *loop, *parent;
FOR_EACH_LOOP (loop, 0)
if (loop->aux == NULL)
{
- loop->aux = xcalloc (1, sizeof (struct loop_data));
+ loop->aux = xcalloc (1, sizeof (class loop_data));
bitmap_initialize (&LOOP_DATA (loop)->regs_ref, &reg_obstack);
bitmap_initialize (&LOOP_DATA (loop)->regs_live, &reg_obstack);
}
@@ -2252,7 +2253,7 @@ calculate_loop_reg_pressure (void)
void
move_loop_invariants (void)
{
- struct loop *loop;
+ class loop *loop;
if (optimize == 1)
df_live_add_problem ();
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 207b5e2..2274cc3 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -85,10 +85,11 @@ enum iv_grd_result
/* Information about a biv. */
-struct biv_entry
+class biv_entry
{
+public:
unsigned regno; /* The register of the biv. */
- struct rtx_iv iv; /* Value of the biv. */
+ class rtx_iv iv; /* Value of the biv. */
};
static bool clean_slate = true;
@@ -96,7 +97,7 @@ static bool clean_slate = true;
static unsigned int iv_ref_table_size = 0;
/* Table of rtx_ivs indexed by the df_ref uid field. */
-static struct rtx_iv ** iv_ref_table;
+static class rtx_iv ** iv_ref_table;
/* Induction variable stored at the reference. */
#define DF_REF_IV(REF) iv_ref_table[DF_REF_ID (REF)]
@@ -104,7 +105,7 @@ static struct rtx_iv ** iv_ref_table;
/* The current loop. */
-static struct loop *current_loop;
+static class loop *current_loop;
/* Hashtable helper. */
@@ -135,7 +136,7 @@ biv_entry_hasher::equal (const biv_entry *b, const rtx_def *r)
static hash_table<biv_entry_hasher> *bivs;
-static bool iv_analyze_op (rtx_insn *, scalar_int_mode, rtx, struct rtx_iv *);
+static bool iv_analyze_op (rtx_insn *, scalar_int_mode, rtx, class rtx_iv *);
/* Return the RTX code corresponding to the IV extend code EXTEND. */
static inline enum rtx_code
@@ -155,9 +156,9 @@ iv_extend_to_rtx_code (enum iv_extend_code extend)
/* Dumps information about IV to FILE. */
-extern void dump_iv_info (FILE *, struct rtx_iv *);
+extern void dump_iv_info (FILE *, class rtx_iv *);
void
-dump_iv_info (FILE *file, struct rtx_iv *iv)
+dump_iv_info (FILE *file, class rtx_iv *iv)
{
if (!iv->base)
{
@@ -203,9 +204,9 @@ check_iv_ref_table_size (void)
if (iv_ref_table_size < DF_DEFS_TABLE_SIZE ())
{
unsigned int new_size = DF_DEFS_TABLE_SIZE () + (DF_DEFS_TABLE_SIZE () / 4);
- iv_ref_table = XRESIZEVEC (struct rtx_iv *, iv_ref_table, new_size);
+ iv_ref_table = XRESIZEVEC (class rtx_iv *, iv_ref_table, new_size);
memset (&iv_ref_table[iv_ref_table_size], 0,
- (new_size - iv_ref_table_size) * sizeof (struct rtx_iv *));
+ (new_size - iv_ref_table_size) * sizeof (class rtx_iv *));
iv_ref_table_size = new_size;
}
}
@@ -244,7 +245,7 @@ static void
clear_iv_info (void)
{
unsigned i, n_defs = DF_DEFS_TABLE_SIZE ();
- struct rtx_iv *iv;
+ class rtx_iv *iv;
check_iv_ref_table_size ();
for (i = 0; i < n_defs; i++)
@@ -264,7 +265,7 @@ clear_iv_info (void)
/* Prepare the data for an induction variable analysis of a LOOP. */
void
-iv_analysis_loop_init (struct loop *loop)
+iv_analysis_loop_init (class loop *loop)
{
current_loop = loop;
@@ -302,7 +303,7 @@ latch_dominating_def (rtx reg, df_ref *def)
{
df_ref single_rd = NULL, adef;
unsigned regno = REGNO (reg);
- struct df_rd_bb_info *bb_info = DF_RD_BB_INFO (current_loop->latch);
+ class df_rd_bb_info *bb_info = DF_RD_BB_INFO (current_loop->latch);
for (adef = DF_REG_DEF_CHAIN (regno); adef; adef = DF_REF_NEXT_REG (adef))
{
@@ -385,7 +386,7 @@ iv_get_reaching_def (rtx_insn *insn, rtx reg, df_ref *def)
consistency with other iv manipulation functions that may fail). */
static bool
-iv_constant (struct rtx_iv *iv, scalar_int_mode mode, rtx cst)
+iv_constant (class rtx_iv *iv, scalar_int_mode mode, rtx cst)
{
iv->mode = mode;
iv->base = cst;
@@ -402,7 +403,7 @@ iv_constant (struct rtx_iv *iv, scalar_int_mode mode, rtx cst)
/* Evaluates application of subreg to MODE on IV. */
static bool
-iv_subreg (struct rtx_iv *iv, scalar_int_mode mode)
+iv_subreg (class rtx_iv *iv, scalar_int_mode mode)
{
/* If iv is invariant, just calculate the new value. */
if (iv->step == const0_rtx
@@ -444,7 +445,7 @@ iv_subreg (struct rtx_iv *iv, scalar_int_mode mode)
/* Evaluates application of EXTEND to MODE on IV. */
static bool
-iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode)
+iv_extend (class rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode)
{
/* If iv is invariant, just calculate the new value. */
if (iv->step == const0_rtx
@@ -482,7 +483,7 @@ iv_extend (struct rtx_iv *iv, enum iv_extend_code extend, scalar_int_mode mode)
/* Evaluates negation of IV. */
static bool
-iv_neg (struct rtx_iv *iv)
+iv_neg (class rtx_iv *iv)
{
if (iv->extend == IV_UNKNOWN_EXTEND)
{
@@ -505,7 +506,7 @@ iv_neg (struct rtx_iv *iv)
/* Evaluates addition or subtraction (according to OP) of IV1 to IV0. */
static bool
-iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op)
+iv_add (class rtx_iv *iv0, class rtx_iv *iv1, enum rtx_code op)
{
scalar_int_mode mode;
rtx arg;
@@ -575,7 +576,7 @@ iv_add (struct rtx_iv *iv0, struct rtx_iv *iv1, enum rtx_code op)
/* Evaluates multiplication of IV by constant CST. */
static bool
-iv_mult (struct rtx_iv *iv, rtx mby)
+iv_mult (class rtx_iv *iv, rtx mby)
{
scalar_int_mode mode = iv->extend_mode;
@@ -600,7 +601,7 @@ iv_mult (struct rtx_iv *iv, rtx mby)
/* Evaluates shift of IV by constant CST. */
static bool
-iv_shift (struct rtx_iv *iv, rtx mby)
+iv_shift (class rtx_iv *iv, rtx mby)
{
scalar_int_mode mode = iv->extend_mode;
@@ -810,9 +811,9 @@ get_biv_step (df_ref last_def, scalar_int_mode outer_mode, rtx reg,
/* Records information that DEF is induction variable IV. */
static void
-record_iv (df_ref def, struct rtx_iv *iv)
+record_iv (df_ref def, class rtx_iv *iv)
{
- struct rtx_iv *recorded_iv = XNEW (struct rtx_iv);
+ class rtx_iv *recorded_iv = XNEW (class rtx_iv);
*recorded_iv = *iv;
check_iv_ref_table_size ();
@@ -823,9 +824,9 @@ record_iv (df_ref def, struct rtx_iv *iv)
IV and return true. Otherwise return false. */
static bool
-analyzed_for_bivness_p (rtx def, struct rtx_iv *iv)
+analyzed_for_bivness_p (rtx def, class rtx_iv *iv)
{
- struct biv_entry *biv = bivs->find_with_hash (def, REGNO (def));
+ class biv_entry *biv = bivs->find_with_hash (def, REGNO (def));
if (!biv)
return false;
@@ -835,9 +836,9 @@ analyzed_for_bivness_p (rtx def, struct rtx_iv *iv)
}
static void
-record_biv (rtx def, struct rtx_iv *iv)
+record_biv (rtx def, class rtx_iv *iv)
{
- struct biv_entry *biv = XNEW (struct biv_entry);
+ class biv_entry *biv = XNEW (class biv_entry);
biv_entry **slot = bivs->find_slot_with_hash (def, REGNO (def), INSERT);
biv->regno = REGNO (def);
@@ -850,7 +851,7 @@ record_biv (rtx def, struct rtx_iv *iv)
to *IV. OUTER_MODE is the mode of DEF. */
static bool
-iv_analyze_biv (scalar_int_mode outer_mode, rtx def, struct rtx_iv *iv)
+iv_analyze_biv (scalar_int_mode outer_mode, rtx def, class rtx_iv *iv)
{
rtx inner_step, outer_step;
scalar_int_mode inner_mode;
@@ -928,11 +929,11 @@ iv_analyze_biv (scalar_int_mode outer_mode, rtx def, struct rtx_iv *iv)
bool
iv_analyze_expr (rtx_insn *insn, scalar_int_mode mode, rtx rhs,
- struct rtx_iv *iv)
+ class rtx_iv *iv)
{
rtx mby = NULL_RTX;
rtx op0 = NULL_RTX, op1 = NULL_RTX;
- struct rtx_iv iv0, iv1;
+ class rtx_iv iv0, iv1;
enum rtx_code code = GET_CODE (rhs);
scalar_int_mode omode = mode;
@@ -1039,7 +1040,7 @@ iv_analyze_expr (rtx_insn *insn, scalar_int_mode mode, rtx rhs,
/* Analyzes iv DEF and stores the result to *IV. */
static bool
-iv_analyze_def (df_ref def, struct rtx_iv *iv)
+iv_analyze_def (df_ref def, class rtx_iv *iv)
{
rtx_insn *insn = DF_REF_INSN (def);
rtx reg = DF_REF_REG (def);
@@ -1103,7 +1104,7 @@ iv_analyze_def (df_ref def, struct rtx_iv *iv)
mode of OP. */
static bool
-iv_analyze_op (rtx_insn *insn, scalar_int_mode mode, rtx op, struct rtx_iv *iv)
+iv_analyze_op (rtx_insn *insn, scalar_int_mode mode, rtx op, class rtx_iv *iv)
{
df_ref def = NULL;
enum iv_grd_result res;
@@ -1164,7 +1165,7 @@ iv_analyze_op (rtx_insn *insn, scalar_int_mode mode, rtx op, struct rtx_iv *iv)
mode of VAL. */
bool
-iv_analyze (rtx_insn *insn, scalar_int_mode mode, rtx val, struct rtx_iv *iv)
+iv_analyze (rtx_insn *insn, scalar_int_mode mode, rtx val, class rtx_iv *iv)
{
rtx reg;
@@ -1189,7 +1190,7 @@ iv_analyze (rtx_insn *insn, scalar_int_mode mode, rtx val, struct rtx_iv *iv)
/* Analyzes definition of DEF in INSN and stores the result to IV. */
bool
-iv_analyze_result (rtx_insn *insn, rtx def, struct rtx_iv *iv)
+iv_analyze_result (rtx_insn *insn, rtx def, class rtx_iv *iv)
{
df_ref adef;
@@ -1209,7 +1210,7 @@ iv_analyze_result (rtx_insn *insn, rtx def, struct rtx_iv *iv)
bool
biv_p (rtx_insn *insn, scalar_int_mode mode, rtx reg)
{
- struct rtx_iv iv;
+ class rtx_iv iv;
df_ref def, last_def;
if (!simple_reg_p (reg))
@@ -1231,7 +1232,7 @@ biv_p (rtx_insn *insn, scalar_int_mode mode, rtx reg)
/* Calculates value of IV at ITERATION-th iteration. */
rtx
-get_iv_value (struct rtx_iv *iv, rtx iteration)
+get_iv_value (class rtx_iv *iv, rtx iteration)
{
rtx val;
@@ -1850,7 +1851,7 @@ eliminate_implied_conditions (enum rtx_code op, rtx *head, rtx tail)
is a list, its elements are assumed to be combined using OP. */
static void
-simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
+simplify_using_initial_values (class loop *loop, enum rtx_code op, rtx *expr)
{
bool expression_valid;
rtx head, tail, last_valid_expr;
@@ -2071,8 +2072,8 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
is SIGNED_P to DESC. */
static void
-shorten_into_mode (struct rtx_iv *iv, scalar_int_mode mode,
- enum rtx_code cond, bool signed_p, struct niter_desc *desc)
+shorten_into_mode (class rtx_iv *iv, scalar_int_mode mode,
+ enum rtx_code cond, bool signed_p, class niter_desc *desc)
{
rtx mmin, mmax, cond_over, cond_under;
@@ -2130,8 +2131,8 @@ shorten_into_mode (struct rtx_iv *iv, scalar_int_mode mode,
some assumptions to DESC). */
static bool
-canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1,
- enum rtx_code cond, struct niter_desc *desc)
+canonicalize_iv_subregs (class rtx_iv *iv0, class rtx_iv *iv1,
+ enum rtx_code cond, class niter_desc *desc)
{
scalar_int_mode comp_mode;
bool signed_p;
@@ -2246,7 +2247,7 @@ canonicalize_iv_subregs (struct rtx_iv *iv0, struct rtx_iv *iv1,
expression for the number of iterations, before we tried to simplify it. */
static uint64_t
-determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
+determine_max_iter (class loop *loop, class niter_desc *desc, rtx old_niter)
{
rtx niter = desc->niter_expr;
rtx mmin, mmax, cmp;
@@ -2304,11 +2305,11 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
(basically its rtl version), complicated by things like subregs. */
static void
-iv_number_of_iterations (struct loop *loop, rtx_insn *insn, rtx condition,
- struct niter_desc *desc)
+iv_number_of_iterations (class loop *loop, rtx_insn *insn, rtx condition,
+ class niter_desc *desc)
{
rtx op0, op1, delta, step, bound, may_xform, tmp, tmp0, tmp1;
- struct rtx_iv iv0, iv1;
+ class rtx_iv iv0, iv1;
rtx assumption, may_not_xform;
enum rtx_code cond;
machine_mode nonvoid_mode;
@@ -2866,7 +2867,7 @@ fail:
into DESC. */
static void
-check_simple_exit (struct loop *loop, edge e, struct niter_desc *desc)
+check_simple_exit (class loop *loop, edge e, class niter_desc *desc)
{
basic_block exit_bb;
rtx condition;
@@ -2914,12 +2915,12 @@ check_simple_exit (struct loop *loop, edge e, struct niter_desc *desc)
/* Finds a simple exit of LOOP and stores its description into DESC. */
void
-find_simple_exit (struct loop *loop, struct niter_desc *desc)
+find_simple_exit (class loop *loop, class niter_desc *desc)
{
unsigned i;
basic_block *body;
edge e;
- struct niter_desc act;
+ class niter_desc act;
bool any = false;
edge_iterator ei;
@@ -3017,10 +3018,10 @@ find_simple_exit (struct loop *loop, struct niter_desc *desc)
/* Creates a simple loop description of LOOP if it was not computed
already. */
-struct niter_desc *
-get_simple_loop_desc (struct loop *loop)
+class niter_desc *
+get_simple_loop_desc (class loop *loop)
{
- struct niter_desc *desc = simple_loop_desc (loop);
+ class niter_desc *desc = simple_loop_desc (loop);
if (desc)
return desc;
@@ -3037,9 +3038,9 @@ get_simple_loop_desc (struct loop *loop)
/* Releases simple loop description for LOOP. */
void
-free_simple_loop_desc (struct loop *loop)
+free_simple_loop_desc (class loop *loop)
{
- struct niter_desc *desc = simple_loop_desc (loop);
+ class niter_desc *desc = simple_loop_desc (loop);
if (!desc)
return;
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 1b4c73b..63fccd2 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -163,19 +163,19 @@ struct opt_info
basic_block loop_preheader; /* The loop preheader basic block. */
};
-static void decide_unroll_stupid (struct loop *, int);
-static void decide_unroll_constant_iterations (struct loop *, int);
-static void decide_unroll_runtime_iterations (struct loop *, int);
-static void unroll_loop_stupid (struct loop *);
+static void decide_unroll_stupid (class loop *, int);
+static void decide_unroll_constant_iterations (class loop *, int);
+static void decide_unroll_runtime_iterations (class loop *, int);
+static void unroll_loop_stupid (class loop *);
static void decide_unrolling (int);
-static void unroll_loop_constant_iterations (struct loop *);
-static void unroll_loop_runtime_iterations (struct loop *);
-static struct opt_info *analyze_insns_in_loop (struct loop *);
+static void unroll_loop_constant_iterations (class loop *);
+static void unroll_loop_runtime_iterations (class loop *);
+static struct opt_info *analyze_insns_in_loop (class loop *);
static void opt_info_start_duplication (struct opt_info *);
static void apply_opt_in_copies (struct opt_info *, unsigned, bool, bool);
static void free_opt_info (struct opt_info *);
-static struct var_to_expand *analyze_insn_to_expand_var (struct loop*, rtx_insn *);
-static bool referenced_in_one_insn_in_loop_p (struct loop *, rtx, int *);
+static struct var_to_expand *analyze_insn_to_expand_var (class loop*, rtx_insn *);
+static bool referenced_in_one_insn_in_loop_p (class loop *, rtx, int *);
static struct iv_to_split *analyze_iv_to_split_insn (rtx_insn *);
static void expand_var_during_unrolling (struct var_to_expand *, rtx_insn *);
static void insert_var_expansion_initialization (struct var_to_expand *,
@@ -189,7 +189,7 @@ static rtx get_expansion (struct var_to_expand *);
appropriate given the dump or -fopt-info settings. */
static void
-report_unroll (struct loop *loop, dump_location_t locus)
+report_unroll (class loop *loop, dump_location_t locus)
{
dump_flags_t report_flags = MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS;
@@ -215,7 +215,7 @@ report_unroll (struct loop *loop, dump_location_t locus)
static void
decide_unrolling (int flags)
{
- struct loop *loop;
+ class loop *loop;
/* Scan the loops, inner ones first. */
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
@@ -279,7 +279,7 @@ decide_unrolling (int flags)
void
unroll_loops (int flags)
{
- struct loop *loop;
+ class loop *loop;
bool changed = false;
/* Now decide rest of unrolling. */
@@ -322,9 +322,9 @@ unroll_loops (int flags)
/* Check whether exit of the LOOP is at the end of loop body. */
static bool
-loop_exit_at_end_p (struct loop *loop)
+loop_exit_at_end_p (class loop *loop)
{
- struct niter_desc *desc = get_simple_loop_desc (loop);
+ class niter_desc *desc = get_simple_loop_desc (loop);
rtx_insn *insn;
/* We should never have conditional in latch block. */
@@ -347,10 +347,10 @@ loop_exit_at_end_p (struct loop *loop)
and how much. */
static void
-decide_unroll_constant_iterations (struct loop *loop, int flags)
+decide_unroll_constant_iterations (class loop *loop, int flags)
{
unsigned nunroll, nunroll_by_av, best_copies, best_unroll = 0, n_copies, i;
- struct niter_desc *desc;
+ class niter_desc *desc;
widest_int iterations;
/* If we were not asked to unroll this loop, just return back silently. */
@@ -480,14 +480,14 @@ decide_unroll_constant_iterations (struct loop *loop, int flags)
}
*/
static void
-unroll_loop_constant_iterations (struct loop *loop)
+unroll_loop_constant_iterations (class loop *loop)
{
unsigned HOST_WIDE_INT niter;
unsigned exit_mod;
unsigned i;
edge e;
unsigned max_unroll = loop->lpt_decision.times;
- struct niter_desc *desc = get_simple_loop_desc (loop);
+ class niter_desc *desc = get_simple_loop_desc (loop);
bool exit_at_end = loop_exit_at_end_p (loop);
struct opt_info *opt_info = NULL;
bool ok;
@@ -667,10 +667,10 @@ unroll_loop_constant_iterations (struct loop *loop)
/* Decide whether to unroll LOOP iterating runtime computable number of times
and how much. */
static void
-decide_unroll_runtime_iterations (struct loop *loop, int flags)
+decide_unroll_runtime_iterations (class loop *loop, int flags)
{
unsigned nunroll, nunroll_by_av, i;
- struct niter_desc *desc;
+ class niter_desc *desc;
widest_int iterations;
/* If we were not asked to unroll this loop, just return back silently. */
@@ -881,7 +881,7 @@ compare_and_jump_seq (rtx op0, rtx op1, enum rtx_code comp,
}
*/
static void
-unroll_loop_runtime_iterations (struct loop *loop)
+unroll_loop_runtime_iterations (class loop *loop)
{
rtx old_niter, niter, tmp;
rtx_insn *init_code, *branch_code;
@@ -894,7 +894,7 @@ unroll_loop_runtime_iterations (struct loop *loop)
edge e;
bool extra_zero_check, last_may_exit;
unsigned max_unroll = loop->lpt_decision.times;
- struct niter_desc *desc = get_simple_loop_desc (loop);
+ class niter_desc *desc = get_simple_loop_desc (loop);
bool exit_at_end = loop_exit_at_end_p (loop);
struct opt_info *opt_info = NULL;
bool ok;
@@ -1152,10 +1152,10 @@ unroll_loop_runtime_iterations (struct loop *loop)
/* Decide whether to unroll LOOP stupidly and how much. */
static void
-decide_unroll_stupid (struct loop *loop, int flags)
+decide_unroll_stupid (class loop *loop, int flags)
{
unsigned nunroll, nunroll_by_av, i;
- struct niter_desc *desc;
+ class niter_desc *desc;
widest_int iterations;
/* If we were not asked to unroll this loop, just return back silently. */
@@ -1250,10 +1250,10 @@ decide_unroll_stupid (struct loop *loop, int flags)
}
*/
static void
-unroll_loop_stupid (struct loop *loop)
+unroll_loop_stupid (class loop *loop)
{
unsigned nunroll = loop->lpt_decision.times;
- struct niter_desc *desc = get_simple_loop_desc (loop);
+ class niter_desc *desc = get_simple_loop_desc (loop);
struct opt_info *opt_info = NULL;
bool ok;
@@ -1301,7 +1301,7 @@ unroll_loop_stupid (struct loop *loop)
variable. */
static bool
-referenced_in_one_insn_in_loop_p (struct loop *loop, rtx reg,
+referenced_in_one_insn_in_loop_p (class loop *loop, rtx reg,
int *debug_uses)
{
basic_block *body, bb;
@@ -1329,7 +1329,7 @@ referenced_in_one_insn_in_loop_p (struct loop *loop, rtx reg,
/* Reset the DEBUG_USES debug insns in LOOP that reference REG. */
static void
-reset_debug_uses_in_loop (struct loop *loop, rtx reg, int debug_uses)
+reset_debug_uses_in_loop (class loop *loop, rtx reg, int debug_uses)
{
basic_block *body, bb;
unsigned i;
@@ -1378,7 +1378,7 @@ reset_debug_uses_in_loop (struct loop *loop, rtx reg, int debug_uses)
*/
static struct var_to_expand *
-analyze_insn_to_expand_var (struct loop *loop, rtx_insn *insn)
+analyze_insn_to_expand_var (class loop *loop, rtx_insn *insn)
{
rtx set, dest, src;
struct var_to_expand *ves;
@@ -1519,7 +1519,7 @@ static struct iv_to_split *
analyze_iv_to_split_insn (rtx_insn *insn)
{
rtx set, dest;
- struct rtx_iv iv;
+ class rtx_iv iv;
struct iv_to_split *ivts;
scalar_int_mode mode;
bool ok;
@@ -1571,7 +1571,7 @@ analyze_iv_to_split_insn (rtx_insn *insn)
is undefined for the return value. */
static struct opt_info *
-analyze_insns_in_loop (struct loop *loop)
+analyze_insns_in_loop (class loop *loop)
{
basic_block *body, bb;
unsigned i;
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 4f68a73..e1418e5 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -1801,7 +1801,8 @@ public:
{}
/* opt_pass methods: */
- virtual bool gate (function *) { return flag_split_wide_types != 0; }
+ virtual bool gate (function *) { return flag_split_wide_types
+ && flag_split_wide_types_early; }
virtual unsigned int execute (function *)
{
decompose_multiword_subregs (true);
@@ -1817,3 +1818,46 @@ make_pass_lower_subreg2 (gcc::context *ctxt)
{
return new pass_lower_subreg2 (ctxt);
}
+
+/* Implement third lower subreg pass. */
+
+namespace {
+
+const pass_data pass_data_lower_subreg3 =
+{
+ RTL_PASS, /* type */
+ "subreg3", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_LOWER_SUBREG, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_df_finish, /* todo_flags_finish */
+};
+
+class pass_lower_subreg3 : public rtl_opt_pass
+{
+public:
+ pass_lower_subreg3 (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_lower_subreg3, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *) { return flag_split_wide_types
+ && !flag_split_wide_types_early; }
+ virtual unsigned int execute (function *)
+ {
+ decompose_multiword_subregs (true);
+ return 0;
+ }
+
+}; // class pass_lower_subreg3
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_lower_subreg3 (gcc::context *ctxt)
+{
+ return new pass_lower_subreg3 (ctxt);
+}
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index d1d99e0..55d8d13 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -2172,8 +2172,9 @@ process_alt_operands (int only_alternative)
else
{
/* Operands don't match. If the operands are
- different user defined explicit hard registers,
- then we cannot make them match. */
+ different user defined explicit hard
+ registers, then we cannot make them match
+ when one is early clobber operand. */
if ((REG_P (*curr_id->operand_loc[nop])
|| SUBREG_P (*curr_id->operand_loc[nop]))
&& (REG_P (*curr_id->operand_loc[m])
@@ -2192,9 +2193,17 @@ process_alt_operands (int only_alternative)
&& REG_P (m_reg)
&& HARD_REGISTER_P (m_reg)
&& REG_USERVAR_P (m_reg))
- break;
+ {
+ int i;
+
+ for (i = 0; i < early_clobbered_regs_num; i++)
+ if (m == early_clobbered_nops[i])
+ break;
+ if (i < early_clobbered_regs_num
+ || early_clobber_p)
+ break;
+ }
}
-
/* Both operands must allow a reload register,
otherwise we cannot make them match. */
if (curr_alt[m] == NO_REGS)
diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index 051839a..943da88 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -71,8 +71,9 @@ along with GCC; see the file COPYING3. If not see
/* This structure is used to record information about hard register
eliminations. */
-struct lra_elim_table
+class lra_elim_table
{
+public:
/* Hard register number to be eliminated. */
int from;
/* Hard register number used as replacement. */
@@ -99,7 +100,7 @@ struct lra_elim_table
of eliminating a register in favor of another. If there is more
than one way of eliminating a particular register, the most
preferred should be specified first. */
-static struct lra_elim_table *reg_eliminate = 0;
+static class lra_elim_table *reg_eliminate = 0;
/* This is an intermediate structure to initialize the table. It has
exactly the members provided by ELIMINABLE_REGS. */
@@ -117,7 +118,7 @@ static const struct elim_table_1
static void
print_elim_table (FILE *f)
{
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
{
@@ -141,7 +142,7 @@ lra_debug_elim_table (void)
VALUE. Setup FRAME_POINTER_NEEDED if elimination from frame
pointer to stack pointer is not possible anymore. */
static void
-setup_can_eliminate (struct lra_elim_table *ep, bool value)
+setup_can_eliminate (class lra_elim_table *ep, bool value)
{
ep->can_eliminate = ep->prev_can_eliminate = value;
if (! value
@@ -155,12 +156,12 @@ setup_can_eliminate (struct lra_elim_table *ep, bool value)
or NULL if none. The elimination table may contain more than
one elimination for the same hard register, but this map specifies
the one that we are currently using. */
-static struct lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
+static class lra_elim_table *elimination_map[FIRST_PSEUDO_REGISTER];
/* When an eliminable hard register becomes not eliminable, we use the
following special structure to restore original offsets for the
register. */
-static struct lra_elim_table self_elim_table;
+static class lra_elim_table self_elim_table;
/* Offsets should be used to restore original offsets for eliminable
hard register which just became not eliminable. Zero,
@@ -176,7 +177,7 @@ static void
setup_elimination_map (void)
{
int i;
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
elimination_map[i] = NULL;
@@ -241,7 +242,7 @@ form_sum (rtx x, rtx y)
int
lra_get_elimination_hard_regno (int hard_regno)
{
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
return hard_regno;
@@ -252,11 +253,11 @@ lra_get_elimination_hard_regno (int hard_regno)
/* Return elimination which will be used for hard reg REG, NULL
otherwise. */
-static struct lra_elim_table *
+static class lra_elim_table *
get_elimination (rtx reg)
{
int hard_regno;
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
lra_assert (REG_P (reg));
if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
@@ -333,7 +334,7 @@ lra_eliminate_regs_1 (rtx_insn *insn, rtx x, machine_mode mem_mode,
poly_int64 update_sp_offset, bool full_p)
{
enum rtx_code code = GET_CODE (x);
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
rtx new_rtx;
int i, j;
const char *fmt;
@@ -730,7 +731,7 @@ static void
mark_not_eliminable (rtx x, machine_mode mem_mode)
{
enum rtx_code code = GET_CODE (x);
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
int i, j;
const char *fmt;
poly_int64 offset = 0;
@@ -900,7 +901,7 @@ eliminate_regs_in_insn (rtx_insn *insn, bool replace_p, bool first_p,
int i;
rtx substed_operand[MAX_RECOG_OPERANDS];
rtx orig_operand[MAX_RECOG_OPERANDS];
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
rtx plus_src, plus_cst_src;
lra_insn_recog_data_t id;
struct lra_static_insn_data *static_id;
@@ -1108,7 +1109,7 @@ static bool
update_reg_eliminate (bitmap insns_with_changed_offsets)
{
bool prev, result;
- struct lra_elim_table *ep, *ep1;
+ class lra_elim_table *ep, *ep1;
HARD_REG_SET temp_hard_reg_set;
targetm.compute_frame_layout ();
@@ -1213,12 +1214,12 @@ update_reg_eliminate (bitmap insns_with_changed_offsets)
static void
init_elim_table (void)
{
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
bool value_p;
const struct elim_table_1 *ep1;
if (!reg_eliminate)
- reg_eliminate = XCNEWVEC (struct lra_elim_table, NUM_ELIMINABLE_REGS);
+ reg_eliminate = XCNEWVEC (class lra_elim_table, NUM_ELIMINABLE_REGS);
memset (self_elim_offsets, 0, sizeof (self_elim_offsets));
/* Initiate member values which will be never changed. */
@@ -1261,7 +1262,7 @@ init_elimination (void)
bool stop_to_sp_elimination_p;
basic_block bb;
rtx_insn *insn;
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
init_elim_table ();
FOR_EACH_BB_FN (bb, cfun)
@@ -1295,7 +1296,7 @@ void
lra_eliminate_reg_if_possible (rtx *loc)
{
int regno;
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
lra_assert (REG_P (*loc));
if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
@@ -1339,7 +1340,7 @@ lra_eliminate (bool final_p, bool first_p)
unsigned int uid;
bitmap_head insns_with_changed_offsets;
bitmap_iterator bi;
- struct lra_elim_table *ep;
+ class lra_elim_table *ep;
gcc_assert (! final_p || ! first_p);
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index d0a8fac..f8db969 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -64,8 +64,9 @@ struct lra_copy
};
/* Common info about a register (pseudo or hard register). */
-struct lra_reg
+class lra_reg
{
+public:
/* Bitmap of UIDs of insns (including debug insns) referring the
reg. */
bitmap_head insn_bitmap;
@@ -118,7 +119,7 @@ struct lra_reg
};
/* References to the common info about each register. */
-extern struct lra_reg *lra_reg_info;
+extern class lra_reg *lra_reg_info;
extern HARD_REG_SET hard_regs_spilled_into;
@@ -210,8 +211,9 @@ struct lra_static_insn_data
/* LRA internal info about an insn (LRA internal insn
representation). */
-struct lra_insn_recog_data
+class lra_insn_recog_data
{
+public:
/* The insn code. */
int icode;
/* The alternative should be used for the insn, LRA_UNKNOWN_ALT if
@@ -242,7 +244,7 @@ struct lra_insn_recog_data
struct lra_insn_reg *regs;
};
-typedef struct lra_insn_recog_data *lra_insn_recog_data_t;
+typedef class lra_insn_recog_data *lra_insn_recog_data_t;
/* Whether the clobber is used temporary in LRA. */
#define LRA_TEMP_CLOBBER_P(x) \
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index 55b2adc..96aa7c4 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -384,8 +384,9 @@ mark_regno_dead (int regno, machine_mode mode)
/* Structure describing local BB data used for pseudo
live-analysis. */
-struct bb_data_pseudos
+class bb_data_pseudos
{
+public:
/* Basic block about which the below data are. */
basic_block bb;
bitmap_head killed_pseudos; /* pseudos killed in the BB. */
@@ -393,7 +394,7 @@ struct bb_data_pseudos
};
/* Array for all BB data. Indexed by the corresponding BB index. */
-typedef struct bb_data_pseudos *bb_data_t;
+typedef class bb_data_pseudos *bb_data_t;
/* All basic block data are referred through the following array. */
static bb_data_t bb_data;
@@ -469,7 +470,7 @@ initiate_live_solver (void)
{
bitmap_initialize (&all_hard_regs_bitmap, &reg_obstack);
bitmap_set_range (&all_hard_regs_bitmap, 0, FIRST_PSEUDO_REGISTER);
- bb_data = XNEWVEC (struct bb_data_pseudos, last_basic_block_for_fn (cfun));
+ bb_data = XNEWVEC (class bb_data_pseudos, last_basic_block_for_fn (cfun));
bitmap_initialize (&all_blocks, &reg_obstack);
basic_block bb;
diff --git a/gcc/lra-remat.c b/gcc/lra-remat.c
index 1083811..6a5bf4f 100644
--- a/gcc/lra-remat.c
+++ b/gcc/lra-remat.c
@@ -124,8 +124,9 @@ static cand_t *regno_cands;
/* Data about basic blocks used for the rematerialization
sub-pass. */
-struct remat_bb_data
+class remat_bb_data
{
+public:
/* Basic block about which the below data are. */
basic_block bb;
/* Registers changed in the basic block: */
@@ -144,7 +145,7 @@ struct remat_bb_data
};
/* Array for all BB data. Indexed by the corresponding BB index. */
-typedef struct remat_bb_data *remat_bb_data_t;
+typedef class remat_bb_data *remat_bb_data_t;
/* Basic blocks for data flow problems -- all bocks except the special
ones. */
@@ -509,7 +510,7 @@ create_remat_bb_data (void)
basic_block bb;
remat_bb_data_t bb_info;
- remat_bb_data = XNEWVEC (struct remat_bb_data,
+ remat_bb_data = XNEWVEC (class remat_bb_data,
last_basic_block_for_fn (cfun));
FOR_ALL_BB_FN (bb, cfun)
{
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index c19b76a..c73d501 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -97,8 +97,9 @@ static struct pseudo_slot *pseudo_slots;
/* The structure describes a register or a stack slot which can be
used for several spilled pseudos. */
-struct slot
+class slot
{
+public:
/* First pseudo with given stack slot. */
int regno;
/* Hard reg into which the slot pseudos are spilled. The value is
@@ -121,7 +122,7 @@ struct slot
/* Array containing info about the stack slots. The array element is
indexed by the stack slot number in the range [0..slots_num). */
-static struct slot *slots;
+static class slot *slots;
/* The number of the stack slots currently existing. */
static int slots_num;
@@ -586,7 +587,7 @@ lra_spill (void)
spill_hard_reg[i] = NULL_RTX;
pseudo_slots[i].mem = NULL_RTX;
}
- slots = XNEWVEC (struct slot, regs_num);
+ slots = XNEWVEC (class slot, regs_num);
/* Sort regnos according their usage frequencies. */
qsort (pseudo_regnos, n, sizeof (int), regno_freq_compare);
n = assign_spill_hard_regs (pseudo_regnos, n);
diff --git a/gcc/lra.c b/gcc/lra.c
index 982a3cc..af40f43 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -972,7 +972,7 @@ lra_set_insn_recog_data (rtx_insn *insn)
/* It might be a new simple insn which is not recognized yet. */
INSN_CODE (insn) = icode = recog_memoized (insn);
}
- data = XNEW (struct lra_insn_recog_data);
+ data = XNEW (class lra_insn_recog_data);
lra_insn_recog_data[uid] = data;
data->insn = insn;
data->used_insn_alternative = LRA_UNKNOWN_ALT;
@@ -1306,7 +1306,7 @@ lra_set_used_insn_alternative_by_uid (int uid, int alt)
/* The size of the following array. */
static int reg_info_size;
/* Common info about each register. */
-struct lra_reg *lra_reg_info;
+class lra_reg *lra_reg_info;
HARD_REG_SET hard_regs_spilled_into;
@@ -1356,7 +1356,7 @@ init_reg_info (void)
last_reg_value = 0;
reg_info_size = max_reg_num () * 3 / 2 + 1;
- lra_reg_info = XNEWVEC (struct lra_reg, reg_info_size);
+ lra_reg_info = XNEWVEC (class lra_reg, reg_info_size);
for (i = 0; i < reg_info_size; i++)
initialize_lra_reg_info_element (i);
copy_vec.truncate (0);
@@ -1385,7 +1385,7 @@ expand_reg_info (void)
if (reg_info_size > max_reg_num ())
return;
reg_info_size = max_reg_num () * 3 / 2 + 1;
- lra_reg_info = XRESIZEVEC (struct lra_reg, lra_reg_info, reg_info_size);
+ lra_reg_info = XRESIZEVEC (class lra_reg, lra_reg_info, reg_info_size);
for (i = old; i < reg_info_size; i++)
initialize_lra_reg_info_element (i);
}
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 4dfa286..bc0f010 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -1012,7 +1012,7 @@ output_symtab (void)
/* Return identifier encoded in IB as a plain string. */
static tree
-read_identifier (struct lto_input_block *ib)
+read_identifier (class lto_input_block *ib)
{
unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
tree id;
@@ -1032,7 +1032,7 @@ read_identifier (struct lto_input_block *ib)
/* Return string encoded in IB, NULL if string is empty. */
static const char *
-read_string (struct lto_input_block *ib)
+read_string (class lto_input_block *ib)
{
unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
const char *str;
@@ -1203,7 +1203,7 @@ get_alias_symbol (tree decl)
static struct cgraph_node *
input_node (struct lto_file_decl_data *file_data,
- struct lto_input_block *ib,
+ class lto_input_block *ib,
enum LTO_symtab_tags tag,
vec<symtab_node *> nodes)
{
@@ -1326,7 +1326,7 @@ input_node (struct lto_file_decl_data *file_data,
static varpool_node *
input_varpool_node (struct lto_file_decl_data *file_data,
- struct lto_input_block *ib)
+ class lto_input_block *ib)
{
int decl_index;
tree var_decl;
@@ -1402,7 +1402,7 @@ input_varpool_node (struct lto_file_decl_data *file_data,
Return the node read or overwriten. */
static void
-input_ref (struct lto_input_block *ib,
+input_ref (class lto_input_block *ib,
symtab_node *referring_node,
vec<symtab_node *> nodes)
{
@@ -1428,7 +1428,7 @@ input_ref (struct lto_input_block *ib,
indirect_unknown_callee set). */
static void
-input_edge (struct lto_input_block *ib, vec<symtab_node *> nodes,
+input_edge (class lto_input_block *ib, vec<symtab_node *> nodes,
bool indirect)
{
struct cgraph_node *caller, *callee;
@@ -1496,7 +1496,7 @@ input_edge (struct lto_input_block *ib, vec<symtab_node *> nodes,
static vec<symtab_node *>
input_cgraph_1 (struct lto_file_decl_data *file_data,
- struct lto_input_block *ib)
+ class lto_input_block *ib)
{
enum LTO_symtab_tags tag;
vec<symtab_node *> nodes = vNULL;
@@ -1573,7 +1573,7 @@ input_cgraph_1 (struct lto_file_decl_data *file_data,
/* Input ipa_refs. */
static void
-input_refs (struct lto_input_block *ib,
+input_refs (class lto_input_block *ib,
vec<symtab_node *> nodes)
{
int count;
@@ -1596,7 +1596,7 @@ input_refs (struct lto_input_block *ib,
/* Input profile_info from IB. */
static void
-input_profile_summary (struct lto_input_block *ib,
+input_profile_summary (class lto_input_block *ib,
struct lto_file_decl_data *file_data)
{
unsigned int runs = streamer_read_uhwi (ib);
@@ -1693,7 +1693,7 @@ input_symtab (void)
{
const char *data;
size_t len;
- struct lto_input_block *ib;
+ class lto_input_block *ib;
vec<symtab_node *> nodes;
ib = lto_create_simple_input_block (file_data, LTO_section_symtab_nodes,
@@ -1750,7 +1750,7 @@ input_offload_tables (bool do_force_output)
{
const char *data;
size_t len;
- struct lto_input_block *ib
+ class lto_input_block *ib
= lto_create_simple_input_block (file_data, LTO_section_offload_table,
&data, &len);
if (!ib)
@@ -1909,7 +1909,7 @@ output_cgraph_opt_summary (void)
static void
input_edge_opt_summary (struct cgraph_edge *edge ATTRIBUTE_UNUSED,
- struct lto_input_block *ib_main ATTRIBUTE_UNUSED)
+ class lto_input_block *ib_main ATTRIBUTE_UNUSED)
{
}
@@ -1917,8 +1917,8 @@ input_edge_opt_summary (struct cgraph_edge *edge ATTRIBUTE_UNUSED,
static void
input_node_opt_summary (struct cgraph_node *node,
- struct lto_input_block *ib_main,
- struct data_in *data_in)
+ class lto_input_block *ib_main,
+ class data_in *data_in)
{
int i;
int count;
@@ -1973,7 +1973,7 @@ input_cgraph_opt_section (struct lto_file_decl_data *file_data,
const int cfg_offset = sizeof (struct lto_function_header);
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
- struct data_in *data_in;
+ class data_in *data_in;
unsigned int i;
unsigned int count;
diff --git a/gcc/lto-compress.c b/gcc/lto-compress.c
index b925363..c5c37db 100644
--- a/gcc/lto-compress.c
+++ b/gcc/lto-compress.c
@@ -115,13 +115,10 @@ lto_normalized_zstd_level (void)
{
int level = flag_lto_compression_level;
- if (level != ZSTD_CLEVEL_DEFAULT)
- {
- if (level < 1)
- level = 1;
- else if (level > ZSTD_maxCLevel ())
- level = ZSTD_maxCLevel ();
- }
+ if (level < 0)
+ level = 0;
+ else if (level > ZSTD_maxCLevel ())
+ level = ZSTD_maxCLevel ();
return level;
}
diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c
index 80fdb03..0bdcf62 100644
--- a/gcc/lto-section-in.c
+++ b/gcc/lto-section-in.c
@@ -161,7 +161,8 @@ lto_get_section_data (struct lto_file_decl_data *file_data,
stream = lto_start_uncompression (lto_append_data, &buffer);
lto_uncompress_block (stream, data, *len);
- lto_end_uncompression (stream, file_data->lto_section_header.compression);
+ lto_end_uncompression (stream,
+ file_data->lto_section_header.get_compression ());
*len = buffer.length - header_length;
data = buffer.data + header_length;
@@ -228,7 +229,7 @@ lto_free_raw_section_data (struct lto_file_decl_data *file_data,
raw pointer to the section is returned in DATAR and LEN. These are
used to free the section. Return NULL if the section is not present. */
-struct lto_input_block *
+class lto_input_block *
lto_create_simple_input_block (struct lto_file_decl_data *file_data,
enum lto_section_type section_type,
const char **datar, size_t *len)
@@ -257,7 +258,7 @@ lto_create_simple_input_block (struct lto_file_decl_data *file_data,
void
lto_destroy_simple_input_block (struct lto_file_decl_data *file_data,
enum lto_section_type section_type,
- struct lto_input_block *ib,
+ class lto_input_block *ib,
const char *data, size_t len)
{
delete ib;
@@ -437,7 +438,7 @@ lto_free_function_in_decl_state_for_node (symtab_node *node)
/* Report read pass end of the section. */
void
-lto_section_overrun (struct lto_input_block *ib)
+lto_section_overrun (class lto_input_block *ib)
{
fatal_error (input_location, "bytecode stream: trying to read %d bytes "
"after the end of the input buffer", ib->p - ib->len);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 49fd573..3158edd 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -84,7 +84,7 @@ lto_tag_check_set (enum LTO_tags actual, int ntags, ...)
/* Read LENGTH bytes from STREAM to ADDR. */
void
-lto_input_data_block (struct lto_input_block *ib, void *addr, size_t length)
+lto_input_data_block (class lto_input_block *ib, void *addr, size_t length)
{
size_t i;
unsigned char *const buffer = (unsigned char *) addr;
@@ -232,7 +232,7 @@ lto_location_cache::revert_location_cache ()
void
lto_location_cache::input_location (location_t *loc, struct bitpack_d *bp,
- struct data_in *data_in)
+ class data_in *data_in)
{
static const char *stream_file;
static int stream_line;
@@ -287,7 +287,7 @@ lto_location_cache::input_location (location_t *loc, struct bitpack_d *bp,
void
lto_input_location (location_t *loc, struct bitpack_d *bp,
- struct data_in *data_in)
+ class data_in *data_in)
{
data_in->location_cache.input_location (loc, bp, data_in);
}
@@ -297,7 +297,7 @@ lto_input_location (location_t *loc, struct bitpack_d *bp,
discarded. */
location_t
-stream_input_location_now (struct bitpack_d *bp, struct data_in *data_in)
+stream_input_location_now (struct bitpack_d *bp, class data_in *data_in)
{
location_t loc;
stream_input_location (&loc, bp, data_in);
@@ -313,7 +313,7 @@ stream_input_location_now (struct bitpack_d *bp, struct data_in *data_in)
function scope for the read tree. */
tree
-lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
+lto_input_tree_ref (class lto_input_block *ib, class data_in *data_in,
struct function *fn, enum LTO_tags tag)
{
unsigned HOST_WIDE_INT ix_u;
@@ -378,7 +378,7 @@ lto_input_tree_ref (struct lto_input_block *ib, struct data_in *data_in,
block IB, using descriptors in DATA_IN. */
static struct eh_catch_d *
-lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in,
+lto_input_eh_catch_list (class lto_input_block *ib, class data_in *data_in,
eh_catch *last_p)
{
eh_catch first;
@@ -424,7 +424,7 @@ lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in,
in DATA_IN. */
static eh_region
-input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
+input_eh_region (class lto_input_block *ib, class data_in *data_in, int ix)
{
enum LTO_tags tag;
eh_region r;
@@ -499,7 +499,7 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
in DATA_IN. */
static eh_landing_pad
-input_eh_lp (struct lto_input_block *ib, struct data_in *data_in, int ix)
+input_eh_lp (class lto_input_block *ib, class data_in *data_in, int ix)
{
enum LTO_tags tag;
eh_landing_pad lp;
@@ -603,7 +603,7 @@ lto_init_eh (void)
in DATA_IN. */
static void
-input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
+input_eh_regions (class lto_input_block *ib, class data_in *data_in,
struct function *fn)
{
HOST_WIDE_INT i, root_region, len;
@@ -714,7 +714,7 @@ make_new_block (struct function *fn, unsigned int index)
/* Read the CFG for function FN from input block IB. */
static void
-input_cfg (struct lto_input_block *ib, struct data_in *data_in,
+input_cfg (class lto_input_block *ib, class data_in *data_in,
struct function *fn)
{
unsigned int bb_count;
@@ -807,7 +807,7 @@ input_cfg (struct lto_input_block *ib, struct data_in *data_in,
continue;
}
- struct loop *loop = alloc_loop ();
+ class loop *loop = alloc_loop ();
loop->header = BASIC_BLOCK_FOR_FN (fn, header_index);
loop->header->loop_father = loop;
@@ -847,7 +847,7 @@ input_cfg (struct lto_input_block *ib, struct data_in *data_in,
block IB. */
static void
-input_ssa_names (struct lto_input_block *ib, struct data_in *data_in,
+input_ssa_names (class lto_input_block *ib, class data_in *data_in,
struct function *fn)
{
unsigned int i, size;
@@ -964,8 +964,8 @@ fixup_call_stmt_edges (struct cgraph_node *orig, gimple **stmts)
using input block IB. */
static void
-input_struct_function_base (struct function *fn, struct data_in *data_in,
- struct lto_input_block *ib)
+input_struct_function_base (struct function *fn, class data_in *data_in,
+ class lto_input_block *ib)
{
struct bitpack_d bp;
int len;
@@ -1029,8 +1029,8 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
/* Read the body of function FN_DECL from DATA_IN using input block IB. */
static void
-input_function (tree fn_decl, struct data_in *data_in,
- struct lto_input_block *ib, struct lto_input_block *ib_cfg)
+input_function (tree fn_decl, class data_in *data_in,
+ class lto_input_block *ib, class lto_input_block *ib_cfg)
{
struct function *fn;
enum LTO_tags tag;
@@ -1141,6 +1141,14 @@ input_function (tree fn_decl, struct data_in *data_in,
? !MAY_HAVE_DEBUG_MARKER_STMTS
: !MAY_HAVE_DEBUG_BIND_STMTS))
remove = true;
+ /* In case the linemap overflows locations can be dropped
+ to zero. Thus do not keep nonsensical inline entry markers
+ we'd later ICE on. */
+ tree block;
+ if (gimple_debug_inline_entry_p (stmt)
+ && (block = gimple_block (stmt))
+ && !inlined_function_outer_scope_p (block))
+ remove = true;
if (is_gimple_call (stmt)
&& gimple_call_internal_p (stmt))
{
@@ -1233,8 +1241,8 @@ input_function (tree fn_decl, struct data_in *data_in,
/* Read the body of function FN_DECL from DATA_IN using input block IB. */
static void
-input_constructor (tree var, struct data_in *data_in,
- struct lto_input_block *ib)
+input_constructor (tree var, class data_in *data_in,
+ class lto_input_block *ib)
{
DECL_INITIAL (var) = stream_read_tree (ib, data_in);
}
@@ -1251,7 +1259,7 @@ lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symta
const char *data, enum lto_section_type section_type)
{
const struct lto_function_header *header;
- struct data_in *data_in;
+ class data_in *data_in;
int cfg_offset;
int main_offset;
int string_offset;
@@ -1364,7 +1372,7 @@ vec<dref_entry> dref_queue;
input block IB using the per-file context in DATA_IN. */
static void
-lto_read_tree_1 (struct lto_input_block *ib, struct data_in *data_in, tree expr)
+lto_read_tree_1 (class lto_input_block *ib, class data_in *data_in, tree expr)
{
/* Read all the bitfield values in EXPR. Note that for LTO, we
only write language-independent bitfields, so no more unpacking is
@@ -1402,7 +1410,7 @@ lto_read_tree_1 (struct lto_input_block *ib, struct data_in *data_in, tree expr)
input block IB using the per-file context in DATA_IN. */
static tree
-lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
+lto_read_tree (class lto_input_block *ib, class data_in *data_in,
enum LTO_tags tag, hashval_t hash)
{
/* Instantiate a new tree node. */
@@ -1425,7 +1433,7 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
following in the IB, DATA_IN stream. */
hashval_t
-lto_input_scc (struct lto_input_block *ib, struct data_in *data_in,
+lto_input_scc (class lto_input_block *ib, class data_in *data_in,
unsigned *len, unsigned *entry_len)
{
/* A blob of unnamed tree nodes, fill the cache from it and
@@ -1482,7 +1490,7 @@ lto_input_scc (struct lto_input_block *ib, struct data_in *data_in,
to previously read nodes. */
tree
-lto_input_tree_1 (struct lto_input_block *ib, struct data_in *data_in,
+lto_input_tree_1 (class lto_input_block *ib, class data_in *data_in,
enum LTO_tags tag, hashval_t hash)
{
tree result;
@@ -1532,7 +1540,7 @@ lto_input_tree_1 (struct lto_input_block *ib, struct data_in *data_in,
}
tree
-lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
+lto_input_tree (class lto_input_block *ib, class data_in *data_in)
{
enum LTO_tags tag;
@@ -1564,7 +1572,7 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base)
const struct lto_simple_header_with_strings *header
= (const struct lto_simple_header_with_strings *) data;
int string_offset;
- struct data_in *data_in;
+ class data_in *data_in;
tree str;
if (! data)
@@ -1612,7 +1620,7 @@ lto_input_mode_table (struct lto_file_decl_data *file_data)
const struct lto_simple_header_with_strings *header
= (const struct lto_simple_header_with_strings *) data;
int string_offset;
- struct data_in *data_in;
+ class data_in *data_in;
string_offset = sizeof (*header) + header->main_size;
lto_input_block ib (data + sizeof (*header), header->main_size, NULL);
@@ -1727,12 +1735,12 @@ lto_reader_init (void)
table to use with LEN strings. RESOLUTIONS is the vector of linker
resolutions (NULL if not using a linker plugin). */
-struct data_in *
+class data_in *
lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings,
unsigned len,
vec<ld_plugin_symbol_resolution_t> resolutions)
{
- struct data_in *data_in = new (struct data_in);
+ class data_in *data_in = new (class data_in);
data_in->file_data = file_data;
data_in->strings = strings;
data_in->strings_len = len;
@@ -1745,7 +1753,7 @@ lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings,
/* Remove DATA_IN. */
void
-lto_data_in_delete (struct data_in *data_in)
+lto_data_in_delete (class data_in *data_in)
{
data_in->globals_resolution.release ();
streamer_tree_cache_delete (data_in->reader_cache);
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 49ca5ce..e0881cf5 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1911,7 +1911,7 @@ output_cfg (struct output_block *ob, struct function *fn)
/* Output each loop, skipping the tree root which has number zero. */
for (unsigned i = 1; i < number_of_loops (fn); ++i)
{
- struct loop *loop = get_loop (fn, i);
+ class loop *loop = get_loop (fn, i);
/* Write the index of the loop header. That's enough to rebuild
the loop tree on the reader side. Stream -1 for an unused
@@ -2403,7 +2403,8 @@ produce_lto_section ()
bool slim_object = flag_generate_lto && !flag_fat_lto_objects;
lto_section s
- = { LTO_major_version, LTO_minor_version, slim_object, compression, 0 };
+ = { LTO_major_version, LTO_minor_version, slim_object, 0 };
+ s.set_compression (compression);
lto_write_data (&s, sizeof s);
lto_end_section ();
destroy_output_block (ob);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index f1593d6..bf755a6 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -308,7 +308,7 @@ public:
/* Tree merging did suceed; throw away recent changes. */
void revert_location_cache ();
void input_location (location_t *loc, struct bitpack_d *bp,
- struct data_in *data_in);
+ class data_in *data_in);
lto_location_cache ()
: loc_cache (), accepted_length (0), current_file (NULL), current_line (0),
current_col (0), current_sysp (false), current_loc (UNKNOWN_LOCATION)
@@ -394,9 +394,22 @@ struct lto_section
{
int16_t major_version;
int16_t minor_version;
- unsigned char slim_object: 1;
- lto_compression compression: 4;
- int32_t reserved0: 27;
+ unsigned char slim_object;
+
+ /* Flags is a private field that is not defined publicly. */
+ uint16_t flags;
+
+ /* Set compression to FLAGS. */
+ inline void set_compression (lto_compression c)
+ {
+ flags = c;
+ }
+
+ /* Get compression from FLAGS. */
+ inline lto_compression get_compression ()
+ {
+ return (lto_compression) flags;
+ }
};
STATIC_ASSERT (sizeof (lto_section) == 8);
@@ -735,8 +748,9 @@ struct output_block
/* Data and descriptors used when reading from an LTO file. */
-struct data_in
+class data_in
{
+public:
/* The global decls and types. */
struct lto_file_decl_data *file_data;
@@ -758,13 +772,13 @@ struct data_in
/* In lto-section-in.c */
-extern struct lto_input_block * lto_create_simple_input_block (
+extern class lto_input_block * lto_create_simple_input_block (
struct lto_file_decl_data *,
enum lto_section_type, const char **, size_t *);
extern void
lto_destroy_simple_input_block (struct lto_file_decl_data *,
enum lto_section_type,
- struct lto_input_block *, const char *, size_t);
+ class lto_input_block *, const char *, size_t);
extern void lto_set_in_hooks (struct lto_file_decl_data **,
lto_get_section_data_f *,
lto_free_section_data_f *);
@@ -794,7 +808,7 @@ extern struct lto_in_decl_state *lto_get_function_in_decl_state (
struct lto_file_decl_data *, tree);
extern void lto_free_function_in_decl_state (struct lto_in_decl_state *);
extern void lto_free_function_in_decl_state_for_node (symtab_node *);
-extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN;
+extern void lto_section_overrun (class lto_input_block *) ATTRIBUTE_NORETURN;
extern void lto_value_range_error (const char *,
HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT) ATTRIBUTE_NORETURN;
@@ -859,23 +873,23 @@ extern void lto_input_constructors_and_inits (struct lto_file_decl_data *,
const char *);
extern void lto_input_toplevel_asms (struct lto_file_decl_data *, int);
extern void lto_input_mode_table (struct lto_file_decl_data *);
-extern struct data_in *lto_data_in_create (struct lto_file_decl_data *,
+extern class data_in *lto_data_in_create (struct lto_file_decl_data *,
const char *, unsigned,
vec<ld_plugin_symbol_resolution_t> );
-extern void lto_data_in_delete (struct data_in *);
-extern void lto_input_data_block (struct lto_input_block *, void *, size_t);
-void lto_input_location (location_t *, struct bitpack_d *, struct data_in *);
+extern void lto_data_in_delete (class data_in *);
+extern void lto_input_data_block (class lto_input_block *, void *, size_t);
+void lto_input_location (location_t *, struct bitpack_d *, class data_in *);
location_t stream_input_location_now (struct bitpack_d *bp,
- struct data_in *data);
-tree lto_input_tree_ref (struct lto_input_block *, struct data_in *,
+ class data_in *data);
+tree lto_input_tree_ref (class lto_input_block *, class data_in *,
struct function *, enum LTO_tags);
void lto_tag_check_set (enum LTO_tags, int, ...);
void lto_init_eh (void);
-hashval_t lto_input_scc (struct lto_input_block *, struct data_in *,
+hashval_t lto_input_scc (class lto_input_block *, class data_in *,
unsigned *, unsigned *);
-tree lto_input_tree_1 (struct lto_input_block *, struct data_in *,
+tree lto_input_tree_1 (class lto_input_block *, class data_in *,
enum LTO_tags, hashval_t hash);
-tree lto_input_tree (struct lto_input_block *, struct data_in *);
+tree lto_input_tree (class lto_input_block *, class data_in *);
/* In lto-streamer-out.c */
@@ -930,14 +944,14 @@ void select_what_to_stream (void);
void cl_target_option_stream_out (struct output_block *, struct bitpack_d *,
struct cl_target_option *);
-void cl_target_option_stream_in (struct data_in *,
+void cl_target_option_stream_in (class data_in *,
struct bitpack_d *,
struct cl_target_option *);
void cl_optimization_stream_out (struct output_block *,
struct bitpack_d *, struct cl_optimization *);
-void cl_optimization_stream_in (struct data_in *,
+void cl_optimization_stream_in (class data_in *,
struct bitpack_d *, struct cl_optimization *);
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 23ad84e..c18b2c4 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,40 @@
+2019-07-22 Giuliano Belinassi <giuliano.belinassi@usp.br>
+
+ * lang.opt (flag_dump_callgraph): New flag.
+ * lto-dump.c (dump_symtab_graphviz): New function.
+ (dump_tool_help): New option.
+ (lto_main): Handle graphviz dumping.
+
+2019-07-18 Jan Hubicka <hubicka@ucw.cz>
+
+ * lto-common.c (gimple_register_canonical_type_1): Do not look for
+ non-ODR conflicts of types in anonymous namespaces.
+ (unify_scc): Do not merge anonymous namespace types.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * lto-common.c (lto_splay_tree_new): : Change class-key of PODs
+ to struct and others to class.
+ (mentions_vars_p): Same.
+ (register_resolution): Same.
+ (lto_register_var_decl_in_symtab): Same.
+ (lto_register_function_decl_in_symtab): Same.
+ (cmp_tree): Same.
+ (lto_read_decls): Same.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR c++/61339
+ * lto-dump.c: Change class-key from class to struct and vice versa
+ to match convention and avoid -Wclass-is-pod and -Wstruct-no-pod.
+
+2019-07-04 Martin Liska <mliska@suse.cz>
+
+ PR lto/91078
+ * lto-common.c (lto_file_finalize): Use memcpy to set
+ file_data->lto_section_header.
+
2019-07-03 Martin Liska <mliska@suse.cz>
* lto-common.c: Read LTO section and verify header.
diff --git a/gcc/lto/lang.opt b/gcc/lto/lang.opt
index 5bacef3..c62dd5a 100644
--- a/gcc/lto/lang.opt
+++ b/gcc/lto/lang.opt
@@ -127,6 +127,9 @@ help
LTODump Var(flag_lto_dump_tool_help)
Dump the dump tool command line options.
+callgraph
+LTODump Var(flag_dump_callgraph)
+Dump the symtab callgraph.
fresolution=
LTO Joined
diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c
index bc8c2b4..ef2d02a 100644
--- a/gcc/lto/lto-common.c
+++ b/gcc/lto/lto-common.c
@@ -179,7 +179,7 @@ lto_splay_tree_new (void)
input. */
static const uint32_t *
-lto_read_in_decl_state (struct data_in *data_in, const uint32_t *data,
+lto_read_in_decl_state (class data_in *data_in, const uint32_t *data,
struct lto_in_decl_state *state)
{
uint32_t ix;
@@ -418,13 +418,19 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
if (RECORD_OR_UNION_TYPE_P (t)
&& odr_type_p (t) && !odr_type_violation_reported_p (t))
{
- /* Here we rely on fact that all non-ODR types was inserted into
- canonical type hash and thus we can safely detect conflicts between
- ODR types and interoperable non-ODR types. */
- gcc_checking_assert (type_streaming_finished
- && TYPE_MAIN_VARIANT (t) == t);
- slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash,
- NO_INSERT);
+ /* Anonymous namespace types never conflict with non-C++ types. */
+ if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t))
+ slot = NULL;
+ else
+ {
+ /* Here we rely on fact that all non-ODR types was inserted into
+ canonical type hash and thus we can safely detect conflicts between
+ ODR types and interoperable non-ODR types. */
+ gcc_checking_assert (type_streaming_finished
+ && TYPE_MAIN_VARIANT (t) == t);
+ slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash,
+ NO_INSERT);
+ }
if (slot && !TYPE_CXX_ODR_P (*(tree *)slot))
{
tree nonodr = *(tree *)slot;
@@ -868,7 +874,7 @@ mentions_vars_p (tree t)
/* Return the resolution for the decl with index INDEX from DATA_IN. */
static enum ld_plugin_symbol_resolution
-get_resolution (struct data_in *data_in, unsigned index)
+get_resolution (class data_in *data_in, unsigned index)
{
if (data_in->globals_resolution.exists ())
{
@@ -911,7 +917,7 @@ register_resolution (struct lto_file_decl_data *file_data, tree decl,
different files. */
static void
-lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl,
+lto_register_var_decl_in_symtab (class data_in *data_in, tree decl,
unsigned ix)
{
tree context;
@@ -936,7 +942,7 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl,
file being read. */
static void
-lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl,
+lto_register_function_decl_in_symtab (class data_in *data_in, tree decl,
unsigned ix)
{
/* If this variable has already been declared, queue the
@@ -949,7 +955,7 @@ lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl,
/* Check if T is a decl and needs register its resolution info. */
static void
-lto_maybe_register_decl (struct data_in *data_in, tree t, unsigned ix)
+lto_maybe_register_decl (class data_in *data_in, tree t, unsigned ix)
{
if (TREE_CODE (t) == VAR_DECL)
lto_register_var_decl_in_symtab (data_in, t, ix);
@@ -1624,7 +1630,7 @@ cmp_tree (const void *p1_, const void *p2_)
that was successful, otherwise return false. */
static bool
-unify_scc (struct data_in *data_in, unsigned from,
+unify_scc (class data_in *data_in, unsigned from,
unsigned len, unsigned scc_entry_len, hashval_t scc_hash)
{
bool unified_p = false;
@@ -1640,11 +1646,14 @@ unify_scc (struct data_in *data_in, unsigned from,
tree t = streamer_tree_cache_get_tree (cache, from + i);
scc->entries[i] = t;
/* Do not merge SCCs with local entities inside them. Also do
- not merge TRANSLATION_UNIT_DECLs. */
+ not merge TRANSLATION_UNIT_DECLs and anonymous namespace types. */
if (TREE_CODE (t) == TRANSLATION_UNIT_DECL
|| (VAR_OR_FUNCTION_DECL_P (t)
&& !(TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
- || TREE_CODE (t) == LABEL_DECL)
+ || TREE_CODE (t) == LABEL_DECL
+ || (TYPE_P (t)
+ && type_with_linkage_p (TYPE_MAIN_VARIANT (t))
+ && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t))))
{
/* Avoid doing any work for these cases and do not worry to
record the SCCs for further merging. */
@@ -1787,7 +1796,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
const int decl_offset = sizeof (struct lto_decl_header);
const int main_offset = decl_offset + header->decl_state_size;
const int string_offset = main_offset + header->main_size;
- struct data_in *data_in;
+ class data_in *data_in;
unsigned int i;
const uint32_t *data_ptr, *data_end;
uint32_t num_decl_states;
@@ -2199,7 +2208,7 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file)
return;
}
- file_data->lto_section_header = *(const lto_section *)data;
+ memcpy (&file_data->lto_section_header, data, sizeof (lto_section));
lto_check_version (file_data->lto_section_header.major_version,
file_data->lto_section_header.minor_version,
file_data->file_name);
diff --git a/gcc/lto/lto-dump.c b/gcc/lto/lto-dump.c
index e9de33c..74d99b5 100644
--- a/gcc/lto/lto-dump.c
+++ b/gcc/lto/lto-dump.c
@@ -38,8 +38,9 @@ along with GCC; see the file COPYING3. If not see
/* Stores details of symbols for dumping symbol list. */
-struct symbol_entry
+class symbol_entry
{
+public:
symtab_node *node;
symbol_entry (symtab_node *node_): node (node_)
{}
@@ -70,8 +71,9 @@ struct symbol_entry
/* Stores variable specific details of symbols for dumping symbol list. */
-struct variable_entry: public symbol_entry
+class variable_entry: public symbol_entry
{
+public:
variable_entry (varpool_node *node_): symbol_entry (node_)
{}
@@ -100,8 +102,9 @@ struct variable_entry: public symbol_entry
/* Stores function specific details of symbols for dumping symbol list. */
-struct function_entry: public symbol_entry
+class function_entry: public symbol_entry
{
+public:
function_entry (cgraph_node *node_): symbol_entry (node_)
{}
@@ -212,6 +215,12 @@ void dump_list_variables (void)
}
}
+/* Dump symbol table in graphviz format. */
+void dump_symtab_graphviz (void)
+{
+ symtab->dump_graphviz (stdout);
+}
+
/* Dump symbol list. */
void dump_list (void)
@@ -266,26 +275,27 @@ void dump_body ()
/* List of command line options for dumping. */
void dump_tool_help ()
{
- printf ("Usage: lto-dump [OPTION]... SUB_COMMAND [OPTION]...\n\n");
- printf ("LTO dump tool command line options.\n\n");
- printf (" -list [options] Dump the symbol list.\n");
- printf (" -demangle Dump the demangled output.\n");
- printf (" -defined-only Dump only the defined symbols.\n");
- printf (" -print-value Dump initial values of the "
- "variables.\n");
- printf (" -name-sort Sort the symbols alphabetically.\n");
- printf (" -size-sort Sort the symbols according to size.\n");
- printf (" -reverse-sort Dump the symbols in reverse order.\n");
- printf (" -symbol= Dump the details of specific symbol.\n");
- printf (" -objects Dump the details of LTO objects.\n");
- printf (" -type-stats Dump statistics of tree types.\n");
- printf (" -tree-stats Dump statistics of trees.\n");
- printf (" -gimple-stats Dump statistics of gimple "
- "statements.\n");
- printf (" -dump-body= Dump the specific gimple body.\n");
- printf (" -dump-level= Deciding the optimization level "
- "of body.\n");
- printf (" -help Display the dump tool help.\n");
+ const char *msg =
+ "Usage: lto-dump [OPTION]... SUB_COMMAND [OPTION]...\n\n"
+ "LTO dump tool command line options.\n\n"
+ " -list [options] Dump the symbol list.\n"
+ " -demangle Dump the demangled output.\n"
+ " -defined-only Dump only the defined symbols.\n"
+ " -print-value Dump initial values of the variables.\n"
+ " -name-sort Sort the symbols alphabetically.\n"
+ " -size-sort Sort the symbols according to size.\n"
+ " -reverse-sort Dump the symbols in reverse order.\n"
+ " -symbol= Dump the details of specific symbol.\n"
+ " -objects Dump the details of LTO objects.\n"
+ " -callgraph Dump the callgraph in graphviz format.\n"
+ " -type-stats Dump statistics of tree types.\n"
+ " -tree-stats Dump statistics of trees.\n"
+ " -gimple-stats Dump statistics of gimple statements.\n"
+ " -dump-body= Dump the specific gimple body.\n"
+ " -dump-level= Deciding the optimization level of body.\n"
+ " -help Display the dump tool help.\n";
+
+ fputs (msg, stdout);
return;
}
@@ -359,4 +369,9 @@ lto_main (void)
dump_body ();
return;
}
+ else if (flag_dump_callgraph)
+ {
+ dump_symtab_graphviz ();
+ return;
+ }
}
diff --git a/gcc/mem-stats.h b/gcc/mem-stats.h
index 7796059..9ceb9cc 100644
--- a/gcc/mem-stats.h
+++ b/gcc/mem-stats.h
@@ -31,8 +31,9 @@ class hash_map;
#define LOCATION_LINE_WIDTH 48
/* Memory allocation location. */
-struct mem_location
+class mem_location
{
+public:
/* Default constructor. */
inline
mem_location () {}
@@ -123,8 +124,9 @@ struct mem_location
};
/* Memory usage register to a memory location. */
-struct mem_usage
+class mem_usage
{
+public:
/* Default constructor. */
mem_usage (): m_allocated (0), m_times (0), m_peak (0), m_instances (1) {}
@@ -260,8 +262,9 @@ struct mem_usage
/* Memory usage pair that connectes memory usage and number
of allocated bytes. */
template <class T>
-struct mem_usage_pair
+class mem_usage_pair
{
+public:
mem_usage_pair (T *usage_, size_t allocated_): usage (usage_),
allocated (allocated_) {}
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 9954ea5..c355594 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -211,7 +211,7 @@ static int sms_order_nodes (ddg_ptr, int, int *, int *);
static void set_node_sched_params (ddg_ptr);
static partial_schedule_ptr sms_schedule_by_order (ddg_ptr, int, int, int *);
static void permute_partial_schedule (partial_schedule_ptr, rtx_insn *);
-static void generate_prolog_epilog (partial_schedule_ptr, struct loop *,
+static void generate_prolog_epilog (partial_schedule_ptr, class loop *,
rtx, rtx);
static int calculate_stage_count (partial_schedule_ptr, int);
static void calculate_must_precede_follow (ddg_node_ptr, int, int,
@@ -1124,7 +1124,7 @@ duplicate_insns_of_cycles (partial_schedule_ptr ps, int from_stage,
/* Generate the instructions (including reg_moves) for prolog & epilog. */
static void
-generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop,
+generate_prolog_epilog (partial_schedule_ptr ps, class loop *loop,
rtx count_reg, rtx count_init)
{
int i;
@@ -1181,7 +1181,7 @@ generate_prolog_epilog (partial_schedule_ptr ps, struct loop *loop,
/* Mark LOOP as software pipelined so the later
scheduling passes don't touch it. */
static void
-mark_loop_unsched (struct loop *loop)
+mark_loop_unsched (class loop *loop)
{
unsigned i;
basic_block *bbs = get_loop_body (loop);
@@ -1195,7 +1195,7 @@ mark_loop_unsched (struct loop *loop)
/* Return true if all the BBs of the loop are empty except the
loop header. */
static bool
-loop_single_full_bb_p (struct loop *loop)
+loop_single_full_bb_p (class loop *loop)
{
unsigned i;
basic_block *bbs = get_loop_body (loop);
@@ -1251,7 +1251,7 @@ dump_insn_location (rtx_insn *insn)
/* Return true if the loop is in its canonical form and false if not.
i.e. SIMPLE_SMS_LOOP_P and have one preheader block, and single exit. */
static bool
-loop_canon_p (struct loop *loop)
+loop_canon_p (class loop *loop)
{
if (loop->inner || !loop_outer (loop))
@@ -1294,7 +1294,7 @@ loop_canon_p (struct loop *loop)
make it one by splitting the first entry edge and
redirecting the others to the new BB. */
static void
-canon_loop (struct loop *loop)
+canon_loop (class loop *loop)
{
edge e;
edge_iterator i;
@@ -1346,7 +1346,7 @@ sms_schedule (void)
int maxii, max_asap;
partial_schedule_ptr ps;
basic_block bb = NULL;
- struct loop *loop;
+ class loop *loop;
basic_block condition_bb = NULL;
edge latch_edge;
HOST_WIDE_INT trip_count, max_trip_count;
diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
index 9236b36..94543de 100644
--- a/gcc/omp-expand.c
+++ b/gcc/omp-expand.c
@@ -2516,7 +2516,7 @@ expand_omp_for_ordered_loops (struct omp_for_data *fd, tree *counts,
if (e2)
{
- struct loop *loop = alloc_loop ();
+ class loop *loop = alloc_loop ();
loop->header = new_header;
loop->latch = e2->src;
add_loop (loop, body_bb->loop_father);
@@ -3477,14 +3477,14 @@ expand_omp_for_generic (struct omp_region *region,
/* We enter expand_omp_for_generic with a loop. This original loop may
have its own loop struct, or it may be part of an outer loop struct
(which may be the fake loop). */
- struct loop *outer_loop = entry_bb->loop_father;
+ class loop *outer_loop = entry_bb->loop_father;
bool orig_loop_has_loop_struct = l1_bb->loop_father != outer_loop;
add_bb_to_loop (l2_bb, outer_loop);
/* We've added a new loop around the original loop. Allocate the
corresponding loop struct. */
- struct loop *new_loop = alloc_loop ();
+ class loop *new_loop = alloc_loop ();
new_loop->header = l0_bb;
new_loop->latch = l2_bb;
add_loop (new_loop, outer_loop);
@@ -3494,7 +3494,7 @@ expand_omp_for_generic (struct omp_region *region,
if (!orig_loop_has_loop_struct
&& !gimple_omp_for_combined_p (fd->for_stmt))
{
- struct loop *orig_loop = alloc_loop ();
+ class loop *orig_loop = alloc_loop ();
orig_loop->header = l1_bb;
/* The loop may have multiple latches. */
add_loop (orig_loop, new_loop);
@@ -3744,7 +3744,9 @@ expand_omp_for_static_nochunk (struct omp_region *region,
cond_var = OMP_CLAUSE_DECL (c);
}
if (fd->have_reductemp
- || fd->have_pointer_condtemp
+ /* For scan, we don't want to reinitialize condtemp before the
+ second loop. */
+ || (fd->have_pointer_condtemp && !fd->have_scantemp)
|| fd->have_nonctrl_scantemp)
{
tree t1 = build_int_cst (long_integer_type_node, 0);
@@ -4235,7 +4237,8 @@ expand_omp_for_static_nochunk (struct omp_region *region,
else
gsi_insert_after (&gsi, omp_build_barrier (t), GSI_SAME_STMT);
}
- else if (fd->have_pointer_condtemp)
+ else if ((fd->have_pointer_condtemp || fd->have_scantemp)
+ && !fd->have_nonctrl_scantemp)
{
tree fn = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
gcall *g = gimple_build_call (fn, 0);
@@ -4353,7 +4356,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
set_immediate_dominator (CDI_DOMINATORS, exit3_bb, exit_bb);
}
- struct loop *loop = body_bb->loop_father;
+ class loop *loop = body_bb->loop_father;
if (loop != entry_bb->loop_father)
{
gcc_assert (broken_loop || loop->header == body_bb);
@@ -5101,8 +5104,8 @@ expand_omp_for_static_chunk (struct omp_region *region,
if (!broken_loop)
{
- struct loop *loop = body_bb->loop_father;
- struct loop *trip_loop = alloc_loop ();
+ class loop *loop = body_bb->loop_father;
+ class loop *trip_loop = alloc_loop ();
trip_loop->header = iter_part_bb;
trip_loop->latch = trip_update_bb;
add_loop (trip_loop, iter_part_bb->loop_father);
@@ -5520,7 +5523,7 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
if (!broken_loop)
{
- struct loop *loop = alloc_loop ();
+ class loop *loop = alloc_loop ();
loop->header = l1_bb;
loop->latch = cont_bb;
add_loop (loop, l1_bb->loop_father);
@@ -5941,7 +5944,7 @@ expand_omp_taskloop_for_inner (struct omp_region *region,
if (!broken_loop && !gimple_omp_for_combined_p (fd->for_stmt))
{
- struct loop *loop = alloc_loop ();
+ class loop *loop = alloc_loop ();
loop->header = body_bb;
if (collapse_bb == NULL)
loop->latch = cont_bb;
@@ -6458,12 +6461,12 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
{
/* We now have one, two or three nested loops. Update the loop
structures. */
- struct loop *parent = entry_bb->loop_father;
- struct loop *body = body_bb->loop_father;
+ class loop *parent = entry_bb->loop_father;
+ class loop *body = body_bb->loop_father;
if (chunking)
{
- struct loop *chunk_loop = alloc_loop ();
+ class loop *chunk_loop = alloc_loop ();
chunk_loop->header = head_bb;
chunk_loop->latch = bottom_bb;
add_loop (chunk_loop, parent);
@@ -6479,7 +6482,7 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
if (parent)
{
- struct loop *body_loop = alloc_loop ();
+ class loop *body_loop = alloc_loop ();
body_loop->header = body_bb;
body_loop->latch = cont_bb;
add_loop (body_loop, parent);
@@ -6487,7 +6490,7 @@ expand_oacc_for (struct omp_region *region, struct omp_for_data *fd)
if (fd->tiling)
{
/* Insert tiling's element loop. */
- struct loop *inner_loop = alloc_loop ();
+ class loop *inner_loop = alloc_loop ();
inner_loop->header = elem_body_bb;
inner_loop->latch = elem_cont_bb;
add_loop (inner_loop, body_loop);
@@ -6529,7 +6532,7 @@ expand_omp_for (struct omp_region *region, gimple *inner_stmt)
original loops from being detected. Fix that up. */
loops_state_set (LOOPS_NEED_FIXUP);
- if (gimple_omp_for_kind (fd.for_stmt) & GF_OMP_FOR_SIMD)
+ if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_SIMD)
expand_omp_simd (region, &fd);
else if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
{
@@ -7472,7 +7475,7 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
/* Remove GIMPLE_OMP_ATOMIC_STORE. */
gsi_remove (&si, true);
- struct loop *loop = alloc_loop ();
+ class loop *loop = alloc_loop ();
loop->header = loop_header;
loop->latch = store_bb;
add_loop (loop, loop_header->loop_father);
@@ -7622,14 +7625,14 @@ static void
mark_loops_in_oacc_kernels_region (basic_block region_entry,
basic_block region_exit)
{
- struct loop *outer = region_entry->loop_father;
+ class loop *outer = region_entry->loop_father;
gcc_assert (region_exit == NULL || outer == region_exit->loop_father);
/* Don't parallelize the kernels region if it contains more than one outer
loop. */
unsigned int nr_outer_loops = 0;
- struct loop *single_outer = NULL;
- for (struct loop *loop = outer->inner; loop != NULL; loop = loop->next)
+ class loop *single_outer = NULL;
+ for (class loop *loop = outer->inner; loop != NULL; loop = loop->next)
{
gcc_assert (loop_outer (loop) == outer);
@@ -7646,14 +7649,14 @@ mark_loops_in_oacc_kernels_region (basic_block region_entry,
if (nr_outer_loops != 1)
return;
- for (struct loop *loop = single_outer->inner;
+ for (class loop *loop = single_outer->inner;
loop != NULL;
loop = loop->inner)
if (loop->next)
return;
/* Mark the loops in the region. */
- for (struct loop *loop = single_outer; loop != NULL; loop = loop->inner)
+ for (class loop *loop = single_outer; loop != NULL; loop = loop->inner)
loop->in_oacc_kernels_region = true;
}
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index 8086f9a..66be94f 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -156,7 +156,7 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
int i;
struct omp_for_data_loop dummy_loop;
location_t loc = gimple_location (for_stmt);
- bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
+ bool simd = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD;
bool distribute = gimple_omp_for_kind (for_stmt)
== GF_OMP_FOR_KIND_DISTRIBUTE;
bool taskloop = gimple_omp_for_kind (for_stmt)
diff --git a/gcc/omp-grid.c b/gcc/omp-grid.c
index 1ff65aa..e7e18aa 100644
--- a/gcc/omp-grid.c
+++ b/gcc/omp-grid.c
@@ -83,8 +83,9 @@ omp_grid_lastprivate_predicate (struct omp_for_data *fd)
/* Structure describing the basic properties of the loop we ara analyzing
whether it can be gridified and when it is gridified. */
-struct grid_prop
+class grid_prop
{
+public:
/* True when we are doing tiling gridification, i.e. when there is a distinct
distribute loop over groups and a loop construct over work-items. False
when distribute and parallel for loops form a combined construct. */
@@ -1001,7 +1002,7 @@ grid_process_grid_body (gimple_stmt_iterator *gsi, bool *handled_ops_p,
*handled_ops_p = false;
gimple *stmt = gsi_stmt (*gsi);
if (gimple_code (stmt) == GIMPLE_OMP_FOR
- && (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD))
+ && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
{
gomp_for *loop = as_a <gomp_for *> (stmt);
tree clauses = gimple_omp_for_clauses (loop);
@@ -1029,14 +1030,14 @@ grid_eliminate_combined_simd_part (gomp_for *parloop)
memset (&wi, 0, sizeof (wi));
wi.val_only = true;
- enum gf_mask msk = GF_OMP_FOR_SIMD;
+ enum gf_mask msk = GF_OMP_FOR_KIND_SIMD;
wi.info = (void *) &msk;
walk_gimple_seq (gimple_omp_body (parloop), omp_find_combined_for, NULL, &wi);
gimple *stmt = (gimple *) wi.info;
/* We expect that the SIMD id the only statement in the parallel loop. */
gcc_assert (stmt
&& gimple_code (stmt) == GIMPLE_OMP_FOR
- && (gimple_omp_for_kind (stmt) == GF_OMP_FOR_SIMD)
+ && (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
&& gimple_omp_for_combined_into_p (stmt)
&& !gimple_omp_for_combined_p (stmt));
gomp_for *simd = as_a <gomp_for *> (stmt);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 98a9df5..d8756c0 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -140,13 +140,22 @@ struct omp_context
/* True if lower_omp_1 should look up lastprivate conditional in parent
context. */
- bool combined_into_simd_safelen0;
+ bool combined_into_simd_safelen1;
/* True if there is nested scan context with inclusive clause. */
bool scan_inclusive;
/* True if there is nested scan context with exclusive clause. */
bool scan_exclusive;
+
+ /* True in the second simd loop of for simd with inscan reductions. */
+ bool for_simd_scan_phase;
+
+ /* True if there is order(concurrent) clause on the construct. */
+ bool order_concurrent;
+
+ /* True if there is bind clause on the construct (i.e. a loop construct). */
+ bool loop_p;
};
static splay_tree all_contexts;
@@ -574,7 +583,8 @@ build_outer_var_ref (tree var, omp_context *ctx,
x = build_receiver_ref (var, by_ref, ctx);
}
else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ || ctx->loop_p
|| (code == OMP_CLAUSE_PRIVATE
&& (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
|| gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
@@ -1387,6 +1397,14 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
}
break;
+ case OMP_CLAUSE_ORDER:
+ ctx->order_concurrent = true;
+ break;
+
+ case OMP_CLAUSE_BIND:
+ ctx->loop_p = true;
+ break;
+
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_COLLAPSE:
@@ -1431,7 +1449,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
install_var_local (decl, ctx);
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && (gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
&& !OMP_CLAUSE__CONDTEMP__ITER (c))
install_var_local (decl, ctx);
break;
@@ -1592,6 +1610,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_NOGROUP:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_USE_DEVICE_PTR:
case OMP_CLAUSE_NONTEMPORAL:
case OMP_CLAUSE_ASYNC:
@@ -2421,6 +2441,85 @@ scan_omp_simd (gimple_stmt_iterator *gsi, gomp_for *stmt,
scan_omp_for (stmt, outer_ctx)->simt_stmt = new_stmt;
}
+static tree omp_find_scan (gimple_stmt_iterator *, bool *,
+ struct walk_stmt_info *);
+static omp_context *maybe_lookup_ctx (gimple *);
+
+/* Duplicate #pragma omp simd, one for the scan input phase loop and one
+ for scan phase loop. */
+
+static void
+scan_omp_simd_scan (gimple_stmt_iterator *gsi, gomp_for *stmt,
+ omp_context *outer_ctx)
+{
+ /* The only change between inclusive and exclusive scan will be
+ within the first simd loop, so just use inclusive in the
+ worksharing loop. */
+ outer_ctx->scan_inclusive = true;
+ tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_INCLUSIVE);
+ OMP_CLAUSE_DECL (c) = integer_zero_node;
+
+ gomp_scan *input_stmt = gimple_build_omp_scan (NULL, NULL_TREE);
+ gomp_scan *scan_stmt = gimple_build_omp_scan (NULL, c);
+ gsi_replace (gsi, input_stmt, false);
+ gimple_seq input_body = NULL;
+ gimple_seq_add_stmt (&input_body, stmt);
+ gsi_insert_after (gsi, scan_stmt, GSI_NEW_STMT);
+
+ gimple_stmt_iterator input1_gsi = gsi_none ();
+ struct walk_stmt_info wi;
+ memset (&wi, 0, sizeof (wi));
+ wi.val_only = true;
+ wi.info = (void *) &input1_gsi;
+ walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), omp_find_scan, NULL, &wi);
+ gcc_assert (!gsi_end_p (input1_gsi));
+
+ gimple *input_stmt1 = gsi_stmt (input1_gsi);
+ gsi_next (&input1_gsi);
+ gimple *scan_stmt1 = gsi_stmt (input1_gsi);
+ gcc_assert (scan_stmt1 && gimple_code (scan_stmt1) == GIMPLE_OMP_SCAN);
+ c = gimple_omp_scan_clauses (as_a <gomp_scan *> (scan_stmt1));
+ if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
+ std::swap (input_stmt1, scan_stmt1);
+
+ gimple_seq input_body1 = gimple_omp_body (input_stmt1);
+ gimple_omp_set_body (input_stmt1, NULL);
+
+ gimple_seq scan_body = copy_gimple_seq_and_replace_locals (stmt);
+ gomp_for *new_stmt = as_a <gomp_for *> (scan_body);
+
+ gimple_omp_set_body (input_stmt1, input_body1);
+ gimple_omp_set_body (scan_stmt1, NULL);
+
+ gimple_stmt_iterator input2_gsi = gsi_none ();
+ memset (&wi, 0, sizeof (wi));
+ wi.val_only = true;
+ wi.info = (void *) &input2_gsi;
+ walk_gimple_seq_mod (gimple_omp_body_ptr (new_stmt), omp_find_scan,
+ NULL, &wi);
+ gcc_assert (!gsi_end_p (input2_gsi));
+
+ gimple *input_stmt2 = gsi_stmt (input2_gsi);
+ gsi_next (&input2_gsi);
+ gimple *scan_stmt2 = gsi_stmt (input2_gsi);
+ gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
+ if (c && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_EXCLUSIVE)
+ std::swap (input_stmt2, scan_stmt2);
+
+ gimple_omp_set_body (input_stmt2, NULL);
+
+ gimple_omp_set_body (input_stmt, input_body);
+ gimple_omp_set_body (scan_stmt, scan_body);
+
+ omp_context *ctx = new_omp_context (input_stmt, outer_ctx);
+ scan_omp (gimple_omp_body_ptr (input_stmt), ctx);
+
+ ctx = new_omp_context (scan_stmt, outer_ctx);
+ scan_omp (gimple_omp_body_ptr (scan_stmt), ctx);
+
+ maybe_lookup_ctx (new_stmt)->for_simd_scan_phase = true;
+}
+
/* Scan an OpenMP sections directive. */
static void
@@ -2585,9 +2684,21 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
&& gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
ctx = ctx->outer;
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
+ && !ctx->loop_p)
{
c = NULL_TREE;
+ if (ctx->order_concurrent
+ && (gimple_code (stmt) == GIMPLE_OMP_ORDERED
+ || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD
+ || gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE))
+ {
+ error_at (gimple_location (stmt),
+ "OpenMP constructs other than %<parallel%>, %<loop%>"
+ " or %<simd%> may not be nested inside a region with"
+ " the %<order(concurrent)%> clause");
+ return false;
+ }
if (gimple_code (stmt) == GIMPLE_OMP_ORDERED)
{
c = gimple_omp_ordered_clauses (as_a <gomp_ordered *> (stmt));
@@ -2613,31 +2724,53 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
|| gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
|| gimple_code (stmt) == GIMPLE_OMP_SCAN)
return true;
+ else if (gimple_code (stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ return true;
error_at (gimple_location (stmt),
- "OpenMP constructs other than %<#pragma omp ordered simd%>"
- " or %<#pragma omp atomic%> may not be nested inside"
- " %<simd%> region");
+ "OpenMP constructs other than "
+ "%<ordered simd%>, %<simd%>, %<loop%> or %<atomic%> may "
+ "not be nested inside %<simd%> region");
return false;
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
{
if ((gimple_code (stmt) != GIMPLE_OMP_FOR
- || ((gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_DISTRIBUTE)
- && (gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_GRID_LOOP)))
+ || (gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_DISTRIBUTE
+ && gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_GRID_LOOP
+ && omp_find_clause (gimple_omp_for_clauses (stmt),
+ OMP_CLAUSE_BIND) == NULL_TREE))
&& gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
{
error_at (gimple_location (stmt),
- "only %<distribute%> or %<parallel%> regions are "
- "allowed to be strictly nested inside %<teams%> "
- "region");
+ "only %<distribute%>, %<parallel%> or %<loop%> "
+ "regions are allowed to be strictly nested inside "
+ "%<teams%> region");
return false;
}
}
+ else if (ctx->order_concurrent
+ && gimple_code (stmt) != GIMPLE_OMP_PARALLEL
+ && (gimple_code (stmt) != GIMPLE_OMP_FOR
+ || gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_SIMD)
+ && gimple_code (stmt) != GIMPLE_OMP_SCAN)
+ {
+ if (ctx->loop_p)
+ error_at (gimple_location (stmt),
+ "OpenMP constructs other than %<parallel%>, %<loop%> or "
+ "%<simd%> may not be nested inside a %<loop%> region");
+ else
+ error_at (gimple_location (stmt),
+ "OpenMP constructs other than %<parallel%>, %<loop%> or "
+ "%<simd%> may not be nested inside a region with "
+ "the %<order(concurrent)%> clause");
+ return false;
+ }
}
switch (gimple_code (stmt))
{
case GIMPLE_OMP_FOR:
- if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
+ if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
return true;
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
{
@@ -2653,6 +2786,11 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
/* We split taskloop into task and nested taskloop in it. */
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP)
return true;
+ /* For now, hope this will change and loop bind(parallel) will not
+ be allowed in lots of contexts. */
+ if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
+ && omp_find_clause (gimple_omp_for_clauses (stmt), OMP_CLAUSE_BIND))
+ return true;
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
{
bool ok = false;
@@ -2703,8 +2841,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
const char *construct
= (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL)
- ? "#pragma omp cancel"
- : "#pragma omp cancellation point";
+ ? "cancel"
+ : "cancellation point";
if (ctx == NULL)
{
error_at (gimple_location (stmt), "orphaned %qs construct",
@@ -2717,7 +2855,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
{
case 1:
if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
- bad = "#pragma omp parallel";
+ bad = "parallel";
else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL
&& !integer_zerop (gimple_call_arg (stmt, 1)))
@@ -2727,7 +2865,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case 2:
if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
|| gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
- bad = "#pragma omp for";
+ bad = "for";
else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL
&& !integer_zerop (gimple_call_arg (stmt, 1)))
@@ -2736,12 +2874,12 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
OMP_CLAUSE_NOWAIT))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel for%> inside "
+ "%<cancel for%> inside "
"%<nowait%> for construct");
if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
OMP_CLAUSE_ORDERED))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel for%> inside "
+ "%<cancel for%> inside "
"%<ordered%> for construct");
}
kind = "for";
@@ -2749,7 +2887,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case 4:
if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
&& gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
- bad = "#pragma omp sections";
+ bad = "sections";
else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL
&& !integer_zerop (gimple_call_arg (stmt, 1)))
@@ -2761,7 +2899,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
(ctx->stmt),
OMP_CLAUSE_NOWAIT))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel sections%> inside "
+ "%<cancel sections%> inside "
"%<nowait%> sections construct");
}
else
@@ -2774,7 +2912,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
(ctx->outer->stmt),
OMP_CLAUSE_NOWAIT))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel sections%> inside "
+ "%<cancel sections%> inside "
"%<nowait%> sections construct");
}
}
@@ -2785,7 +2923,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
&& (!is_taskloop_ctx (ctx)
|| ctx->outer == NULL
|| !is_task_ctx (ctx->outer)))
- bad = "#pragma omp task";
+ bad = "task";
else
{
for (omp_context *octx = ctx->outer;
@@ -2863,14 +3001,14 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
return true;
error_at (gimple_location (stmt),
"barrier region may not be closely nested inside "
- "of work-sharing, %<critical%>, %<ordered%>, "
- "%<master%>, explicit %<task%> or %<taskloop%> "
- "region");
+ "of work-sharing, %<loop%>, %<critical%>, "
+ "%<ordered%>, %<master%>, explicit %<task%> or "
+ "%<taskloop%> region");
return false;
}
error_at (gimple_location (stmt),
"work-sharing region may not be closely nested inside "
- "of work-sharing, %<critical%>, %<ordered%>, "
+ "of work-sharing, %<loop%>, %<critical%>, %<ordered%>, "
"%<master%>, explicit %<task%> or %<taskloop%> region");
return false;
case GIMPLE_OMP_PARALLEL:
@@ -2899,8 +3037,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case GIMPLE_OMP_TASK:
error_at (gimple_location (stmt),
"%<master%> region may not be closely nested inside "
- "of work-sharing, explicit %<task%> or %<taskloop%> "
- "region");
+ "of work-sharing, %<loop%>, explicit %<task%> or "
+ "%<taskloop%> region");
return false;
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TEAMS:
@@ -3239,12 +3377,123 @@ setjmp_or_longjmp_p (const_tree fndecl)
return true;
tree declname = DECL_NAME (fndecl);
- if (!declname)
+ if (!declname
+ || (DECL_CONTEXT (fndecl) != NULL_TREE
+ && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
+ || !TREE_PUBLIC (fndecl))
return false;
+
const char *name = IDENTIFIER_POINTER (declname);
return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
}
+/* Return true if FNDECL is an omp_* runtime API call. */
+
+static bool
+omp_runtime_api_call (const_tree fndecl)
+{
+ tree declname = DECL_NAME (fndecl);
+ if (!declname
+ || (DECL_CONTEXT (fndecl) != NULL_TREE
+ && TREE_CODE (DECL_CONTEXT (fndecl)) != TRANSLATION_UNIT_DECL)
+ || !TREE_PUBLIC (fndecl))
+ return false;
+
+ const char *name = IDENTIFIER_POINTER (declname);
+ if (strncmp (name, "omp_", 4) != 0)
+ return false;
+
+ static const char *omp_runtime_apis[] =
+ {
+ /* This array has 3 sections. First omp_* calls that don't
+ have any suffixes. */
+ "target_alloc",
+ "target_associate_ptr",
+ "target_disassociate_ptr",
+ "target_free",
+ "target_is_present",
+ "target_memcpy",
+ "target_memcpy_rect",
+ NULL,
+ /* Now omp_* calls that are available as omp_* and omp_*_. */
+ "capture_affinity",
+ "destroy_lock",
+ "destroy_nest_lock",
+ "display_affinity",
+ "get_active_level",
+ "get_affinity_format",
+ "get_cancellation",
+ "get_default_device",
+ "get_dynamic",
+ "get_initial_device",
+ "get_level",
+ "get_max_active_levels",
+ "get_max_task_priority",
+ "get_max_threads",
+ "get_nested",
+ "get_num_devices",
+ "get_num_places",
+ "get_num_procs",
+ "get_num_teams",
+ "get_num_threads",
+ "get_partition_num_places",
+ "get_place_num",
+ "get_proc_bind",
+ "get_team_num",
+ "get_thread_limit",
+ "get_thread_num",
+ "get_wtick",
+ "get_wtime",
+ "in_final",
+ "in_parallel",
+ "init_lock",
+ "init_nest_lock",
+ "is_initial_device",
+ "pause_resource",
+ "pause_resource_all",
+ "set_affinity_format",
+ "set_lock",
+ "set_nest_lock",
+ "test_lock",
+ "test_nest_lock",
+ "unset_lock",
+ "unset_nest_lock",
+ NULL,
+ /* And finally calls available as omp_*, omp_*_ and omp_*_8_. */
+ "get_ancestor_thread_num",
+ "get_partition_place_nums",
+ "get_place_num_procs",
+ "get_place_proc_ids",
+ "get_schedule",
+ "get_team_size",
+ "set_default_device",
+ "set_dynamic",
+ "set_max_active_levels",
+ "set_nested",
+ "set_num_threads",
+ "set_schedule"
+ };
+
+ int mode = 0;
+ for (unsigned i = 0; i < ARRAY_SIZE (omp_runtime_apis); i++)
+ {
+ if (omp_runtime_apis[i] == NULL)
+ {
+ mode++;
+ continue;
+ }
+ size_t len = strlen (omp_runtime_apis[i]);
+ if (strncmp (name + 4, omp_runtime_apis[i], len) == 0
+ && (name[4 + len] == '\0'
+ || (mode > 0
+ && name[4 + len] == '_'
+ && (name[4 + len + 1] == '\0'
+ || (mode > 1
+ && strcmp (name + 4 + len + 1, "8_") == 0)))))
+ return true;
+ }
+ return false;
+}
/* Helper function for scan_omp.
@@ -3270,14 +3519,15 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
tree fndecl = gimple_call_fndecl (stmt);
if (fndecl)
{
- if (setjmp_or_longjmp_p (fndecl)
- && ctx
+ if (ctx
&& gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
+ && setjmp_or_longjmp_p (fndecl)
+ && !ctx->loop_p)
{
remove = true;
error_at (gimple_location (stmt),
- "setjmp/longjmp inside simd construct");
+ "setjmp/longjmp inside %<simd%> construct");
}
else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (fndecl))
@@ -3294,6 +3544,19 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
default:
break;
}
+ else if (ctx)
+ {
+ omp_context *octx = ctx;
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_SCAN && ctx->outer)
+ octx = ctx->outer;
+ if (octx->order_concurrent && omp_runtime_api_call (fndecl))
+ {
+ remove = true;
+ error_at (gimple_location (stmt),
+ "OpenMP runtime API call %qD in a region with "
+ "%<order(concurrent)%> clause", fndecl);
+ }
+ }
}
}
if (remove)
@@ -3321,6 +3584,19 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
case GIMPLE_OMP_FOR:
if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
== GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_combined_into_p (stmt)
+ && gimple_code (ctx->stmt) != GIMPLE_OMP_SCAN)
+ {
+ tree clauses = gimple_omp_for_clauses (as_a <gomp_for *> (stmt));
+ tree c = omp_find_clause (clauses, OMP_CLAUSE_REDUCTION);
+ if (c && OMP_CLAUSE_REDUCTION_INSCAN (c) && !seen_error ())
+ {
+ scan_omp_simd_scan (gsi, as_a <gomp_for *> (stmt), ctx);
+ break;
+ }
+ }
+ if ((gimple_omp_for_kind (as_a <gomp_for *> (stmt))
+ == GF_OMP_FOR_KIND_SIMD)
&& omp_maybe_offloaded_ctx (ctx)
&& omp_max_simt_vf ())
scan_omp_simd (gsi, as_a <gomp_for *> (stmt), ctx);
@@ -3682,7 +3958,8 @@ omp_clause_aligned_alignment (tree clause)
/* This structure is part of the interface between lower_rec_simd_input_clauses
and lower_rec_input_clauses. */
-struct omplow_simd_context {
+class omplow_simd_context {
+public:
omplow_simd_context () { memset (this, 0, sizeof (*this)); }
tree idx;
tree lane;
@@ -3757,7 +4034,7 @@ lower_rec_simd_input_clauses (tree new_var, omp_context *ctx,
DECL_ATTRIBUTES (avar));
gimple_add_tmp_var (avar);
tree iavar = avar;
- if (rvar)
+ if (rvar && !ctx->for_simd_scan_phase)
{
/* For inscan reductions, create another array temporary,
which will hold the reduced value. */
@@ -3867,7 +4144,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
bool reduction_omp_orig_ref = false;
int pass;
bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
omplow_simd_context sctx = omplow_simd_context ();
tree simt_lane = NULL_TREE, simtrec = NULL_TREE;
tree ivar = NULL_TREE, lvar = NULL_TREE, uid = NULL_TREE;
@@ -4846,7 +5123,10 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
{
tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
if ((TREE_ADDRESSABLE (new_var) || nx || y
- || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && (gimple_omp_for_collapse (ctx->stmt) != 1
+ || (gimple_omp_for_index (ctx->stmt, 0)
+ != new_var)))
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_
|| omp_is_reference (var))
&& lower_rec_simd_input_clauses (new_var, ctx, &sctx,
@@ -4911,6 +5191,17 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
lower_omp (&tseq, ctx->outer);
gimple_seq_add_seq (&llist[1], tseq);
}
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && ctx->for_simd_scan_phase)
+ {
+ x = unshare_expr (ivar);
+ tree orig_v
+ = build_outer_var_ref (var, ctx,
+ OMP_CLAUSE_LASTPRIVATE);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x,
+ orig_v);
+ gimplify_and_add (x, &llist[0]);
+ }
if (y)
{
y = lang_hooks.decls.omp_clause_dtor (c, ivar);
@@ -4940,6 +5231,16 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
if (nx)
gimplify_and_add (nx, ilist);
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && is_simd
+ && ctx->for_simd_scan_phase)
+ {
+ tree orig_v = build_outer_var_ref (var, ctx,
+ OMP_CLAUSE_LASTPRIVATE);
+ x = lang_hooks.decls.omp_clause_assign_op (c, new_var,
+ orig_v);
+ gimplify_and_add (x, ilist);
+ }
/* FALLTHRU */
do_dtor:
@@ -5213,7 +5514,16 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
x = lang_hooks.decls.omp_clause_default_ctor
(c, unshare_expr (ivar),
build_outer_var_ref (var, ctx));
- if (rvarp)
+ if (rvarp && ctx->for_simd_scan_phase)
+ {
+ if (x)
+ gimplify_and_add (x, &llist[0]);
+ x = lang_hooks.decls.omp_clause_dtor (c, ivar);
+ if (x)
+ gimplify_and_add (x, &llist[1]);
+ break;
+ }
+ else if (rvarp)
{
if (x)
{
@@ -5371,6 +5681,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
&& OMP_CLAUSE_REDUCTION_INSCAN (c))
{
+ if (ctx->for_simd_scan_phase)
+ goto do_dtor;
if (x || (!is_simd
&& OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c)))
{
@@ -5532,6 +5844,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (rvarp)
{
+ if (ctx->for_simd_scan_phase)
+ break;
gimplify_assign (ivar, ref, &llist[0]);
ref = build_outer_var_ref (var, ctx);
gimplify_assign (ref, rvar, &llist[3]);
@@ -5595,17 +5909,18 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (gimple_omp_for_combined_into_p (ctx->stmt))
{
/* Signal to lower_omp_1 that it should use parent context. */
- ctx->combined_into_simd_safelen0 = true;
+ ctx->combined_into_simd_safelen1 = true;
for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
{
tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
- tree *v
- = ctx->lastprivate_conditional_map->get (o);
- tree po = lookup_decl (OMP_CLAUSE_DECL (c), ctx->outer);
- tree *pv
- = ctx->outer->lastprivate_conditional_map->get (po);
+ omp_context *outer = ctx->outer;
+ if (gimple_code (outer->stmt) == GIMPLE_OMP_SCAN)
+ outer = outer->outer;
+ tree *v = ctx->lastprivate_conditional_map->get (o);
+ tree po = lookup_decl (OMP_CLAUSE_DECL (c), outer);
+ tree *pv = outer->lastprivate_conditional_map->get (po);
*v = *pv;
}
}
@@ -5807,7 +6122,7 @@ lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
tree cond_ptr = NULL_TREE;
tree iter_var = NULL_TREE;
bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
tree next = *clauses;
for (tree c = *clauses; c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
@@ -5910,6 +6225,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
bool par_clauses = false;
tree simduid = NULL, lastlane = NULL, simtcond = NULL, simtlast = NULL;
unsigned HOST_WIDE_INT conditional_off = 0;
+ gimple_seq post_stmt_list = NULL;
/* Early exit if there are no lastprivate or linear clauses. */
for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
@@ -5938,7 +6254,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
bool maybe_simt = false;
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
{
maybe_simt = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMT_);
simduid = omp_find_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
@@ -5999,7 +6315,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
&& ctx->lastprivate_conditional_map
- && !ctx->combined_into_simd_safelen0)
+ && !ctx->combined_into_simd_safelen1)
{
gcc_assert (body_p);
if (simduid)
@@ -6036,6 +6352,12 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab1));
gimplify_assign (mem2, v, this_stmt_list);
}
+ else if (predicate
+ && ctx->combined_into_simd_safelen1
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
+ && ctx->lastprivate_conditional_map)
+ this_stmt_list = &post_stmt_list;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
|| (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
@@ -6166,6 +6488,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
if (label)
gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
+ gimple_seq_add_seq (stmt_list, post_stmt_list);
}
/* Lower the OpenACC reductions of CLAUSES for compute axis LEVEL
@@ -6413,7 +6736,7 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
/* SIMD reductions are handled in lower_rec_input_clauses. */
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
return;
/* inscan reductions are handled elsewhere. */
@@ -8629,11 +8952,13 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
bool input_phase = has_clauses ^ octx->scan_inclusive;
bool is_simd = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
- && (gimple_omp_for_kind (octx->stmt) & GF_OMP_FOR_SIMD)
- && !gimple_omp_for_combined_into_p (octx->stmt));
+ && gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_SIMD);
bool is_for = (gimple_code (octx->stmt) == GIMPLE_OMP_FOR
&& gimple_omp_for_kind (octx->stmt) == GF_OMP_FOR_KIND_FOR
&& !gimple_omp_for_combined_p (octx->stmt));
+ bool is_for_simd = is_simd && gimple_omp_for_combined_into_p (octx->stmt);
+ if (is_for_simd && octx->for_simd_scan_phase)
+ is_simd = false;
if (is_simd)
if (tree c = omp_find_clause (gimple_omp_for_clauses (octx->stmt),
OMP_CLAUSE__SIMDUID_))
@@ -8866,16 +9191,15 @@ lower_omp_scan (gimple_stmt_iterator *gsi_p, omp_context *ctx)
}
}
}
- else if (has_clauses)
- sorry_at (gimple_location (stmt),
- "%<#pragma omp scan%> not supported yet");
- if (!is_for)
+ if (is_simd && !is_for_simd)
{
gsi_insert_seq_after (gsi_p, gimple_omp_body (stmt), GSI_SAME_STMT);
gsi_insert_seq_after (gsi_p, before, GSI_SAME_STMT);
gsi_replace (gsi_p, gimple_build_nop (), true);
+ return;
}
- else if (before)
+ lower_omp (gimple_omp_body_ptr (stmt), octx);
+ if (before)
{
gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (stmt));
gsi_insert_seq_before (&gsi, before, GSI_SAME_STMT);
@@ -9102,7 +9426,7 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
/* Callback for walk_gimple_seq. Find #pragma omp scan statement. */
-tree
+static tree
omp_find_scan (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
struct walk_stmt_info *wi)
{
@@ -9113,6 +9437,12 @@ omp_find_scan (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
{
WALK_SUBSTMTS;
+ case GIMPLE_OMP_FOR:
+ if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD
+ && gimple_omp_for_combined_into_p (stmt))
+ *handled_ops_p = false;
+ break;
+
case GIMPLE_OMP_SCAN:
*(gimple_stmt_iterator *) (wi->info) = *gsi_p;
return integer_zero_node;
@@ -9238,8 +9568,8 @@ omp_find_scan (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
for (i = 0; i < n; i = i + 1)
{
{
- // For UDRs, this is UDR merge (rprivb[ivar], var2); r = rprivb[ivar];
- r = rprivb[ivar] + var2;
+ // For UDRs, this is r = var2; UDR merge (r, rprivb[ivar]);
+ r = var2 + rprivb[ivar];
}
{
// This is the scan phase from user code.
@@ -9253,6 +9583,7 @@ static void
lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
struct omp_for_data *fd, omp_context *ctx)
{
+ bool is_for_simd = gimple_omp_for_combined_p (stmt);
gcc_assert (ctx->scan_inclusive || ctx->scan_exclusive);
gimple_seq body = gimple_omp_body (stmt);
@@ -9297,6 +9628,45 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
gcc_assert (scan_stmt2 && gimple_code (scan_stmt2) == GIMPLE_OMP_SCAN);
gimple_omp_set_body (scan_stmt2, scan_body);
+ gimple_stmt_iterator input3_gsi = gsi_none ();
+ gimple_stmt_iterator scan3_gsi = gsi_none ();
+ gimple_stmt_iterator input4_gsi = gsi_none ();
+ gimple_stmt_iterator scan4_gsi = gsi_none ();
+ gimple *input_stmt3 = NULL, *scan_stmt3 = NULL;
+ gimple *input_stmt4 = NULL, *scan_stmt4 = NULL;
+ omp_context *input_simd_ctx = NULL, *scan_simd_ctx = NULL;
+ if (is_for_simd)
+ {
+ memset (&wi, 0, sizeof (wi));
+ wi.val_only = true;
+ wi.info = (void *) &input3_gsi;
+ walk_gimple_seq_mod (&input_body, omp_find_scan, NULL, &wi);
+ gcc_assert (!gsi_end_p (input3_gsi));
+
+ input_stmt3 = gsi_stmt (input3_gsi);
+ gsi = input3_gsi;
+ gsi_next (&gsi);
+ scan3_gsi = gsi;
+ scan_stmt3 = gsi_stmt (gsi);
+ gcc_assert (scan_stmt3 && gimple_code (scan_stmt3) == GIMPLE_OMP_SCAN);
+
+ memset (&wi, 0, sizeof (wi));
+ wi.val_only = true;
+ wi.info = (void *) &input4_gsi;
+ walk_gimple_seq_mod (&scan_body, omp_find_scan, NULL, &wi);
+ gcc_assert (!gsi_end_p (input4_gsi));
+
+ input_stmt4 = gsi_stmt (input4_gsi);
+ gsi = input4_gsi;
+ gsi_next (&gsi);
+ scan4_gsi = gsi;
+ scan_stmt4 = gsi_stmt (gsi);
+ gcc_assert (scan_stmt4 && gimple_code (scan_stmt4) == GIMPLE_OMP_SCAN);
+
+ input_simd_ctx = maybe_lookup_ctx (input_stmt3)->outer;
+ scan_simd_ctx = maybe_lookup_ctx (input_stmt4)->outer;
+ }
+
tree num_threads = create_tmp_var (integer_type_node);
tree thread_num = create_tmp_var (integer_type_node);
tree nthreads_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
@@ -9388,12 +9758,22 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
x = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (rprivb), rprivb, x);
tree rprivb_ref = build_simple_mem_ref_loc (clause_loc, x);
+ tree var4 = is_for_simd ? new_var : var2;
+ tree var5 = NULL_TREE, var6 = NULL_TREE;
+ if (is_for_simd)
+ {
+ var5 = lookup_decl (var, input_simd_ctx);
+ var6 = lookup_decl (var, scan_simd_ctx);
+ if (new_vard != new_var)
+ {
+ var5 = build_simple_mem_ref_loc (clause_loc, var5);
+ var6 = build_simple_mem_ref_loc (clause_loc, var6);
+ }
+ }
if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
{
tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
tree val = var2;
- if (new_vard != new_var)
- val = build_fold_addr_expr_loc (clause_loc, val);
x = lang_hooks.decls.omp_clause_default_ctor
(c, var2, build_outer_var_ref (var, ctx));
@@ -9401,16 +9781,19 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
gimplify_and_add (x, &clist);
x = build_outer_var_ref (var, ctx);
- x = lang_hooks.decls.omp_clause_assign_op (c, var2, x);
+ x = lang_hooks.decls.omp_clause_assign_op (c, unshare_expr (var4),
+ x);
gimplify_and_add (x, &thr01_list);
tree y = (DECL_HAS_VALUE_EXPR_P (new_vard)
? DECL_VALUE_EXPR (new_vard) : NULL_TREE);
if (var3)
{
- x = lang_hooks.decls.omp_clause_assign_op (c, var2, var3);
+ x = unshare_expr (var4);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
gimplify_and_add (x, &thrn1_list);
- x = lang_hooks.decls.omp_clause_assign_op (c, var2, var3);
+ x = unshare_expr (var4);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x, var3);
gimplify_and_add (x, &thr02_list);
}
else if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c))
@@ -9418,8 +9801,13 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
/* Otherwise, assign to it the identity element. */
gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c);
tseq = copy_gimple_seq_and_replace_locals (tseq);
- SET_DECL_VALUE_EXPR (new_vard, val);
- DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
+ if (!is_for_simd)
+ {
+ if (new_vard != new_var)
+ val = build_fold_addr_expr_loc (clause_loc, val);
+ SET_DECL_VALUE_EXPR (new_vard, val);
+ DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
+ }
SET_DECL_VALUE_EXPR (placeholder, error_mark_node);
DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
lower_omp (&tseq, ctx);
@@ -9439,39 +9827,64 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
}
}
- x = lang_hooks.decls.omp_clause_assign_op (c, var2, rprivam1_ref);
+ x = unshare_expr (var4);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x, rprivam1_ref);
gimplify_and_add (x, &thrn2_list);
- if (ctx->scan_exclusive)
+ if (is_for_simd)
{
x = unshare_expr (rprivb_ref);
- x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x, var5);
gimplify_and_add (x, &scan1_list);
}
+ else
+ {
+ if (ctx->scan_exclusive)
+ {
+ x = unshare_expr (rprivb_ref);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
+ gimplify_and_add (x, &scan1_list);
+ }
- gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
- tseq = copy_gimple_seq_and_replace_locals (tseq);
- SET_DECL_VALUE_EXPR (placeholder, var2);
- DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
- lower_omp (&tseq, ctx);
- gimple_seq_add_seq (&scan1_list, tseq);
+ gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
+ tseq = copy_gimple_seq_and_replace_locals (tseq);
+ SET_DECL_VALUE_EXPR (placeholder, var2);
+ DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
+ lower_omp (&tseq, ctx);
+ gimple_seq_add_seq (&scan1_list, tseq);
- if (ctx->scan_inclusive)
- {
- x = unshare_expr (rprivb_ref);
- x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
- gimplify_and_add (x, &scan1_list);
+ if (ctx->scan_inclusive)
+ {
+ x = unshare_expr (rprivb_ref);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
+ gimplify_and_add (x, &scan1_list);
+ }
}
x = unshare_expr (rpriva_ref);
- x = lang_hooks.decls.omp_clause_assign_op (c, x, var2);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x,
+ unshare_expr (var4));
gimplify_and_add (x, &mdlist);
- tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
+ x = unshare_expr (is_for_simd ? var6 : new_var);
+ x = lang_hooks.decls.omp_clause_assign_op (c, x, var4);
+ gimplify_and_add (x, &input2_list);
+
+ val = rprivb_ref;
+ if (new_vard != new_var)
+ val = build_fold_addr_expr_loc (clause_loc, val);
+
+ gimple_seq tseq = OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c);
tseq = copy_gimple_seq_and_replace_locals (tseq);
SET_DECL_VALUE_EXPR (new_vard, val);
DECL_HAS_VALUE_EXPR_P (new_vard) = 1;
- SET_DECL_VALUE_EXPR (placeholder, rprivb_ref);
+ if (is_for_simd)
+ {
+ SET_DECL_VALUE_EXPR (placeholder, var6);
+ DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
+ }
+ else
+ DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
lower_omp (&tseq, ctx);
if (y)
SET_DECL_VALUE_EXPR (new_vard, y);
@@ -9480,12 +9893,14 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
DECL_HAS_VALUE_EXPR_P (new_vard) = 0;
SET_DECL_VALUE_EXPR (new_vard, NULL_TREE);
}
+ if (!is_for_simd)
+ {
+ SET_DECL_VALUE_EXPR (placeholder, new_var);
+ DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
+ lower_omp (&tseq, ctx);
+ }
gimple_seq_add_seq (&input2_list, tseq);
- x = unshare_expr (new_var);
- x = lang_hooks.decls.omp_clause_assign_op (c, x, rprivb_ref);
- gimplify_and_add (x, &input2_list);
-
x = build_outer_var_ref (var, ctx);
x = lang_hooks.decls.omp_clause_assign_op (c, x, rpriva_ref);
gimplify_and_add (x, &last_list);
@@ -9522,29 +9937,38 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
else
{
x = build_outer_var_ref (var, ctx);
- gimplify_assign (var2, x, &thr01_list);
+ gimplify_assign (unshare_expr (var4), x, &thr01_list);
x = omp_reduction_init (c, TREE_TYPE (new_var));
- gimplify_assign (var2, unshare_expr (x), &thrn1_list);
- gimplify_assign (var2, x, &thr02_list);
+ gimplify_assign (unshare_expr (var4), unshare_expr (x),
+ &thrn1_list);
+ gimplify_assign (unshare_expr (var4), x, &thr02_list);
- gimplify_assign (var2, rprivam1_ref, &thrn2_list);
+ gimplify_assign (unshare_expr (var4), rprivam1_ref, &thrn2_list);
enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
if (code == MINUS_EXPR)
code = PLUS_EXPR;
- if (ctx->scan_exclusive)
- gimplify_assign (unshare_expr (rprivb_ref), var2, &scan1_list);
- x = build2 (code, TREE_TYPE (new_var), var2, new_var);
- gimplify_assign (var2, x, &scan1_list);
- if (ctx->scan_inclusive)
- gimplify_assign (unshare_expr (rprivb_ref), var2, &scan1_list);
+ if (is_for_simd)
+ gimplify_assign (unshare_expr (rprivb_ref), var5, &scan1_list);
+ else
+ {
+ if (ctx->scan_exclusive)
+ gimplify_assign (unshare_expr (rprivb_ref), var2,
+ &scan1_list);
+ x = build2 (code, TREE_TYPE (new_var), var2, new_var);
+ gimplify_assign (var2, x, &scan1_list);
+ if (ctx->scan_inclusive)
+ gimplify_assign (unshare_expr (rprivb_ref), var2,
+ &scan1_list);
+ }
- gimplify_assign (unshare_expr (rpriva_ref), var2, &mdlist);
+ gimplify_assign (unshare_expr (rpriva_ref), unshare_expr (var4),
+ &mdlist);
- x = build2 (code, TREE_TYPE (new_var), rprivb_ref, var2);
- gimplify_assign (new_var, x, &input2_list);
+ x = build2 (code, TREE_TYPE (new_var), var4, rprivb_ref);
+ gimplify_assign (is_for_simd ? var6 : new_var, x, &input2_list);
gimplify_assign (build_outer_var_ref (var, ctx), rpriva_ref,
&last_list);
@@ -9558,7 +9982,8 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
gimple_seq_add_stmt (&scan1_list, g);
g = gimple_build_assign (ivar, PLUS_EXPR, ivar, size_one_node);
- gimple_seq_add_stmt (gimple_omp_body_ptr (scan_stmt2), g);
+ gimple_seq_add_stmt (gimple_omp_body_ptr (is_for_simd
+ ? scan_stmt4 : scan_stmt2), g);
tree controlb = create_tmp_var (boolean_type_node);
tree controlp = create_tmp_var (ptr_type_node);
@@ -9588,8 +10013,29 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
*cp2 = gimple_omp_for_clauses (new_stmt);
gimple_omp_for_set_clauses (new_stmt, new_clauses2);
- gimple_omp_set_body (scan_stmt1, scan1_list);
- gimple_omp_set_body (input_stmt2, input2_list);
+ if (is_for_simd)
+ {
+ gimple_seq_add_seq (gimple_omp_body_ptr (scan_stmt3), scan1_list);
+ gimple_seq_add_seq (gimple_omp_body_ptr (input_stmt4), input2_list);
+
+ gsi_insert_seq_after (&input3_gsi, gimple_omp_body (input_stmt3),
+ GSI_SAME_STMT);
+ gsi_remove (&input3_gsi, true);
+ gsi_insert_seq_after (&scan3_gsi, gimple_omp_body (scan_stmt3),
+ GSI_SAME_STMT);
+ gsi_remove (&scan3_gsi, true);
+ gsi_insert_seq_after (&input4_gsi, gimple_omp_body (input_stmt4),
+ GSI_SAME_STMT);
+ gsi_remove (&input4_gsi, true);
+ gsi_insert_seq_after (&scan4_gsi, gimple_omp_body (scan_stmt4),
+ GSI_SAME_STMT);
+ gsi_remove (&scan4_gsi, true);
+ }
+ else
+ {
+ gimple_omp_set_body (scan_stmt1, scan1_list);
+ gimple_omp_set_body (input_stmt2, input2_list);
+ }
gsi_insert_seq_after (&input1_gsi, gimple_omp_body (input_stmt1),
GSI_SAME_STMT);
@@ -9699,6 +10145,7 @@ lower_omp_for_scan (gimple_seq *body_p, gimple_seq *dlist, gomp_for *stmt,
gimple_seq_add_stmt (body_p, g);
tree cplx = create_tmp_var (build_complex_type (unsigned_type_node, false));
+ DECL_GIMPLE_REG_P (cplx) = 1;
g = gimple_build_call_internal (IFN_MUL_OVERFLOW, 2, thread_nump1, twok);
gimple_call_set_lhs (g, cplx);
gimple_seq_add_stmt (body_p, g);
@@ -12180,8 +12627,12 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
if (tree *v = up->lastprivate_conditional_map->get (lhs))
{
tree clauses;
- if (up->combined_into_simd_safelen0)
- up = up->outer;
+ if (up->combined_into_simd_safelen1)
+ {
+ up = up->outer;
+ if (gimple_code (up->stmt) == GIMPLE_OMP_SCAN)
+ up = up->outer;
+ }
if (gimple_code (up->stmt) == GIMPLE_OMP_FOR)
clauses = gimple_omp_for_clauses (up->stmt);
else
diff --git a/gcc/omp-offload.c b/gcc/omp-offload.c
index c8a281c..da788d9 100644
--- a/gcc/omp-offload.c
+++ b/gcc/omp-offload.c
@@ -389,8 +389,8 @@ oacc_xform_loop (gcall *call)
|| !global_options_set.x_flag_tree_loop_vectorize))
{
basic_block bb = gsi_bb (gsi);
- struct loop *parent = bb->loop_father;
- struct loop *body = parent->inner;
+ class loop *parent = bb->loop_father;
+ class loop *body = parent->inner;
parent->force_vectorize = true;
parent->safelen = INT_MAX;
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index 472e202..caa8da3 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -1194,7 +1194,7 @@ simd_clone_adjust (struct cgraph_node *node)
gimple *g;
basic_block incr_bb = NULL;
- struct loop *loop = NULL;
+ class loop *loop = NULL;
/* Create a new BB right before the original exit BB, to hold the
iteration increment and the condition/branch. */
diff --git a/gcc/optabs-query.c b/gcc/optabs-query.c
index 4116bfe..2a06696 100644
--- a/gcc/optabs-query.c
+++ b/gcc/optabs-query.c
@@ -120,7 +120,7 @@ get_traditional_extraction_insn (extraction_insn *insn,
POS_OP is the operand number of the bit position. */
static bool
-get_optab_extraction_insn (struct extraction_insn *insn,
+get_optab_extraction_insn (class extraction_insn *insn,
enum extraction_type type,
machine_mode mode, direct_optab reg_optab,
direct_optab misalign_optab, int pos_op)
diff --git a/gcc/optabs-query.h b/gcc/optabs-query.h
index b0f50a9..d998fca 100644
--- a/gcc/optabs-query.h
+++ b/gcc/optabs-query.h
@@ -144,8 +144,9 @@ get_vcond_eq_icode (machine_mode vmode, machine_mode cmode)
enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
/* Describes an instruction that inserts or extracts a bitfield. */
-struct extraction_insn
+class extraction_insn
{
+public:
/* The code of the instruction. */
enum insn_code icode;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 18ca737..06bcaab 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -250,7 +250,7 @@ rtx
expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
rtx target, int unsignedp)
{
- struct expand_operand eops[4];
+ class expand_operand eops[4];
tree oprnd0, oprnd1, oprnd2;
machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
optab widen_pattern_optab;
@@ -344,7 +344,7 @@ rtx
expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
rtx op1, rtx op2, rtx target, int unsignedp)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
enum insn_code icode = optab_handler (ternary_optab, mode);
gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
@@ -413,7 +413,7 @@ expand_vector_broadcast (machine_mode vmode, rtx op)
insn_code icode = optab_handler (vec_duplicate_optab, vmode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
create_output_operand (&ops[0], NULL_RTX, vmode);
create_input_operand (&ops[1], op, GET_MODE (op));
expand_insn (icode, 2, ops);
@@ -1039,7 +1039,7 @@ expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
machine_mode mode0, mode1, tmp_mode;
- struct expand_operand ops[3];
+ class expand_operand ops[3];
bool commutative_p;
rtx_insn *pat;
rtx xop0 = op0, xop1 = op1;
@@ -2012,7 +2012,7 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
enum insn_code icode = optab_handler (unoptab, mode);
create_fixed_operand (&ops[0], targ0);
@@ -2084,7 +2084,7 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
enum insn_code icode = optab_handler (binoptab, mode);
machine_mode mode0 = insn_data[icode].operand[1].mode;
machine_mode mode1 = insn_data[icode].operand[2].mode;
@@ -2724,7 +2724,7 @@ expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
{
if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
enum insn_code icode = optab_handler (unoptab, mode);
rtx_insn *last = get_last_insn ();
rtx_insn *pat;
@@ -2972,6 +2972,17 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
return target;
}
+ /* Emit ~op0 as op0 ^ -1. */
+ if (unoptab == one_cmpl_optab
+ && (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+ && optab_handler (xor_optab, mode) != CODE_FOR_nothing)
+ {
+ temp = expand_binop (mode, xor_optab, op0, CONSTM1_RTX (mode),
+ target, unsignedp, OPTAB_DIRECT);
+ if (temp)
+ return temp;
+ }
+
if (optab_to_code (unoptab) == NEG)
{
/* Try negating floating point values by flipping the sign bit. */
@@ -3578,7 +3589,7 @@ bool
maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
enum rtx_code code)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
rtx_insn *pat;
create_output_operand (&ops[0], target, GET_MODE (target));
@@ -4289,7 +4300,7 @@ emit_indirect_jump (rtx loc)
sorry ("indirect jumps are not available on this target");
else
{
- struct expand_operand ops[1];
+ class expand_operand ops[1];
create_address_operand (&ops[0], loc);
expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
emit_barrier ();
@@ -4394,7 +4405,7 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
OPTAB_WIDEN, &comparison, &cmpmode);
if (comparison)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
create_output_operand (&ops[0], target, mode);
create_fixed_operand (&ops[1], comparison);
@@ -4460,7 +4471,7 @@ emit_conditional_neg_or_complement (rtx target, rtx_code code,
target = gen_reg_rtx (mode);
rtx_insn *last = get_last_insn ();
- struct expand_operand ops[4];
+ class expand_operand ops[4];
create_output_operand (&ops[0], target, mode);
create_fixed_operand (&ops[1], cond);
@@ -4548,7 +4559,7 @@ emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
&comparison, &cmode);
if (comparison)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
create_output_operand (&ops[0], target, mode);
create_fixed_operand (&ops[1], comparison);
@@ -5414,7 +5425,7 @@ vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
tree t_op0, tree t_op1, bool unsignedp,
enum insn_code icode, unsigned int opno)
{
- struct expand_operand ops[2];
+ class expand_operand ops[2];
rtx rtx_op0, rtx_op1;
machine_mode m0, m1;
enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
@@ -5509,7 +5520,7 @@ expand_vec_perm_1 (enum insn_code icode, rtx target,
{
machine_mode tmode = GET_MODE (target);
machine_mode smode = GET_MODE (sel);
- struct expand_operand ops[4];
+ class expand_operand ops[4];
gcc_assert (GET_MODE_CLASS (smode) == MODE_VECTOR_INT
|| mode_for_int_vector (tmode).require () == smode);
@@ -5596,7 +5607,7 @@ expand_vec_perm_const (machine_mode mode, rtx v0, rtx v1,
rtx shift_amt = shift_amt_for_vec_perm_mask (mode, indices, shift_optab);
if (shift_amt)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
if (shift_code != CODE_FOR_nothing)
{
create_output_operand (&ops[0], target, mode);
@@ -5782,7 +5793,7 @@ rtx
expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
rtx target)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
machine_mode mode = TYPE_MODE (vec_cond_type);
machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0));
enum insn_code icode = get_vcond_mask_icode (mode, mask_mode);
@@ -5814,7 +5825,7 @@ rtx
expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
rtx target)
{
- struct expand_operand ops[6];
+ class expand_operand ops[6];
enum insn_code icode;
rtx comparison, rtx_op1, rtx_op2;
machine_mode mode = TYPE_MODE (vec_cond_type);
@@ -5884,7 +5895,7 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
rtx
expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
enum insn_code icode;
machine_mode emode = GET_MODE_INNER (vmode);
@@ -5904,7 +5915,7 @@ expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
rtx
expand_vec_cmp_expr (tree type, tree exp, rtx target)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
enum insn_code icode;
rtx comparison;
machine_mode mask_mode = TYPE_MODE (type);
@@ -5945,7 +5956,7 @@ rtx
expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
rtx target, bool uns_p)
{
- struct expand_operand eops[3];
+ class expand_operand eops[3];
enum insn_code icode;
int method, i;
machine_mode wmode;
@@ -6098,7 +6109,7 @@ maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
icode = direct_optab_handler (atomic_exchange_optab, mode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[4];
+ class expand_operand ops[4];
create_output_operand (&ops[0], target, mode);
create_fixed_operand (&ops[1], mem);
@@ -6136,7 +6147,7 @@ maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
create_output_operand (&ops[0], target, mode);
create_fixed_operand (&ops[1], mem);
create_input_operand (&ops[2], val, mode);
@@ -6196,7 +6207,7 @@ static rtx
maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
{
machine_mode pat_bool_mode;
- struct expand_operand ops[3];
+ class expand_operand ops[3];
if (!targetm.have_atomic_test_and_set ())
return NULL_RTX;
@@ -6366,7 +6377,7 @@ expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
enum memmodel fail_model)
{
machine_mode mode = GET_MODE (mem);
- struct expand_operand ops[8];
+ class expand_operand ops[8];
enum insn_code icode;
rtx target_oval, target_bool = NULL_RTX;
rtx libfunc;
@@ -6568,7 +6579,7 @@ expand_atomic_load (rtx target, rtx mem, enum memmodel model)
icode = direct_optab_handler (atomic_load_optab, mode);
if (icode != CODE_FOR_nothing)
{
- struct expand_operand ops[3];
+ class expand_operand ops[3];
rtx_insn *last = get_last_insn ();
if (is_mm_seq_cst (model))
expand_memory_blockage ();
@@ -6621,7 +6632,7 @@ expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
{
machine_mode mode = GET_MODE (mem);
enum insn_code icode;
- struct expand_operand ops[3];
+ class expand_operand ops[3];
/* If the target supports the store directly, great. */
icode = direct_optab_handler (atomic_store_optab, mode);
@@ -6831,7 +6842,7 @@ maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
rtx val, bool use_memmodel, enum memmodel model, bool after)
{
machine_mode mode = GET_MODE (mem);
- struct expand_operand ops[4];
+ class expand_operand ops[4];
enum insn_code icode;
int op_counter = 0;
int num_ops;
@@ -7145,7 +7156,7 @@ valid_multiword_target_p (rtx target)
of that rtx if so. */
void
-create_integer_operand (struct expand_operand *op, poly_int64 intval)
+create_integer_operand (class expand_operand *op, poly_int64 intval)
{
create_expand_operand (op, EXPAND_INTEGER,
gen_int_mode (intval, MAX_MODE_INT),
@@ -7157,7 +7168,7 @@ create_integer_operand (struct expand_operand *op, poly_int64 intval)
static bool
maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
- struct expand_operand *op)
+ class expand_operand *op)
{
/* See if the operand matches in its current form. */
if (insn_operand_matches (icode, opno, op->value))
@@ -7199,20 +7210,18 @@ maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
static bool
maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
- struct expand_operand *op)
+ class expand_operand *op)
{
machine_mode mode, imode;
- bool old_volatile_ok, result;
mode = op->mode;
switch (op->type)
{
case EXPAND_FIXED:
- old_volatile_ok = volatile_ok;
- volatile_ok = true;
- result = maybe_legitimize_operand_same_code (icode, opno, op);
- volatile_ok = old_volatile_ok;
- return result;
+ {
+ temporary_volatile_ok v (true);
+ return maybe_legitimize_operand_same_code (icode, opno, op);
+ }
case EXPAND_OUTPUT:
gcc_assert (mode != VOIDmode);
@@ -7281,7 +7290,7 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
TYPE is the type of VALUE. */
void
-create_convert_operand_from_type (struct expand_operand *op,
+create_convert_operand_from_type (class expand_operand *op,
rtx value, tree type)
{
create_convert_operand_from (op, value, TYPE_MODE (type),
@@ -7296,8 +7305,8 @@ create_convert_operand_from_type (struct expand_operand *op,
static inline bool
can_reuse_operands_p (enum insn_code icode,
unsigned int opno1, unsigned int opno2,
- const struct expand_operand *op1,
- const struct expand_operand *op2)
+ const class expand_operand *op1,
+ const class expand_operand *op2)
{
/* Check requirements that are common to all types. */
if (op1->type != op2->type
@@ -7332,7 +7341,7 @@ can_reuse_operands_p (enum insn_code icode,
bool
maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
- unsigned int nops, struct expand_operand *ops)
+ unsigned int nops, class expand_operand *ops)
{
rtx_insn *last = get_last_insn ();
rtx *orig_values = XALLOCAVEC (rtx, nops);
@@ -7374,7 +7383,7 @@ maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
rtx_insn *
maybe_gen_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops)
+ class expand_operand *ops)
{
gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
if (!maybe_legitimize_operands (icode, 0, nops, ops))
@@ -7418,7 +7427,7 @@ maybe_gen_insn (enum insn_code icode, unsigned int nops,
bool
maybe_expand_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops)
+ class expand_operand *ops)
{
rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
if (pat)
@@ -7433,7 +7442,7 @@ maybe_expand_insn (enum insn_code icode, unsigned int nops,
bool
maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops)
+ class expand_operand *ops)
{
rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
if (pat)
@@ -7449,7 +7458,7 @@ maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
void
expand_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops)
+ class expand_operand *ops)
{
if (!maybe_expand_insn (icode, nops, ops))
gcc_unreachable ();
@@ -7459,7 +7468,7 @@ expand_insn (enum insn_code icode, unsigned int nops,
void
expand_jump_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops)
+ class expand_operand *ops)
{
if (!maybe_expand_jump_insn (icode, nops, ops))
gcc_unreachable ();
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 17b5dfb..0654107 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -41,7 +41,8 @@ enum expand_operand_type {
};
/* Information about an operand for instruction expansion. */
-struct expand_operand {
+class expand_operand {
+public:
/* The type of operand. */
ENUM_BITFIELD (expand_operand_type) type : 8;
@@ -70,7 +71,7 @@ struct expand_operand {
to their default values. */
static inline void
-create_expand_operand (struct expand_operand *op,
+create_expand_operand (class expand_operand *op,
enum expand_operand_type type,
rtx value, machine_mode mode,
bool unsigned_p, poly_int64 int_value = 0)
@@ -86,7 +87,7 @@ create_expand_operand (struct expand_operand *op,
/* Make OP describe an operand that must use rtx X, even if X is volatile. */
static inline void
-create_fixed_operand (struct expand_operand *op, rtx x)
+create_fixed_operand (class expand_operand *op, rtx x)
{
create_expand_operand (op, EXPAND_FIXED, x, VOIDmode, false);
}
@@ -97,7 +98,7 @@ create_fixed_operand (struct expand_operand *op, rtx x)
be ignored in that case. */
static inline void
-create_output_operand (struct expand_operand *op, rtx x,
+create_output_operand (class expand_operand *op, rtx x,
machine_mode mode)
{
create_expand_operand (op, EXPAND_OUTPUT, x, mode, false);
@@ -109,7 +110,7 @@ create_output_operand (struct expand_operand *op, rtx x,
as an operand. */
static inline void
-create_input_operand (struct expand_operand *op, rtx value,
+create_input_operand (class expand_operand *op, rtx value,
machine_mode mode)
{
create_expand_operand (op, EXPAND_INPUT, value, mode, false);
@@ -119,7 +120,7 @@ create_input_operand (struct expand_operand *op, rtx value,
to mode MODE. UNSIGNED_P says whether VALUE is unsigned. */
static inline void
-create_convert_operand_to (struct expand_operand *op, rtx value,
+create_convert_operand_to (class expand_operand *op, rtx value,
machine_mode mode, bool unsigned_p)
{
create_expand_operand (op, EXPAND_CONVERT_TO, value, mode, unsigned_p);
@@ -131,7 +132,7 @@ create_convert_operand_to (struct expand_operand *op, rtx value,
UNSIGNED_P says whether VALUE is unsigned. */
static inline void
-create_convert_operand_from (struct expand_operand *op, rtx value,
+create_convert_operand_from (class expand_operand *op, rtx value,
machine_mode mode, bool unsigned_p)
{
create_expand_operand (op, EXPAND_CONVERT_FROM, value, mode, unsigned_p);
@@ -142,12 +143,12 @@ create_convert_operand_from (struct expand_operand *op, rtx value,
of the address, but it may need to be converted to Pmode first. */
static inline void
-create_address_operand (struct expand_operand *op, rtx value)
+create_address_operand (class expand_operand *op, rtx value)
{
create_expand_operand (op, EXPAND_ADDRESS, value, Pmode, false);
}
-extern void create_integer_operand (struct expand_operand *, poly_int64);
+extern void create_integer_operand (class expand_operand *, poly_int64);
/* Passed to expand_simple_binop and expand_binop to say which options
to try to use if the requested operation can't be open-coded on the
@@ -335,21 +336,21 @@ rtx expand_atomic_fetch_op (rtx, rtx, rtx, enum rtx_code, enum memmodel,
extern bool insn_operand_matches (enum insn_code icode, unsigned int opno,
rtx operand);
extern bool valid_multiword_target_p (rtx);
-extern void create_convert_operand_from_type (struct expand_operand *op,
+extern void create_convert_operand_from_type (class expand_operand *op,
rtx value, tree type);
extern bool maybe_legitimize_operands (enum insn_code icode,
unsigned int opno, unsigned int nops,
- struct expand_operand *ops);
+ class expand_operand *ops);
extern rtx_insn *maybe_gen_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops);
+ class expand_operand *ops);
extern bool maybe_expand_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops);
+ class expand_operand *ops);
extern bool maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops);
+ class expand_operand *ops);
extern void expand_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops);
+ class expand_operand *ops);
extern void expand_jump_insn (enum insn_code icode, unsigned int nops,
- struct expand_operand *ops);
+ class expand_operand *ops);
extern enum rtx_code get_rtx_code (enum tree_code tcode, bool unsignedp);
diff --git a/gcc/optinfo.h b/gcc/optinfo.h
index 670b09a..04786b4 100644
--- a/gcc/optinfo.h
+++ b/gcc/optinfo.h
@@ -65,7 +65,7 @@ along with GCC; see the file COPYING3. If not see
/* Forward decls. */
-struct opt_pass;
+class opt_pass;
class optinfo_item;
/* Return true if any of the active optinfo destinations make use
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index 660dfe6..e3f9c54 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -537,7 +537,8 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
extra_args = 0;
- opt_index = find_opt (argv[0] + 1, lang_mask);
+ const char *opt_value = argv[0] + 1;
+ opt_index = find_opt (opt_value, lang_mask);
i = 0;
while (opt_index == OPT_SPECIAL_unknown
&& i < ARRAY_SIZE (option_map))
@@ -745,6 +746,23 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
/* Check if this is a switch for a different front end. */
if (!option_ok_for_language (option, lang_mask))
errors |= CL_ERR_WRONG_LANG;
+ else if (strcmp (option->opt_text, "-Werror=") == 0
+ && strchr (opt_value, ',') == NULL)
+ {
+ /* Verify that -Werror argument is a valid warning
+ for a language. */
+ char *werror_arg = xstrdup (opt_value + 6);
+ werror_arg[0] = 'W';
+
+ size_t warning_index = find_opt (werror_arg, lang_mask);
+ if (warning_index != OPT_SPECIAL_unknown)
+ {
+ const struct cl_option *warning_option
+ = &cl_options[warning_index];
+ if (!option_ok_for_language (warning_option, lang_mask))
+ errors |= CL_ERR_WRONG_LANG;
+ }
+ }
/* Convert the argument to lowercase if appropriate. */
if (arg && option->cl_tolower)
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index bf4db77..7c5bd16 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -103,10 +103,14 @@ complain_wrong_lang (const struct cl_decoded_option *decoded,
text, bad_lang);
else if (lang_mask == CL_DRIVER)
gcc_unreachable ();
- else
+ else if (ok_langs[0] != '\0')
/* Eventually this should become a hard error IMO. */
warning (0, "command-line option %qs is valid for %s but not for %s",
text, ok_langs, bad_lang);
+ else
+ /* Happens for -Werror=warning_name. */
+ warning (0, "%<-Werror=%> argument %qs is not valid for %s",
+ text, bad_lang);
free (ok_langs);
free (bad_lang);
diff --git a/gcc/opts.c b/gcc/opts.c
index b38bfb1..46a19a2 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1282,8 +1282,9 @@ wrap_help (const char *help,
/* Data structure used to print list of valid option values. */
-struct option_help_tuple
+class option_help_tuple
{
+public:
option_help_tuple (int code, vec<const char *> values):
m_code (code), m_values (values)
{}
@@ -1801,8 +1802,9 @@ const struct sanitizer_opts_s coverage_sanitizer_opts[] =
/* A struct for describing a run of chars within a string. */
-struct string_fragment
+class string_fragment
{
+public:
string_fragment (const char *start, size_t len)
: m_start (start), m_len (len) {}
diff --git a/gcc/params.def b/gcc/params.def
index 4567c17..7d0dcae 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1109,12 +1109,6 @@ DEFPARAM (PARAM_IPA_CP_LOOP_HINT_BONUS,
"bounds or strides known.",
64, 0, 0)
-DEFPARAM (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS,
- "ipa-cp-array-index-hint-bonus",
- "Compile-time bonus IPA-CP assigns to candidates which make an array "
- "index known.",
- 48, 0, 0)
-
DEFPARAM (PARAM_IPA_MAX_AA_STEPS,
"ipa-max-aa-steps",
"Maximum number of statements that will be visited by IPA formal "
@@ -1437,6 +1431,12 @@ DEFPARAM(PARAM_HASH_TABLE_VERIFICATION_LIMIT,
"each searched element.",
10, 0, 0)
+DEFPARAM(PARAM_SSA_NAME_DEF_CHAIN_LIMIT,
+ "ssa-name-def-chain-limit",
+ "The maximum number of SSA_NAME assignments to follow in determining "
+ "a value.",
+ 512, 0, 0)
+
/*
Local variables:
diff --git a/gcc/passes.c b/gcc/passes.c
index c6331cb..bd56004 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -2182,7 +2182,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
static void
execute_one_ipa_transform_pass (struct cgraph_node *node,
- ipa_opt_pass_d *ipa_pass)
+ ipa_opt_pass_d *ipa_pass, bool do_not_collect)
{
opt_pass *pass = ipa_pass;
unsigned int todo_after = 0;
@@ -2228,14 +2228,14 @@ execute_one_ipa_transform_pass (struct cgraph_node *node,
redirect_edge_var_map_empty ();
/* Signal this is a suitable GC collection point. */
- if (!(todo_after & TODO_do_not_ggc_collect))
+ if (!do_not_collect && !(todo_after & TODO_do_not_ggc_collect))
ggc_collect ();
}
/* For the current function, execute all ipa transforms. */
void
-execute_all_ipa_transforms (void)
+execute_all_ipa_transforms (bool do_not_collect)
{
struct cgraph_node *node;
if (!cfun)
@@ -2247,7 +2247,8 @@ execute_all_ipa_transforms (void)
unsigned int i;
for (i = 0; i < node->ipa_transforms_to_apply.length (); i++)
- execute_one_ipa_transform_pass (node, node->ipa_transforms_to_apply[i]);
+ execute_one_ipa_transform_pass (node, node->ipa_transforms_to_apply[i],
+ do_not_collect);
node->ipa_transforms_to_apply.release ();
}
}
diff --git a/gcc/passes.def b/gcc/passes.def
index 9a5b0cd..1a7fd14 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -427,6 +427,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_rtl_doloop);
NEXT_PASS (pass_rtl_loop_done);
POP_INSERT_PASSES ()
+ NEXT_PASS (pass_lower_subreg2);
NEXT_PASS (pass_web);
NEXT_PASS (pass_rtl_cprop);
NEXT_PASS (pass_cse2);
@@ -440,7 +441,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_partition_blocks);
NEXT_PASS (pass_outof_cfg_layout_mode);
NEXT_PASS (pass_split_all_insns);
- NEXT_PASS (pass_lower_subreg2);
+ NEXT_PASS (pass_lower_subreg3);
NEXT_PASS (pass_df_initialize_no_opt);
NEXT_PASS (pass_stack_ptr_mod);
NEXT_PASS (pass_mode_switching);
diff --git a/gcc/poly-int.h b/gcc/poly-int.h
index d68a652..0ccdf68 100644
--- a/gcc/poly-int.h
+++ b/gcc/poly-int.h
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef HAVE_POLY_INT_H
#define HAVE_POLY_INT_H
-template<unsigned int N, typename T> class poly_int_pod;
+template<unsigned int N, typename T> struct poly_int_pod;
template<unsigned int N, typename T> class poly_int;
/* poly_coeff_traiits<T> describes the properties of a poly_int
@@ -335,7 +335,7 @@ struct poly_result<T1, T2, 2>
/* A base POD class for polynomial integers. The polynomial has N
coefficients of type C. */
template<unsigned int N, typename C>
-class poly_int_pod
+struct poly_int_pod
{
public:
template<typename Ca>
diff --git a/gcc/predict.c b/gcc/predict.c
index ad19d12..07f66aa 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -87,10 +87,10 @@ static void dump_prediction (FILE *, enum br_predictor, int, basic_block,
enum predictor_reason, edge);
static void predict_paths_leading_to (basic_block, enum br_predictor,
enum prediction,
- struct loop *in_loop = NULL);
+ class loop *in_loop = NULL);
static void predict_paths_leading_to_edge (edge, enum br_predictor,
enum prediction,
- struct loop *in_loop = NULL);
+ class loop *in_loop = NULL);
static bool can_predict_insn_p (const rtx_insn *);
static HOST_WIDE_INT get_predictor_value (br_predictor, HOST_WIDE_INT);
static void determine_unlikely_bbs ();
@@ -355,7 +355,7 @@ optimize_insn_for_speed_p (void)
/* Return TRUE when LOOP should be optimized for size. */
bool
-optimize_loop_for_size_p (struct loop *loop)
+optimize_loop_for_size_p (class loop *loop)
{
return optimize_bb_for_size_p (loop->header);
}
@@ -363,7 +363,7 @@ optimize_loop_for_size_p (struct loop *loop)
/* Return TRUE when LOOP should be optimized for speed. */
bool
-optimize_loop_for_speed_p (struct loop *loop)
+optimize_loop_for_speed_p (class loop *loop)
{
return optimize_bb_for_speed_p (loop->header);
}
@@ -371,9 +371,9 @@ optimize_loop_for_speed_p (struct loop *loop)
/* Return TRUE when LOOP nest should be optimized for speed. */
bool
-optimize_loop_nest_for_speed_p (struct loop *loop)
+optimize_loop_nest_for_speed_p (class loop *loop)
{
- struct loop *l = loop;
+ class loop *l = loop;
if (optimize_loop_for_speed_p (loop))
return true;
l = loop->inner;
@@ -399,7 +399,7 @@ optimize_loop_nest_for_speed_p (struct loop *loop)
/* Return TRUE when LOOP nest should be optimized for size. */
bool
-optimize_loop_nest_for_size_p (struct loop *loop)
+optimize_loop_nest_for_size_p (class loop *loop)
{
return !optimize_loop_nest_for_speed_p (loop);
}
@@ -1471,7 +1471,7 @@ get_base_value (tree t)
Otherwise return false and set LOOP_INVAIANT to NULL. */
static bool
-is_comparison_with_loop_invariant_p (gcond *stmt, struct loop *loop,
+is_comparison_with_loop_invariant_p (gcond *stmt, class loop *loop,
tree *loop_invariant,
enum tree_code *compare_code,
tree *loop_step,
@@ -1637,7 +1637,7 @@ predicted_by_loop_heuristics_p (basic_block bb)
In this loop, we will predict the branch inside the loop to be taken. */
static void
-predict_iv_comparison (struct loop *loop, basic_block bb,
+predict_iv_comparison (class loop *loop, basic_block bb,
tree loop_bound_var,
tree loop_iv_base_var,
enum tree_code loop_bound_code,
@@ -1896,9 +1896,9 @@ predict_extra_loop_exits (edge exit_edge)
static void
predict_loops (void)
{
- struct loop *loop;
+ class loop *loop;
basic_block bb;
- hash_set <struct loop *> with_recursion(10);
+ hash_set <class loop *> with_recursion(10);
FOR_EACH_BB_FN (bb, cfun)
{
@@ -1923,9 +1923,9 @@ predict_loops (void)
basic_block bb, *bbs;
unsigned j, n_exits = 0;
vec<edge> exits;
- struct tree_niter_desc niter_desc;
+ class tree_niter_desc niter_desc;
edge ex;
- struct nb_iter_bound *nb_iter;
+ class nb_iter_bound *nb_iter;
enum tree_code loop_bound_code = ERROR_MARK;
tree loop_bound_step = NULL;
tree loop_bound_var = NULL;
@@ -3135,7 +3135,7 @@ static void
predict_paths_for_bb (basic_block cur, basic_block bb,
enum br_predictor pred,
enum prediction taken,
- bitmap visited, struct loop *in_loop = NULL)
+ bitmap visited, class loop *in_loop = NULL)
{
edge e;
edge_iterator ei;
@@ -3201,7 +3201,7 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
static void
predict_paths_leading_to (basic_block bb, enum br_predictor pred,
- enum prediction taken, struct loop *in_loop)
+ enum prediction taken, class loop *in_loop)
{
predict_paths_for_bb (bb, bb, pred, taken, auto_bitmap (), in_loop);
}
@@ -3210,7 +3210,7 @@ predict_paths_leading_to (basic_block bb, enum br_predictor pred,
static void
predict_paths_leading_to_edge (edge e, enum br_predictor pred,
- enum prediction taken, struct loop *in_loop)
+ enum prediction taken, class loop *in_loop)
{
bool has_nonloop_edge = false;
edge_iterator ei;
@@ -3236,8 +3236,9 @@ predict_paths_leading_to_edge (edge e, enum br_predictor pred,
/* This is used to carry information about basic blocks. It is
attached to the AUX field of the standard CFG block. */
-struct block_info
+class block_info
{
+public:
/* Estimated frequency of execution of basic_block. */
sreal frequency;
@@ -3249,8 +3250,9 @@ struct block_info
};
/* Similar information for edges. */
-struct edge_prob_info
+class edge_prob_info
{
+public:
/* In case edge is a loopback edge, the probability edge will be reached
in case header is. Estimated number of iterations of the loop can be
then computed as 1 / (1 - back_edge_prob). */
@@ -3398,9 +3400,9 @@ propagate_freq (basic_block head, bitmap tovisit)
/* Estimate frequencies in loops at same nest level. */
static void
-estimate_loops_at_level (struct loop *first_loop)
+estimate_loops_at_level (class loop *first_loop)
{
- struct loop *loop;
+ class loop *loop;
for (loop = first_loop; loop; loop = loop->next)
{
@@ -4050,7 +4052,7 @@ pass_profile::execute (function *fun)
profile_status_for_fn (fun) = PROFILE_GUESSED;
if (dump_file && (dump_flags & TDF_DETAILS))
{
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
if (loop->header->count.initialized_p ())
fprintf (dump_file, "Loop got predicted %d to iterate %i times.\n",
diff --git a/gcc/predict.h b/gcc/predict.h
index c1f2f03..5149a97 100644
--- a/gcc/predict.h
+++ b/gcc/predict.h
@@ -68,10 +68,10 @@ extern bool optimize_edge_for_size_p (edge);
extern bool optimize_edge_for_speed_p (edge);
extern bool optimize_insn_for_size_p (void);
extern bool optimize_insn_for_speed_p (void);
-extern bool optimize_loop_for_size_p (struct loop *);
-extern bool optimize_loop_for_speed_p (struct loop *);
-extern bool optimize_loop_nest_for_speed_p (struct loop *);
-extern bool optimize_loop_nest_for_size_p (struct loop *);
+extern bool optimize_loop_for_size_p (class loop *);
+extern bool optimize_loop_for_speed_p (class loop *);
+extern bool optimize_loop_nest_for_speed_p (class loop *);
+extern bool optimize_loop_nest_for_size_p (class loop *);
extern bool predictable_edge_p (edge);
extern void rtl_profile_for_bb (basic_block);
extern void rtl_profile_for_edge (edge);
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index e4df659..2d03b3f 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -74,8 +74,9 @@ struct chunk_info
/* The output buffer datatype. This is best seen as an abstract datatype
whose fields should not be accessed directly by clients. */
-struct output_buffer
+class output_buffer
{
+public:
output_buffer ();
~output_buffer ();
@@ -214,8 +215,9 @@ class format_postprocessor
/* The data structure that contains the bare minimum required to do
proper pretty-printing. Clients may derived from this structure
and add additional fields they need. */
-struct pretty_printer
+class pretty_printer
{
+public:
/* Default construct a pretty printer with specified
maximum line length cut off limit. */
explicit pretty_printer (int = 0);
diff --git a/gcc/profile-count.c b/gcc/profile-count.c
index 2b774a7..6198675 100644
--- a/gcc/profile-count.c
+++ b/gcc/profile-count.c
@@ -125,7 +125,7 @@ profile_count::differs_from_p (profile_count other) const
/* Stream THIS from IB. */
profile_count
-profile_count::stream_in (struct lto_input_block *ib)
+profile_count::stream_in (class lto_input_block *ib)
{
profile_count ret;
ret.m_val = streamer_read_gcov_count (ib);
@@ -216,7 +216,7 @@ profile_probability::differs_lot_from_p (profile_probability other) const
/* Stream THIS from IB. */
profile_probability
-profile_probability::stream_in (struct lto_input_block *ib)
+profile_probability::stream_in (class lto_input_block *ib)
{
profile_probability ret;
ret.m_val = streamer_read_uhwi (ib);
diff --git a/gcc/profile-count.h b/gcc/profile-count.h
index cbab596..ef84ddc 100644
--- a/gcc/profile-count.h
+++ b/gcc/profile-count.h
@@ -22,7 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_PROFILE_COUNT_H
struct function;
-class profile_count;
+struct profile_count;
/* Quality of the profile count. Because gengtype does not support enums
inside of classes, this is in global namespace. */
@@ -154,7 +154,7 @@ class GTY((user)) profile_probability
uint32_t m_val : 29;
enum profile_quality m_quality : 3;
- friend class profile_count;
+ friend struct profile_count;
public:
profile_probability (): m_val (uninitialized_probability),
m_quality (GUESSED)
@@ -615,7 +615,7 @@ public:
profile_count count2) const;
/* LTO streaming support. */
- static profile_probability stream_in (struct lto_input_block *);
+ static profile_probability stream_in (class lto_input_block *);
void stream_out (struct output_block *);
void stream_out (struct lto_output_stream *);
};
@@ -676,7 +676,7 @@ public:
class sreal;
-class GTY(()) profile_count
+struct GTY(()) profile_count
{
public:
/* Use 62bit to hold basic block counters. Should be at least
@@ -1201,7 +1201,7 @@ public:
profile_quality quality = PRECISE);
/* LTO streaming support. */
- static profile_count stream_in (struct lto_input_block *);
+ static profile_count stream_in (class lto_input_block *);
void stream_out (struct output_block *);
void stream_out (struct lto_output_stream *);
};
diff --git a/gcc/profile.c b/gcc/profile.c
index e3f8c55..441cb8e 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -1370,7 +1370,7 @@ branch_prob (bool thunk)
if (flag_branch_probabilities
&& (profile_status_for_fn (cfun) == PROFILE_READ))
{
- struct loop *loop;
+ class loop *loop;
if (dump_file && (dump_flags & TDF_DETAILS))
report_predictor_hitrates ();
diff --git a/gcc/read-md.c b/gcc/read-md.c
index 8247640..d9a27ac 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -43,14 +43,6 @@ int have_error = 0;
#endif /* #ifndef GENERATOR_FILE */
-/* Associates PTR (which can be a string, etc.) with the file location
- specified by FILENAME and LINENO. */
-struct ptr_loc {
- const void *ptr;
- const char *filename;
- int lineno;
-};
-
/* This callback will be invoked whenever an md include directive is
processed. To be used for creation of the dependency file. */
void (*include_callback) (const char *);
@@ -94,25 +86,24 @@ leading_ptr_eq_p (const void *def1, const void *def2)
return *(const void *const *) def1 == *(const void *const *) def2;
}
-/* Associate PTR with the file position given by FILENAME and LINENO. */
+/* Associate PTR with the file position given by FILE_LOC. */
void
-md_reader::set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
+md_reader::set_md_ptr_loc (const void *ptr, file_location file_loc)
{
struct ptr_loc *loc;
loc = (struct ptr_loc *) obstack_alloc (&m_ptr_loc_obstack,
sizeof (struct ptr_loc));
loc->ptr = ptr;
- loc->filename = filename;
- loc->lineno = lineno;
+ loc->loc = file_loc;
*htab_find_slot (m_ptr_locs, loc, INSERT) = loc;
}
/* Return the position associated with pointer PTR. Return null if no
position was set. */
-const struct ptr_loc *
+const md_reader::ptr_loc *
md_reader::get_md_ptr_loc (const void *ptr)
{
return (const struct ptr_loc *) htab_find (m_ptr_locs, &ptr);
@@ -125,7 +116,7 @@ md_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
{
const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
if (loc != 0)
- set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
+ set_md_ptr_loc (new_ptr, loc->loc);
}
/* If PTR is associated with a known file position, print a #line
@@ -136,7 +127,7 @@ md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
{
const struct ptr_loc *loc = get_md_ptr_loc (ptr);
if (loc != 0)
- fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename);
+ fprintf (outf, "#line %d \"%s\"\n", loc->loc.lineno, loc->loc.filename);
}
/* Special fprint_md_ptr_loc for writing to STDOUT. */
@@ -672,7 +663,7 @@ md_reader::read_string (int star_if_braced)
{
char *stringbuf;
int saw_paren = 0;
- int c, old_lineno;
+ int c;
c = read_skip_spaces ();
if (c == '(')
@@ -681,7 +672,7 @@ md_reader::read_string (int star_if_braced)
c = read_skip_spaces ();
}
- old_lineno = get_lineno ();
+ file_location loc = get_current_location ();
if (c == '"')
stringbuf = read_quoted_string ();
else if (c == '{')
@@ -704,7 +695,7 @@ md_reader::read_string (int star_if_braced)
if (saw_paren)
require_char_ws (')');
- set_md_ptr_loc (stringbuf, get_filename (), old_lineno);
+ set_md_ptr_loc (stringbuf, loc);
return stringbuf;
}
diff --git a/gcc/read-md.h b/gcc/read-md.h
index 327f378..377b9f1 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -23,7 +23,8 @@ along with GCC; see the file COPYING3. If not see
#include "obstack.h"
/* Records a position in the file. */
-struct file_location {
+class file_location {
+public:
file_location () {}
file_location (const char *, int, int);
@@ -148,6 +149,13 @@ struct mapping;
class md_reader
{
public:
+ /* Associates PTR (which can be a string, etc.) with the file location
+ specified by LOC. */
+ struct ptr_loc {
+ const void *ptr;
+ file_location loc;
+ };
+
md_reader (bool compact);
virtual ~md_reader ();
@@ -182,7 +190,7 @@ class md_reader
void require_word_ws (const char *expected);
int peek_char (void);
- void set_md_ptr_loc (const void *ptr, const char *filename, int lineno);
+ void set_md_ptr_loc (const void *ptr, file_location);
const struct ptr_loc *get_md_ptr_loc (const void *ptr);
void copy_md_ptr_loc (const void *new_ptr, const void *old_ptr);
void fprint_md_ptr_loc (FILE *outf, const void *ptr);
@@ -204,8 +212,8 @@ class md_reader
rtx copy_rtx_for_iterators (rtx original);
void read_conditions ();
void record_potential_iterator_use (struct iterator_group *group,
- rtx x, unsigned int index,
- const char *name);
+ file_location loc, rtx x,
+ unsigned int index, const char *name);
struct mapping *read_mapping (struct iterator_group *group, htab_t table);
overloaded_name *handle_overloaded_name (rtx, vec<mapping *> *);
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index 3cf34ba..f41f54a 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -52,8 +52,9 @@ class fixup;
at LOC, which will be turned into an actual CFG edge once
the "insn-chain" is fully parsed. */
-struct deferred_edge
+class deferred_edge
{
+public:
deferred_edge (file_location loc, int src_bb_idx, int dest_bb_idx, int flags)
: m_loc (loc), m_src_bb_idx (src_bb_idx), m_dest_bb_idx (dest_bb_idx),
m_flags (flags)
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 6b1b811..3b5d999 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -106,6 +106,9 @@ struct attribute_use {
/* The group that describes the use site. */
struct iterator_group *group;
+ /* The location at which the use occurs. */
+ file_location loc;
+
/* The name of the attribute, possibly with an "iterator:" prefix. */
const char *value;
@@ -361,10 +364,10 @@ find_subst_iter_by_attr (const char *attr)
/* Map attribute string P to its current value. Return null if the attribute
isn't known. If ITERATOR_OUT is nonnull, store the associated iterator
- there. */
+ there. Report any errors against location LOC. */
static struct map_value *
-map_attr_string (const char *p, mapping **iterator_out = 0)
+map_attr_string (file_location loc, const char *p, mapping **iterator_out = 0)
{
const char *attr;
struct mapping *iterator;
@@ -372,6 +375,8 @@ map_attr_string (const char *p, mapping **iterator_out = 0)
struct mapping *m;
struct map_value *v;
int iterator_name_len;
+ struct map_value *res = NULL;
+ struct mapping *prev = NULL;
/* Peel off any "iterator:" prefix. Set ATTR to the start of the
attribute name. */
@@ -414,13 +419,22 @@ map_attr_string (const char *p, mapping **iterator_out = 0)
for (v = m->values; v; v = v->next)
if (v->number == iterator->current_value->number)
{
+ if (res && strcmp (v->string, res->string) != 0)
+ {
+ error_at (loc, "ambiguous attribute '%s'; could be"
+ " '%s' (via '%s:%s') or '%s' (via '%s:%s')",
+ attr, res->string, prev->name, attr,
+ v->string, iterator->name, attr);
+ return v;
+ }
if (iterator_out)
*iterator_out = iterator;
- return v;
+ prev = iterator;
+ res = v;
}
}
}
- return NULL;
+ return res;
}
/* Apply the current iterator values to STRING. Return the new string
@@ -432,16 +446,17 @@ md_reader::apply_iterator_to_string (const char *string)
char *base, *copy, *p, *start, *end;
struct map_value *v;
- if (string == 0)
+ if (string == 0 || string[0] == 0)
return string;
+ file_location loc = get_md_ptr_loc (string)->loc;
base = p = copy = ASTRDUP (string);
while ((start = strchr (p, '<')) && (end = strchr (start, '>')))
{
p = start + 1;
*end = 0;
- v = map_attr_string (p);
+ v = map_attr_string (loc, p);
*end = '>';
if (v == 0)
continue;
@@ -572,7 +587,7 @@ apply_attribute_uses (void)
FOR_EACH_VEC_ELT (attribute_uses, i, ause)
{
- v = map_attr_string (ause->value);
+ v = map_attr_string (ause->loc, ause->value);
if (!v)
fatal_with_file_and_line ("unknown iterator value `%s'", ause->value);
ause->group->apply_iterator (ause->x, ause->index,
@@ -656,6 +671,7 @@ md_reader::handle_overloaded_name (rtx original, vec<mapping *> *iterators)
/* Remove the '@', so that no other code needs to worry about it. */
const char *name = XSTR (original, 0);
+ file_location loc = get_md_ptr_loc (name)->loc;
copy_md_ptr_loc (name + 1, name);
name += 1;
XSTR (original, 0) = name;
@@ -672,7 +688,7 @@ md_reader::handle_overloaded_name (rtx original, vec<mapping *> *iterators)
{
*end = 0;
mapping *iterator;
- if (!map_attr_string (start + 1, &iterator))
+ if (!map_attr_string (loc, start + 1, &iterator))
fatal_with_file_and_line ("unknown iterator `%s'", start + 1);
*end = '>';
@@ -1126,24 +1142,25 @@ record_iterator_use (struct mapping *iterator, rtx x, unsigned int index)
iterator_uses.safe_push (iuse);
}
-/* Record that X uses attribute VALUE, which must match a built-in
- value from group GROUP. If the use is in an operand of X, INDEX
- is the index of that operand, otherwise it is ignored. */
+/* Record that X uses attribute VALUE at location LOC, where VALUE must
+ match a built-in value from group GROUP. If the use is in an operand
+ of X, INDEX is the index of that operand, otherwise it is ignored. */
static void
-record_attribute_use (struct iterator_group *group, rtx x,
+record_attribute_use (struct iterator_group *group, file_location loc, rtx x,
unsigned int index, const char *value)
{
- struct attribute_use ause = {group, value, x, index};
+ struct attribute_use ause = {group, loc, value, x, index};
attribute_uses.safe_push (ause);
}
/* Interpret NAME as either a built-in value, iterator or attribute
for group GROUP. X and INDEX are the values to pass to GROUP's
- apply_iterator callback. */
+ apply_iterator callback. LOC is the location of the use. */
void
md_reader::record_potential_iterator_use (struct iterator_group *group,
+ file_location loc,
rtx x, unsigned int index,
const char *name)
{
@@ -1156,7 +1173,7 @@ md_reader::record_potential_iterator_use (struct iterator_group *group,
/* Copy the attribute string into permanent storage, without the
angle brackets around it. */
obstack_grow0 (&m_string_obstack, name + 1, len - 2);
- record_attribute_use (group, x, index,
+ record_attribute_use (group, loc, x, index,
XOBFINISH (&m_string_obstack, char *));
}
else
@@ -1540,7 +1557,8 @@ rtx_reader::rtx_alloc_for_name (const char *name)
/* Pick the first possible code for now, and record the attribute
use for later. */
rtx x = rtx_alloc (check_code_attribute (m));
- record_attribute_use (&codes, x, 0, deferred_name);
+ record_attribute_use (&codes, get_current_location (),
+ x, 0, deferred_name);
return x;
}
@@ -1639,8 +1657,8 @@ rtx_reader::read_rtx_code (const char *code_name)
c = read_skip_spaces ();
if (c == ':')
{
- read_name (&name);
- record_potential_iterator_use (&modes, return_rtx, 0, name.string);
+ file_location loc = read_name (&name);
+ record_potential_iterator_use (&modes, loc, return_rtx, 0, name.string);
}
else
unread_char (c);
@@ -1862,6 +1880,7 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
|| GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT
|| GET_CODE (return_rtx) == DEFINE_INSN_AND_REWRITE))
{
+ const char *old_stringbuf = stringbuf;
struct obstack *string_obstack = get_string_obstack ();
char line_name[20];
const char *read_md_filename = get_filename ();
@@ -1875,6 +1894,7 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
sprintf (line_name, ":%d", get_lineno ());
obstack_grow (string_obstack, line_name, strlen (line_name)+1);
stringbuf = XOBFINISH (string_obstack, char *);
+ copy_md_ptr_loc (stringbuf, old_stringbuf);
}
/* Find attr-names in the string. */
@@ -1946,10 +1966,13 @@ rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
case 'i':
case 'n':
case 'p':
- /* Can be an iterator or an integer constant. */
- read_name (&name);
- record_potential_iterator_use (&ints, return_rtx, idx, name.string);
- break;
+ {
+ /* Can be an iterator or an integer constant. */
+ file_location loc = read_name (&name);
+ record_potential_iterator_use (&ints, loc, return_rtx, idx,
+ name.string);
+ break;
+ }
case 'r':
read_name (&name);
diff --git a/gcc/recog.h b/gcc/recog.h
index 75cbbdc..e09b27c 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -186,6 +186,23 @@ skip_alternative (const char *p)
/* Nonzero means volatile operands are recognized. */
extern int volatile_ok;
+/* RAII class for temporarily setting volatile_ok. */
+
+class temporary_volatile_ok
+{
+public:
+ temporary_volatile_ok (int value) : save_volatile_ok (volatile_ok)
+ {
+ volatile_ok = value;
+ }
+
+ ~temporary_volatile_ok () { volatile_ok = save_volatile_ok; }
+
+private:
+ temporary_volatile_ok (const temporary_volatile_ok &);
+ int save_volatile_ok;
+};
+
/* Set by constrain_operands to the number of the alternative that
matched. */
extern int which_alternative;
diff --git a/gcc/ree.c b/gcc/ree.c
index 104f8db..c63e159 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -579,8 +579,9 @@ struct ATTRIBUTE_PACKED ext_modified
};
/* Vectors used by combine_reaching_defs and its helpers. */
-struct ext_state
+class ext_state
{
+public:
/* In order to avoid constant alloc/free, we keep these
4 vectors live through the entire find_and_remove_re and just
truncate them each time. */
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 5576630..710f14a 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -2929,6 +2929,7 @@ compensate_edge (edge e)
seq = get_insns ();
end_sequence ();
+ set_insn_locations (seq, e->goto_locus);
insert_insn_on_edge (seq, e);
return true;
}
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index bec2d40..4832aff 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -50,8 +50,9 @@ int max_regno;
/* Used to cache the results of simplifiable_subregs. SHAPE is the input
parameter and SIMPLIFIABLE_REGS is the result. */
-struct simplifiable_subreg
+class simplifiable_subreg
{
+public:
simplifiable_subreg (const subreg_shape &);
subreg_shape shape;
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 5259d56..73c0ced 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -116,7 +116,7 @@ static unsigned current_id;
static vec<du_head_p> id_to_chain;
/* List of currently open chains. */
-static struct du_head *open_chains;
+static class du_head *open_chains;
/* Bitmap of open chains. The bits set always match the list found in
open_chains. */
@@ -135,7 +135,7 @@ static HARD_REG_SET live_hard_regs;
static operand_rr_info *cur_operand;
/* Set while scanning RTL if a register dies. Used to tie chains. */
-static struct du_head *terminated_this_insn;
+static class du_head *terminated_this_insn;
/* Return the chain corresponding to id number ID. Take into account that
chains may have been merged. */
@@ -192,7 +192,7 @@ free_chain_data (void)
another chain whose id is ID. */
static void
-mark_conflict (struct du_head *chains, unsigned id)
+mark_conflict (class du_head *chains, unsigned id)
{
while (chains)
{
@@ -205,7 +205,7 @@ mark_conflict (struct du_head *chains, unsigned id)
use THIS_DU which is part of the chain HEAD. */
static void
-record_operand_use (struct du_head *head, struct du_chain *this_du)
+record_operand_use (class du_head *head, struct du_chain *this_du)
{
if (cur_operand == NULL || cur_operand->failed)
return;
@@ -227,7 +227,7 @@ static du_head_p
create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
rtx_insn *insn, enum reg_class cl)
{
- struct du_head *head = XOBNEW (&rename_obstack, struct du_head);
+ class du_head *head = XOBNEW (&rename_obstack, class du_head);
struct du_chain *this_du;
int nregs;
@@ -288,7 +288,7 @@ create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc,
set the corresponding bits in *PSET. */
static void
-merge_overlapping_regs (HARD_REG_SET *pset, struct du_head *head)
+merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head)
{
bitmap_iterator bi;
unsigned i;
@@ -309,7 +309,7 @@ merge_overlapping_regs (HARD_REG_SET *pset, struct du_head *head)
static bool
check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
- struct du_head *this_head, HARD_REG_SET this_unavailable)
+ class du_head *this_head, HARD_REG_SET this_unavailable)
{
machine_mode mode = GET_MODE (*this_head->first->loc);
int nregs = hard_regno_nregs (new_reg, mode);
@@ -547,8 +547,9 @@ struct incoming_reg_info {
A pointer to such a structure is stored in each basic block's aux field
during regrename_analyze, except for blocks we know can't be optimized
(such as entry and exit blocks). */
-struct bb_rename_info
+class bb_rename_info
{
+public:
/* The basic block corresponding to this structure. */
basic_block bb;
/* Copies of the global information. */
@@ -560,7 +561,7 @@ struct bb_rename_info
/* Initialize a rename_info structure P for basic block BB, which starts a new
scan. */
static void
-init_rename_info (struct bb_rename_info *p, basic_block bb)
+init_rename_info (class bb_rename_info *p, basic_block bb)
{
int i;
df_ref def;
@@ -615,7 +616,7 @@ init_rename_info (struct bb_rename_info *p, basic_block bb)
/* Record in RI that the block corresponding to it has an incoming
live value, described by CHAIN. */
static void
-set_incoming_from_chain (struct bb_rename_info *ri, du_head_p chain)
+set_incoming_from_chain (class bb_rename_info *ri, du_head_p chain)
{
int i;
int incoming_nregs = ri->incoming[chain->regno].nregs;
@@ -689,7 +690,7 @@ merge_chains (du_head_p c1, du_head_p c2)
void
regrename_analyze (bitmap bb_mask)
{
- struct bb_rename_info *rename_info;
+ class bb_rename_info *rename_info;
int i;
basic_block bb;
int n_bbs;
@@ -699,11 +700,11 @@ regrename_analyze (bitmap bb_mask)
n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false);
/* Gather some information about the blocks in this function. */
- rename_info = XCNEWVEC (struct bb_rename_info, n_basic_blocks_for_fn (cfun));
+ rename_info = XCNEWVEC (class bb_rename_info, n_basic_blocks_for_fn (cfun));
i = 0;
FOR_EACH_BB_FN (bb, cfun)
{
- struct bb_rename_info *ri = rename_info + i;
+ class bb_rename_info *ri = rename_info + i;
ri->bb = bb;
if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index))
bb->aux = NULL;
@@ -724,13 +725,13 @@ regrename_analyze (bitmap bb_mask)
for (i = 0; i < n_bbs; i++)
{
basic_block bb1 = BASIC_BLOCK_FOR_FN (cfun, inverse_postorder[i]);
- struct bb_rename_info *this_info;
+ class bb_rename_info *this_info;
bool success;
edge e;
edge_iterator ei;
int old_length = id_to_chain.length ();
- this_info = (struct bb_rename_info *) bb1->aux;
+ this_info = (class bb_rename_info *) bb1->aux;
if (this_info == NULL)
continue;
@@ -770,15 +771,15 @@ regrename_analyze (bitmap bb_mask)
will be used to pre-open chains when processing the successors. */
FOR_EACH_EDGE (e, ei, bb1->succs)
{
- struct bb_rename_info *dest_ri;
- struct du_head *chain;
+ class bb_rename_info *dest_ri;
+ class du_head *chain;
if (dump_file)
fprintf (dump_file, "successor block %d\n", e->dest->index);
if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
continue;
- dest_ri = (struct bb_rename_info *)e->dest->aux;
+ dest_ri = (class bb_rename_info *)e->dest->aux;
if (dest_ri == NULL)
continue;
for (chain = open_chains; chain; chain = chain->next_chain)
@@ -807,7 +808,7 @@ regrename_analyze (bitmap bb_mask)
edges). */
FOR_EACH_BB_FN (bb, cfun)
{
- struct bb_rename_info *bb_ri = (struct bb_rename_info *) bb->aux;
+ class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
unsigned j;
bitmap_iterator bi;
@@ -821,12 +822,12 @@ regrename_analyze (bitmap bb_mask)
{
edge e;
edge_iterator ei;
- struct du_head *chain = regrename_chain_from_id (j);
+ class du_head *chain = regrename_chain_from_id (j);
int n_preds_used = 0, n_preds_joined = 0;
FOR_EACH_EDGE (e, ei, bb->preds)
{
- struct bb_rename_info *src_ri;
+ class bb_rename_info *src_ri;
unsigned k;
bitmap_iterator bi2;
HARD_REG_SET live;
@@ -841,14 +842,14 @@ regrename_analyze (bitmap bb_mask)
if (e->flags & (EDGE_EH | EDGE_ABNORMAL))
continue;
- src_ri = (struct bb_rename_info *)e->src->aux;
+ src_ri = (class bb_rename_info *)e->src->aux;
if (src_ri == NULL)
continue;
EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set,
0, k, bi2)
{
- struct du_head *outgoing_chain = regrename_chain_from_id (k);
+ class du_head *outgoing_chain = regrename_chain_from_id (k);
if (outgoing_chain->regno == chain->regno
&& outgoing_chain->nregs == chain->nregs)
@@ -872,7 +873,7 @@ regrename_analyze (bitmap bb_mask)
}
FOR_EACH_BB_FN (bb, cfun)
{
- struct bb_rename_info *bb_ri = (struct bb_rename_info *) bb->aux;
+ class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux;
unsigned j;
bitmap_iterator bi;
@@ -886,13 +887,13 @@ regrename_analyze (bitmap bb_mask)
{
edge e;
edge_iterator ei;
- struct du_head *chain = regrename_chain_from_id (j);
+ class du_head *chain = regrename_chain_from_id (j);
int n_succs_used = 0, n_succs_joined = 0;
FOR_EACH_EDGE (e, ei, bb->succs)
{
bool printed = false;
- struct bb_rename_info *dest_ri;
+ class bb_rename_info *dest_ri;
unsigned k;
bitmap_iterator bi2;
HARD_REG_SET live;
@@ -904,14 +905,14 @@ regrename_analyze (bitmap bb_mask)
n_succs_used++;
- dest_ri = (struct bb_rename_info *)e->dest->aux;
+ dest_ri = (class bb_rename_info *)e->dest->aux;
if (dest_ri == NULL)
continue;
EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set,
0, k, bi2)
{
- struct du_head *incoming_chain = regrename_chain_from_id (k);
+ class du_head *incoming_chain = regrename_chain_from_id (k);
if (incoming_chain->regno == chain->regno
&& incoming_chain->nregs == chain->nregs)
@@ -958,7 +959,7 @@ regrename_analyze (bitmap bb_mask)
numbering in its subpatterns. */
bool
-regrename_do_replace (struct du_head *head, int reg)
+regrename_do_replace (class du_head *head, int reg)
{
struct du_chain *chain;
unsigned int base_regno = head->regno;
@@ -968,7 +969,7 @@ regrename_do_replace (struct du_head *head, int reg)
for (chain = head->first; chain; chain = chain->next_use)
{
unsigned int regno = ORIGINAL_REGNO (*chain->loc);
- struct reg_attrs *attr = REG_ATTRS (*chain->loc);
+ class reg_attrs *attr = REG_ATTRS (*chain->loc);
int reg_ptr = REG_POINTER (*chain->loc);
if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
@@ -1052,7 +1053,7 @@ static void
note_sets_clobbers (rtx x, const_rtx set, void *data)
{
enum rtx_code code = *(enum rtx_code *)data;
- struct du_head *chain;
+ class du_head *chain;
if (GET_CODE (x) == SUBREG)
x = SUBREG_REG (x);
@@ -1069,7 +1070,7 @@ static void
scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
enum op_type type)
{
- struct du_head **p;
+ class du_head **p;
rtx x = *loc;
unsigned this_regno = REGNO (x);
int this_nregs = REG_NREGS (x);
@@ -1115,8 +1116,8 @@ scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions act
for (p = &open_chains; *p;)
{
- struct du_head *head = *p;
- struct du_head *next = head->next_chain;
+ class du_head *head = *p;
+ class du_head *next = head->next_chain;
int exact_match = (head->regno == this_regno
&& head->nregs == this_nregs);
int superset = (this_regno <= head->regno
@@ -1587,7 +1588,7 @@ record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info)
rtx op = *loc;
enum reg_class cl = alternative_class (op_alt, opn);
- struct du_head *prev_open;
+ class du_head *prev_open;
if (recog_data.operand_type[opn] != OP_OUT
|| op_alt[opn].earlyclobber != earlyclobber)
@@ -1834,7 +1835,7 @@ build_def_use (basic_block bb)
requires a caller-saved reg. */
if (CALL_P (insn))
{
- struct du_head *p;
+ class du_head *p;
for (p = open_chains; p; p = p->next_chain)
p->need_caller_save_reg = 1;
}
diff --git a/gcc/regrename.h b/gcc/regrename.h
index 37f5e39..2fe12d5 100644
--- a/gcc/regrename.h
+++ b/gcc/regrename.h
@@ -22,14 +22,15 @@ along with GCC; see the file COPYING3. If not see
/* We keep linked lists of DU_HEAD structures, each of which describes
a chain of occurrences of a reg. */
-struct du_head
+class du_head
{
+public:
/* The next chain. */
- struct du_head *next_chain;
+ class du_head *next_chain;
/* The first and last elements of this chain. */
struct du_chain *first, *last;
/* The chain that this chain is tied to. */
- struct du_head *tied_chain;
+ class du_head *tied_chain;
/* Describes the register being tracked. */
unsigned regno;
int nregs;
@@ -55,7 +56,7 @@ struct du_head
unsigned int target_data_2;
};
-typedef struct du_head *du_head_p;
+typedef class du_head *du_head_p;
/* This struct describes a single occurrence of a register. */
struct du_chain
@@ -81,7 +82,7 @@ struct operand_rr_info
/* Holds either the chain for the operand itself, or for the registers in
a memory operand. */
struct du_chain *chains[MAX_REGS_PER_ADDRESS];
- struct du_head *heads[MAX_REGS_PER_ADDRESS];
+ class du_head *heads[MAX_REGS_PER_ADDRESS];
};
/* A struct to hold a vector of operand_rr_info structures describing the
diff --git a/gcc/reload.h b/gcc/reload.h
index 813075b..eb49771 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -278,14 +278,15 @@ extern int num_not_at_initial_offset;
/* This structure describes instructions which are relevant for reload.
Apart from all regular insns, this also includes CODE_LABELs, since they
must be examined for register elimination. */
-struct insn_chain
+class insn_chain
{
+public:
/* Links to the neighbor instructions. */
- struct insn_chain *next, *prev;
+ class insn_chain *next, *prev;
/* Link through a chains set up by calculate_needs_all_insns, containing
all insns that need reloading. */
- struct insn_chain *next_need_reload;
+ class insn_chain *next_need_reload;
/* The rtx of the insn. */
rtx_insn *insn;
@@ -319,10 +320,10 @@ struct insn_chain
/* A chain of insn_chain structures to describe all non-note insns in
a function. */
-extern struct insn_chain *reload_insn_chain;
+extern class insn_chain *reload_insn_chain;
/* Allocate a new insn_chain structure. */
-extern struct insn_chain *new_insn_chain (void);
+extern class insn_chain *new_insn_chain (void);
#endif
#if defined SET_HARD_REG_BIT
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 3ad6f1d..38ee356 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -243,14 +243,14 @@ static char *reload_insn_firstobj;
/* List of insn_chain instructions, one for every insn that reload needs to
examine. */
-struct insn_chain *reload_insn_chain;
+class insn_chain *reload_insn_chain;
/* TRUE if we potentially left dead insns in the insn stream and want to
run DCE immediately after reload, FALSE otherwise. */
static bool need_dce;
/* List of all insns needing reloads. */
-static struct insn_chain *insns_need_reload;
+static class insn_chain *insns_need_reload;
/* This structure is used to record information about register eliminations.
Each array entry describes one possible way of eliminating a register
@@ -336,10 +336,10 @@ static int num_labels;
static void replace_pseudos_in (rtx *, machine_mode, rtx);
static void maybe_fix_stack_asms (void);
-static void copy_reloads (struct insn_chain *);
+static void copy_reloads (class insn_chain *);
static void calculate_needs_all_insns (int);
-static int find_reg (struct insn_chain *, int);
-static void find_reload_regs (struct insn_chain *);
+static int find_reg (class insn_chain *, int);
+static void find_reload_regs (class insn_chain *);
static void select_reload_regs (void);
static void delete_caller_save_insns (void);
@@ -368,7 +368,7 @@ static void spill_hard_reg (unsigned int, int);
static int finish_spills (int);
static void scan_paradoxical_subregs (rtx);
static void count_pseudo (int);
-static void order_regs_for_reload (struct insn_chain *);
+static void order_regs_for_reload (class insn_chain *);
static void reload_as_needed (int);
static void forget_old_reloads_1 (rtx, const_rtx, void *);
static void forget_marked_reloads (regset);
@@ -382,19 +382,19 @@ static int reload_reg_free_for_value_p (int, int, int, enum reload_type,
rtx, rtx, int, int);
static int free_for_value_p (int, machine_mode, int, enum reload_type,
rtx, rtx, int, int);
-static int allocate_reload_reg (struct insn_chain *, int, int);
+static int allocate_reload_reg (class insn_chain *, int, int);
static int conflicts_with_override (rtx);
static void failed_reload (rtx_insn *, int);
static int set_reload_reg (int, int);
-static void choose_reload_regs_init (struct insn_chain *, rtx *);
-static void choose_reload_regs (struct insn_chain *);
-static void emit_input_reload_insns (struct insn_chain *, struct reload *,
+static void choose_reload_regs_init (class insn_chain *, rtx *);
+static void choose_reload_regs (class insn_chain *);
+static void emit_input_reload_insns (class insn_chain *, struct reload *,
rtx, int);
-static void emit_output_reload_insns (struct insn_chain *, struct reload *,
+static void emit_output_reload_insns (class insn_chain *, struct reload *,
int);
-static void do_input_reload (struct insn_chain *, struct reload *, int);
-static void do_output_reload (struct insn_chain *, struct reload *, int);
-static void emit_reload_insns (struct insn_chain *);
+static void do_input_reload (class insn_chain *, struct reload *, int);
+static void do_output_reload (class insn_chain *, struct reload *, int);
+static void emit_reload_insns (class insn_chain *);
static void delete_output_reload (rtx_insn *, int, int, rtx);
static void delete_address_reloads (rtx_insn *, rtx_insn *);
static void delete_address_reloads_1 (rtx_insn *, rtx, rtx_insn *);
@@ -467,17 +467,17 @@ init_reload (void)
}
/* List of insn chains that are currently unused. */
-static struct insn_chain *unused_insn_chains = 0;
+static class insn_chain *unused_insn_chains = 0;
/* Allocate an empty insn_chain structure. */
-struct insn_chain *
+class insn_chain *
new_insn_chain (void)
{
- struct insn_chain *c;
+ class insn_chain *c;
if (unused_insn_chains == 0)
{
- c = XOBNEW (&reload_obstack, struct insn_chain);
+ c = XOBNEW (&reload_obstack, class insn_chain);
INIT_REG_SET (&c->live_throughout);
INIT_REG_SET (&c->dead_or_set);
}
@@ -1315,7 +1315,7 @@ maybe_fix_stack_asms (void)
#ifdef STACK_REGS
const char *constraints[MAX_RECOG_OPERANDS];
machine_mode operand_mode[MAX_RECOG_OPERANDS];
- struct insn_chain *chain;
+ class insn_chain *chain;
for (chain = reload_insn_chain; chain != 0; chain = chain->next)
{
@@ -1414,7 +1414,7 @@ maybe_fix_stack_asms (void)
/* Copy the global variables n_reloads and rld into the corresponding elts
of CHAIN. */
static void
-copy_reloads (struct insn_chain *chain)
+copy_reloads (class insn_chain *chain)
{
chain->n_reloads = n_reloads;
chain->rld = XOBNEWVEC (&reload_obstack, struct reload, n_reloads);
@@ -1428,8 +1428,8 @@ copy_reloads (struct insn_chain *chain)
static void
calculate_needs_all_insns (int global)
{
- struct insn_chain **pprev_reload = &insns_need_reload;
- struct insn_chain *chain, *next = 0;
+ class insn_chain **pprev_reload = &insns_need_reload;
+ class insn_chain *chain, *next = 0;
something_needs_elimination = 0;
@@ -1725,7 +1725,7 @@ count_pseudo (int reg)
contents of BAD_SPILL_REGS for the insn described by CHAIN. */
static void
-order_regs_for_reload (struct insn_chain *chain)
+order_regs_for_reload (class insn_chain *chain)
{
unsigned i;
HARD_REG_SET used_by_pseudos;
@@ -1809,7 +1809,7 @@ count_spilled_pseudo (int spilled, int spilled_nregs, int reg)
/* Find reload register to use for reload number ORDER. */
static int
-find_reg (struct insn_chain *chain, int order)
+find_reg (class insn_chain *chain, int order)
{
int rnum = reload_order[order];
struct reload *rl = rld + rnum;
@@ -1954,7 +1954,7 @@ find_reg (struct insn_chain *chain, int order)
for a smaller class even though it belongs to that class. */
static void
-find_reload_regs (struct insn_chain *chain)
+find_reload_regs (class insn_chain *chain)
{
int i;
@@ -2016,7 +2016,7 @@ find_reload_regs (struct insn_chain *chain)
static void
select_reload_regs (void)
{
- struct insn_chain *chain;
+ class insn_chain *chain;
/* Try to satisfy the needs for each insn. */
for (chain = insns_need_reload; chain != 0;
@@ -2029,13 +2029,13 @@ select_reload_regs (void)
static void
delete_caller_save_insns (void)
{
- struct insn_chain *c = reload_insn_chain;
+ class insn_chain *c = reload_insn_chain;
while (c != 0)
{
while (c != 0 && c->is_caller_save_insn)
{
- struct insn_chain *next = c->next;
+ class insn_chain *next = c->next;
rtx_insn *insn = c->insn;
if (c == reload_insn_chain)
@@ -4194,7 +4194,7 @@ spill_hard_reg (unsigned int regno, int cant_eliminate)
static int
finish_spills (int global)
{
- struct insn_chain *chain;
+ class insn_chain *chain;
int something_changed = 0;
unsigned i;
reg_set_iterator rsi;
@@ -4459,7 +4459,7 @@ fixup_eh_region_note (rtx_insn *insn, rtx_insn *prev, rtx_insn *next)
static void
reload_as_needed (int live_known)
{
- struct insn_chain *chain;
+ class insn_chain *chain;
#if AUTO_INC_DEC
int i;
#endif
@@ -6092,7 +6092,7 @@ set_reload_reg (int i, int r)
we didn't change anything. */
static int
-allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
+allocate_reload_reg (class insn_chain *chain ATTRIBUTE_UNUSED, int r,
int last_reload)
{
int i, pass, count;
@@ -6223,7 +6223,7 @@ allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
is the array we use to restore the reg_rtx field for every reload. */
static void
-choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx)
+choose_reload_regs_init (class insn_chain *chain, rtx *save_reload_reg_rtx)
{
int i;
@@ -6324,7 +6324,7 @@ compute_reload_subreg_offset (machine_mode outermode,
finding a reload reg in the proper class. */
static void
-choose_reload_regs (struct insn_chain *chain)
+choose_reload_regs (class insn_chain *chain)
{
rtx_insn *insn = chain->insn;
int i, j;
@@ -7113,7 +7113,7 @@ reload_adjust_reg_for_icode (rtx *reload_reg, rtx alt_reload_reg,
has the number J. OLD contains the value to be used as input. */
static void
-emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
+emit_input_reload_insns (class insn_chain *chain, struct reload *rl,
rtx old, int j)
{
rtx_insn *insn = chain->insn;
@@ -7573,7 +7573,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
/* Generate insns to for the output reload RL, which is for the insn described
by CHAIN and has the number J. */
static void
-emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
+emit_output_reload_insns (class insn_chain *chain, struct reload *rl,
int j)
{
rtx reloadreg;
@@ -7779,7 +7779,7 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
/* Do input reloading for reload RL, which is for the insn described by CHAIN
and has the number J. */
static void
-do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
+do_input_reload (class insn_chain *chain, struct reload *rl, int j)
{
rtx_insn *insn = chain->insn;
rtx old = (rl->in && MEM_P (rl->in)
@@ -7880,7 +7880,7 @@ do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
??? At some point we need to support handling output reloads of
JUMP_INSNs or insns that set cc0. */
static void
-do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
+do_output_reload (class insn_chain *chain, struct reload *rl, int j)
{
rtx note, old;
rtx_insn *insn = chain->insn;
@@ -7986,7 +7986,7 @@ inherit_piecemeal_p (int dest ATTRIBUTE_UNUSED,
/* Output insns to reload values in and out of the chosen reload regs. */
static void
-emit_reload_insns (struct insn_chain *chain)
+emit_reload_insns (class insn_chain *chain)
{
rtx_insn *insn = chain->insn;
diff --git a/gcc/resource.c b/gcc/resource.c
index f8a23ed..c4bcfd7 100644
--- a/gcc/resource.c
+++ b/gcc/resource.c
@@ -987,9 +987,13 @@ mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resource
{
regset regs_live = DF_LR_IN (BASIC_BLOCK_FOR_FN (cfun, b));
rtx_insn *start_insn, *stop_insn;
+ df_ref def;
/* Compute hard regs live at start of block. */
REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
+ FOR_EACH_ARTIFICIAL_DEF (def, b)
+ if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+ SET_HARD_REG_BIT (current_live_regs, DF_REF_REGNO (def));
/* Get starting and ending insn, handling the case where each might
be a SEQUENCE. */
diff --git a/gcc/rtl-iter.h b/gcc/rtl-iter.h
index e48ae4f..ba5e692 100644
--- a/gcc/rtl-iter.h
+++ b/gcc/rtl-iter.h
@@ -56,8 +56,9 @@ class generic_subrtx_iterator
typedef typename T::rtunion_type rtunion_type;
public:
- struct array_type
+ class array_type
{
+ public:
array_type ();
~array_type ();
value_type stack[LOCAL_ELEMS];
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 31fba82..039ab05 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -145,8 +145,9 @@ struct addr_diff_vec_flags
/* Structure used to describe the attributes of a MEM. These are hashed
so MEMs that the same attributes share a data structure. This means
they cannot be modified in place. */
-struct GTY(()) mem_attrs
+class GTY(()) mem_attrs
{
+public:
mem_attrs ();
/* The expression that the MEM accesses, or null if not known.
@@ -187,7 +188,8 @@ struct GTY(()) mem_attrs
object in the low part of a 4-byte register, the OFFSET field
will be -3 rather than 0. */
-struct GTY((for_user)) reg_attrs {
+class GTY((for_user)) reg_attrs {
+public:
tree decl; /* decl corresponding to REG. */
poly_int64 offset; /* Offset from start of DECL. */
};
@@ -208,7 +210,7 @@ union rtunion
tree rt_tree;
basic_block rt_bb;
mem_attrs *rt_mem;
- struct constant_descriptor_rtx *rt_constant;
+ class constant_descriptor_rtx *rt_constant;
struct dw_cfi_node *rt_cfi;
};
@@ -449,8 +451,9 @@ struct GTY((desc("0"), tag("0"),
/* A node for constructing singly-linked lists of rtx. */
-class GTY(()) rtx_expr_list : public rtx_def
+struct GTY(()) rtx_expr_list : public rtx_def
{
+private:
/* No extra fields, but adds invariant: (GET_CODE (X) == EXPR_LIST). */
public:
@@ -469,8 +472,9 @@ is_a_helper <rtx_expr_list *>::test (rtx rt)
return rt->code == EXPR_LIST;
}
-class GTY(()) rtx_insn_list : public rtx_def
+struct GTY(()) rtx_insn_list : public rtx_def
{
+private:
/* No extra fields, but adds invariant: (GET_CODE (X) == INSN_LIST).
This is an instance of:
@@ -501,8 +505,9 @@ is_a_helper <rtx_insn_list *>::test (rtx rt)
/* A node with invariant GET_CODE (X) == SEQUENCE i.e. a vector of rtx,
typically (but not always) of rtx_insn *, used in the late passes. */
-class GTY(()) rtx_sequence : public rtx_def
+struct GTY(()) rtx_sequence : public rtx_def
{
+private:
/* No extra fields, but adds invariant: (GET_CODE (X) == SEQUENCE). */
public:
@@ -533,7 +538,7 @@ is_a_helper <const rtx_sequence *>::test (const_rtx rt)
return rt->code == SEQUENCE;
}
-class GTY(()) rtx_insn : public rtx_def
+struct GTY(()) rtx_insn : public rtx_def
{
public:
/* No extra fields, but adds the invariant:
@@ -567,7 +572,7 @@ public:
/* Subclasses of rtx_insn. */
-class GTY(()) rtx_debug_insn : public rtx_insn
+struct GTY(()) rtx_debug_insn : public rtx_insn
{
/* No extra fields, but adds the invariant:
DEBUG_INSN_P (X) aka (GET_CODE (X) == DEBUG_INSN)
@@ -578,7 +583,7 @@ class GTY(()) rtx_debug_insn : public rtx_insn
from rtl.def. */
};
-class GTY(()) rtx_nonjump_insn : public rtx_insn
+struct GTY(()) rtx_nonjump_insn : public rtx_insn
{
/* No extra fields, but adds the invariant:
NONJUMP_INSN_P (X) aka (GET_CODE (X) == INSN)
@@ -589,7 +594,7 @@ class GTY(()) rtx_nonjump_insn : public rtx_insn
from rtl.def. */
};
-class GTY(()) rtx_jump_insn : public rtx_insn
+struct GTY(()) rtx_jump_insn : public rtx_insn
{
public:
/* No extra fields, but adds the invariant:
@@ -616,7 +621,7 @@ public:
inline void set_jump_target (rtx_code_label *);
};
-class GTY(()) rtx_call_insn : public rtx_insn
+struct GTY(()) rtx_call_insn : public rtx_insn
{
/* No extra fields, but adds the invariant:
CALL_P (X) aka (GET_CODE (X) == CALL_INSN)
@@ -629,7 +634,7 @@ class GTY(()) rtx_call_insn : public rtx_insn
from rtl.def. */
};
-class GTY(()) rtx_jump_table_data : public rtx_insn
+struct GTY(()) rtx_jump_table_data : public rtx_insn
{
/* No extra fields, but adds the invariant:
JUMP_TABLE_DATA_P (X) aka (GET_CODE (INSN) == JUMP_TABLE_DATA)
@@ -640,8 +645,6 @@ class GTY(()) rtx_jump_table_data : public rtx_insn
DEF_RTL_EXPR(JUMP_TABLE_DATA, "jump_table_data", "uuBe0000", RTX_INSN)
from rtl.def. */
-public:
-
/* This can be either:
(a) a table of absolute jumps, in which case PATTERN (this) is an
@@ -657,7 +660,7 @@ public:
inline scalar_int_mode get_data_mode () const;
};
-class GTY(()) rtx_barrier : public rtx_insn
+struct GTY(()) rtx_barrier : public rtx_insn
{
/* No extra fields, but adds the invariant:
BARRIER_P (X) aka (GET_CODE (X) == BARRIER)
@@ -668,7 +671,7 @@ class GTY(()) rtx_barrier : public rtx_insn
from rtl.def. */
};
-class GTY(()) rtx_code_label : public rtx_insn
+struct GTY(()) rtx_code_label : public rtx_insn
{
/* No extra fields, but adds the invariant:
LABEL_P (X) aka (GET_CODE (X) == CODE_LABEL)
@@ -679,7 +682,7 @@ class GTY(()) rtx_code_label : public rtx_insn
from rtl.def. */
};
-class GTY(()) rtx_note : public rtx_insn
+struct GTY(()) rtx_note : public rtx_insn
{
/* No extra fields, but adds the invariant:
NOTE_P(X) aka (GET_CODE (X) == NOTE)
@@ -2096,7 +2099,8 @@ costs_add_n_insns (struct full_rtx_costs *c, int n)
inner_mode == the mode of the SUBREG_REG
offset == the SUBREG_BYTE
outer_mode == the mode of the SUBREG itself. */
-struct subreg_shape {
+class subreg_shape {
+public:
subreg_shape (machine_mode, poly_uint16, machine_mode);
bool operator == (const subreg_shape &) const;
bool operator != (const subreg_shape &) const;
@@ -3722,7 +3726,7 @@ struct GTY(()) target_rtl {
rtx x_static_reg_base_value[FIRST_PSEUDO_REGISTER];
/* The default memory attributes for each mode. */
- struct mem_attrs *x_mode_mem_attrs[(int) MAX_MACHINE_MODE];
+ class mem_attrs *x_mode_mem_attrs[(int) MAX_MACHINE_MODE];
/* Track if RTL has been initialized. */
bool target_specific_initialized;
@@ -3756,10 +3760,10 @@ extern struct target_rtl *this_target_rtl;
#ifndef GENERATOR_FILE
/* Return the attributes of a MEM rtx. */
-static inline const struct mem_attrs *
+static inline const class mem_attrs *
get_mem_attrs (const_rtx x)
{
- struct mem_attrs *attrs;
+ class mem_attrs *attrs;
attrs = MEM_ATTRS (x);
if (!attrs)
@@ -4338,6 +4342,7 @@ extern void insn_locations_init (void);
extern void insn_locations_finalize (void);
extern void set_curr_insn_location (location_t);
extern location_t curr_insn_location (void);
+extern void set_insn_locations (rtx_insn *, location_t);
/* rtl-error.c */
extern void _fatal_insn_not_found (const_rtx, const char *, int, const char *)
diff --git a/gcc/sanopt.c b/gcc/sanopt.c
index 5cb98e1..00ade87 100644
--- a/gcc/sanopt.c
+++ b/gcc/sanopt.c
@@ -207,8 +207,9 @@ struct sanopt_tree_couple_hash : typed_noop_remove <sanopt_tree_couple>
/* This is used to carry various hash maps and variables used
in sanopt_optimize_walker. */
-struct sanopt_ctx
+class sanopt_ctx
{
+public:
/* This map maps a pointer (the first argument of UBSAN_NULL) to
a vector of UBSAN_NULL call statements that check this pointer. */
hash_map<tree, auto_vec<gimple *> > null_check_map;
@@ -353,7 +354,7 @@ maybe_get_dominating_check (auto_vec<gimple *> &v)
/* Optimize away redundant UBSAN_NULL calls. */
static bool
-maybe_optimize_ubsan_null_ifn (struct sanopt_ctx *ctx, gimple *stmt)
+maybe_optimize_ubsan_null_ifn (class sanopt_ctx *ctx, gimple *stmt)
{
gcc_assert (gimple_call_num_args (stmt) == 3);
tree ptr = gimple_call_arg (stmt, 0);
@@ -590,7 +591,7 @@ maybe_optimize_ubsan_ptr_ifn (sanopt_ctx *ctx, gimple *stmt)
when we can actually optimize. */
static bool
-maybe_optimize_ubsan_vptr_ifn (struct sanopt_ctx *ctx, gimple *stmt)
+maybe_optimize_ubsan_vptr_ifn (class sanopt_ctx *ctx, gimple *stmt)
{
gcc_assert (gimple_call_num_args (stmt) == 5);
sanopt_tree_triplet triplet;
@@ -694,7 +695,7 @@ can_remove_asan_check (auto_vec<gimple *> &v, tree len, basic_block bb)
/* Optimize away redundant ASAN_CHECK calls. */
static bool
-maybe_optimize_asan_check_ifn (struct sanopt_ctx *ctx, gimple *stmt)
+maybe_optimize_asan_check_ifn (class sanopt_ctx *ctx, gimple *stmt)
{
gcc_assert (gimple_call_num_args (stmt) == 4);
tree ptr = gimple_call_arg (stmt, 1);
@@ -767,7 +768,7 @@ maybe_optimize_asan_check_ifn (struct sanopt_ctx *ctx, gimple *stmt)
anything anymore. CTX is a sanopt context. */
static void
-sanopt_optimize_walker (basic_block bb, struct sanopt_ctx *ctx)
+sanopt_optimize_walker (basic_block bb, class sanopt_ctx *ctx)
{
basic_block son;
gimple_stmt_iterator gsi;
@@ -886,7 +887,7 @@ sanopt_optimize_walker (basic_block bb, struct sanopt_ctx *ctx)
static int
sanopt_optimize (function *fun, bool *contains_asan_mark)
{
- struct sanopt_ctx ctx;
+ class sanopt_ctx ctx;
ctx.asan_num_accesses = 0;
ctx.contains_asan_mark = false;
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 28b9d38..5cb4a46 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -475,16 +475,16 @@ static int deps_may_trap_p (const_rtx);
static void add_dependence_1 (rtx_insn *, rtx_insn *, enum reg_note);
static void add_dependence_list (rtx_insn *, rtx_insn_list *, int,
enum reg_note, bool);
-static void add_dependence_list_and_free (struct deps_desc *, rtx_insn *,
+static void add_dependence_list_and_free (class deps_desc *, rtx_insn *,
rtx_insn_list **, int, enum reg_note,
bool);
static void delete_all_dependences (rtx_insn *);
static void chain_to_prev_insn (rtx_insn *);
-static void flush_pending_lists (struct deps_desc *, rtx_insn *, int, int);
-static void sched_analyze_1 (struct deps_desc *, rtx, rtx_insn *);
-static void sched_analyze_2 (struct deps_desc *, rtx, rtx_insn *);
-static void sched_analyze_insn (struct deps_desc *, rtx, rtx_insn *);
+static void flush_pending_lists (class deps_desc *, rtx_insn *, int, int);
+static void sched_analyze_1 (class deps_desc *, rtx, rtx_insn *);
+static void sched_analyze_2 (class deps_desc *, rtx, rtx_insn *);
+static void sched_analyze_insn (class deps_desc *, rtx, rtx_insn *);
static bool sched_has_condition_p (const rtx_insn *);
static int conditions_mutex_p (const_rtx, const_rtx, bool, bool);
@@ -1574,7 +1574,7 @@ add_dependence_list (rtx_insn *insn, rtx_insn_list *list, int uncond,
newly created dependencies. */
static void
-add_dependence_list_and_free (struct deps_desc *deps, rtx_insn *insn,
+add_dependence_list_and_free (class deps_desc *deps, rtx_insn *insn,
rtx_insn_list **listp,
int uncond, enum reg_note dep_type, bool hard)
{
@@ -1708,7 +1708,7 @@ chain_to_prev_insn (rtx_insn *insn)
so that we can do memory aliasing on it. */
static void
-add_insn_mem_dependence (struct deps_desc *deps, bool read_p,
+add_insn_mem_dependence (class deps_desc *deps, bool read_p,
rtx_insn *insn, rtx mem)
{
rtx_insn_list **insn_list;
@@ -1749,7 +1749,7 @@ add_insn_mem_dependence (struct deps_desc *deps, bool read_p,
dependencies for a read operation, similarly with FOR_WRITE. */
static void
-flush_pending_lists (struct deps_desc *deps, rtx_insn *insn, int for_read,
+flush_pending_lists (class deps_desc *deps, rtx_insn *insn, int for_read,
int for_write)
{
if (for_write)
@@ -1953,7 +1953,7 @@ create_insn_reg_set (int regno, rtx insn)
/* Set up insn register uses for INSN and dependency context DEPS. */
static void
-setup_insn_reg_uses (struct deps_desc *deps, rtx_insn *insn)
+setup_insn_reg_uses (class deps_desc *deps, rtx_insn *insn)
{
unsigned i;
reg_set_iterator rsi;
@@ -2245,7 +2245,7 @@ static bool can_start_lhs_rhs_p;
/* Extend reg info for the deps context DEPS given that
we have just generated a register numbered REGNO. */
static void
-extend_deps_reg_info (struct deps_desc *deps, int regno)
+extend_deps_reg_info (class deps_desc *deps, int regno)
{
int max_regno = regno + 1;
@@ -2294,7 +2294,7 @@ maybe_extend_reg_info_p (void)
CLOBBER, PRE_DEC, POST_DEC, PRE_INC, POST_INC or USE. */
static void
-sched_analyze_reg (struct deps_desc *deps, int regno, machine_mode mode,
+sched_analyze_reg (class deps_desc *deps, int regno, machine_mode mode,
enum rtx_code ref, rtx_insn *insn)
{
/* We could emit new pseudos in renaming. Extend the reg structures. */
@@ -2382,7 +2382,7 @@ sched_analyze_reg (struct deps_desc *deps, int regno, machine_mode mode,
destination of X, and reads of everything mentioned. */
static void
-sched_analyze_1 (struct deps_desc *deps, rtx x, rtx_insn *insn)
+sched_analyze_1 (class deps_desc *deps, rtx x, rtx_insn *insn)
{
rtx dest = XEXP (x, 0);
enum rtx_code code = GET_CODE (x);
@@ -2556,7 +2556,7 @@ sched_analyze_1 (struct deps_desc *deps, rtx x, rtx_insn *insn)
/* Analyze the uses of memory and registers in rtx X in INSN. */
static void
-sched_analyze_2 (struct deps_desc *deps, rtx x, rtx_insn *insn)
+sched_analyze_2 (class deps_desc *deps, rtx x, rtx_insn *insn)
{
int i;
int j;
@@ -2890,7 +2890,7 @@ get_implicit_reg_pending_clobbers (HARD_REG_SET *temp, rtx_insn *insn)
/* Analyze an INSN with pattern X to find all dependencies. */
static void
-sched_analyze_insn (struct deps_desc *deps, rtx x, rtx_insn *insn)
+sched_analyze_insn (class deps_desc *deps, rtx x, rtx_insn *insn)
{
RTX_CODE code = GET_CODE (x);
rtx link;
@@ -3648,7 +3648,7 @@ chain_to_prev_insn_p (rtx_insn *insn)
/* Analyze INSN with DEPS as a context. */
void
-deps_analyze_insn (struct deps_desc *deps, rtx_insn *insn)
+deps_analyze_insn (class deps_desc *deps, rtx_insn *insn)
{
if (sched_deps_info->start_insn)
sched_deps_info->start_insn (insn);
@@ -3815,7 +3815,7 @@ deps_analyze_insn (struct deps_desc *deps, rtx_insn *insn)
/* Initialize DEPS for the new block beginning with HEAD. */
void
-deps_start_bb (struct deps_desc *deps, rtx_insn *head)
+deps_start_bb (class deps_desc *deps, rtx_insn *head)
{
gcc_assert (!deps->readonly);
@@ -3834,7 +3834,7 @@ deps_start_bb (struct deps_desc *deps, rtx_insn *head)
/* Analyze every insn between HEAD and TAIL inclusive, creating backward
dependencies for each insn. */
void
-sched_analyze (struct deps_desc *deps, rtx_insn *head, rtx_insn *tail)
+sched_analyze (class deps_desc *deps, rtx_insn *head, rtx_insn *tail)
{
rtx_insn *insn;
@@ -3928,10 +3928,10 @@ sched_free_deps (rtx_insn *head, rtx_insn *tail, bool resolved_p)
/* Initialize variables for region data dependence analysis.
When LAZY_REG_LAST is true, do not allocate reg_last array
- of struct deps_desc immediately. */
+ of class deps_desc immediately. */
void
-init_deps (struct deps_desc *deps, bool lazy_reg_last)
+init_deps (class deps_desc *deps, bool lazy_reg_last)
{
int max_reg = (reload_completed ? FIRST_PSEUDO_REGISTER : max_reg_num ());
@@ -3968,7 +3968,7 @@ init_deps (struct deps_desc *deps, bool lazy_reg_last)
/* Init only reg_last field of DEPS, which was not allocated before as
we inited DEPS lazily. */
void
-init_deps_reg_last (struct deps_desc *deps)
+init_deps_reg_last (class deps_desc *deps)
{
gcc_assert (deps && deps->max_reg > 0);
gcc_assert (deps->reg_last == NULL);
@@ -3980,7 +3980,7 @@ init_deps_reg_last (struct deps_desc *deps)
/* Free insn lists found in DEPS. */
void
-free_deps (struct deps_desc *deps)
+free_deps (class deps_desc *deps)
{
unsigned i;
reg_set_iterator rsi;
@@ -4028,7 +4028,7 @@ free_deps (struct deps_desc *deps)
/* Remove INSN from dependence contexts DEPS. */
void
-remove_from_deps (struct deps_desc *deps, rtx_insn *insn)
+remove_from_deps (class deps_desc *deps, rtx_insn *insn)
{
int removed;
unsigned i;
diff --git a/gcc/sched-ebb.c b/gcc/sched-ebb.c
index 4875eef..a594b49 100644
--- a/gcc/sched-ebb.c
+++ b/gcc/sched-ebb.c
@@ -472,7 +472,7 @@ basic_block
schedule_ebb (rtx_insn *head, rtx_insn *tail, bool modulo_scheduling)
{
basic_block first_bb, target_bb;
- struct deps_desc tmp_deps;
+ class deps_desc tmp_deps;
bool success;
/* Blah. We should fix the rest of the code not to get confused by
diff --git a/gcc/sched-int.h b/gcc/sched-int.h
index 3ca5e26..fca1bcf 100644
--- a/gcc/sched-int.h
+++ b/gcc/sched-int.h
@@ -454,8 +454,9 @@ struct deps_reg
};
/* Describe state of dependencies used during sched_analyze phase. */
-struct deps_desc
+class deps_desc
{
+public:
/* The *_insns and *_mems are paired lists. Each pending memory operation
will have a pointer to the MEM rtx on one list and a pointer to the
containing insn on the other list in the same place in the list. */
@@ -570,7 +571,7 @@ struct deps_desc
BOOL_BITFIELD readonly : 1;
};
-typedef struct deps_desc *deps_t;
+typedef class deps_desc *deps_t;
/* This structure holds some state of the current scheduling pass, and
contains some function pointers that abstract out some of the non-generic
@@ -1346,14 +1347,14 @@ extern bool sched_insns_conditions_mutex_p (const rtx_insn *,
const rtx_insn *);
extern bool sched_insn_is_legitimate_for_speculation_p (const rtx_insn *, ds_t);
extern void add_dependence (rtx_insn *, rtx_insn *, enum reg_note);
-extern void sched_analyze (struct deps_desc *, rtx_insn *, rtx_insn *);
-extern void init_deps (struct deps_desc *, bool);
-extern void init_deps_reg_last (struct deps_desc *);
-extern void free_deps (struct deps_desc *);
+extern void sched_analyze (class deps_desc *, rtx_insn *, rtx_insn *);
+extern void init_deps (class deps_desc *, bool);
+extern void init_deps_reg_last (class deps_desc *);
+extern void free_deps (class deps_desc *);
extern void init_deps_global (void);
extern void finish_deps_global (void);
-extern void deps_analyze_insn (struct deps_desc *, rtx_insn *);
-extern void remove_from_deps (struct deps_desc *, rtx_insn *);
+extern void deps_analyze_insn (class deps_desc *, rtx_insn *);
+extern void remove_from_deps (class deps_desc *, rtx_insn *);
extern void init_insn_reg_pressure_info (rtx_insn *);
extern void get_implicit_reg_pending_clobbers (HARD_REG_SET *, rtx_insn *);
@@ -1376,7 +1377,7 @@ extern void haifa_note_reg_use (int);
extern void maybe_extend_reg_info_p (void);
-extern void deps_start_bb (struct deps_desc *, rtx_insn *);
+extern void deps_start_bb (class deps_desc *, rtx_insn *);
extern enum reg_note ds_to_dt (ds_t);
extern bool deps_pools_are_empty_p (void);
@@ -1508,7 +1509,7 @@ extern void dump_rgn_dependencies_dot (const char *);
extern void free_rgn_deps (void);
extern int contributes_to_priority (rtx_insn *, rtx_insn *);
extern void extend_rgns (int *, int *, sbitmap, int *);
-extern void deps_join (struct deps_desc *, struct deps_desc *);
+extern void deps_join (class deps_desc *, class deps_desc *);
extern void rgn_setup_common_sched_info (void);
extern void rgn_setup_sched_infos (void);
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index d400130..59ee6a0 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -248,7 +248,7 @@ static void compute_block_dependences (int);
static void schedule_region (int);
static void concat_insn_mem_list (rtx_insn_list *, rtx_expr_list *,
rtx_insn_list **, rtx_expr_list **);
-static void propagate_deps (int, struct deps_desc *);
+static void propagate_deps (int, class deps_desc *);
static void free_pending_lists (void);
/* Functions for construction of the control flow graph. */
@@ -2583,7 +2583,7 @@ add_branch_dependences (rtx_insn *head, rtx_insn *tail)
the variables of its predecessors. When the analysis for a bb completes,
we save the contents to the corresponding bb_deps[bb] variable. */
-static struct deps_desc *bb_deps;
+static class deps_desc *bb_deps;
static void
concat_insn_mem_list (rtx_insn_list *copy_insns,
@@ -2608,7 +2608,7 @@ concat_insn_mem_list (rtx_insn_list *copy_insns,
/* Join PRED_DEPS to the SUCC_DEPS. */
void
-deps_join (struct deps_desc *succ_deps, struct deps_desc *pred_deps)
+deps_join (class deps_desc *succ_deps, class deps_desc *pred_deps)
{
unsigned reg;
reg_set_iterator rsi;
@@ -2670,7 +2670,7 @@ deps_join (struct deps_desc *succ_deps, struct deps_desc *pred_deps)
/* After computing the dependencies for block BB, propagate the dependencies
found in TMP_DEPS to the successors of the block. */
static void
-propagate_deps (int bb, struct deps_desc *pred_deps)
+propagate_deps (int bb, class deps_desc *pred_deps)
{
basic_block block = BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (bb));
edge_iterator ei;
@@ -2727,7 +2727,7 @@ static void
compute_block_dependences (int bb)
{
rtx_insn *head, *tail;
- struct deps_desc tmp_deps;
+ class deps_desc tmp_deps;
tmp_deps = bb_deps[bb];
@@ -3351,7 +3351,7 @@ sched_rgn_compute_dependencies (int rgn)
init_deps_global ();
/* Initializations for region data dependence analysis. */
- bb_deps = XNEWVEC (struct deps_desc, current_nr_blocks);
+ bb_deps = XNEWVEC (class deps_desc, current_nr_blocks);
for (bb = 0; bb < current_nr_blocks; bb++)
init_deps (bb_deps + bb, false);
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 6dec1be..bb8016b 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -61,7 +61,7 @@ struct succs_info current_succs;
static struct common_sched_info_def sel_common_sched_info;
/* The loop nest being pipelined. */
-struct loop *current_loop_nest;
+class loop *current_loop_nest;
/* LOOP_NESTS is a vector containing the corresponding loop nest for
each region. */
@@ -424,7 +424,7 @@ reset_target_context (tc_t tc, bool clean_p)
}
/* Functions to work with dependence contexts.
- Dc (aka deps context, aka deps_t, aka struct deps_desc *) is short for dependence
+ Dc (aka deps context, aka deps_t, aka class deps_desc *) is short for dependence
context. It accumulates information about processed insns to decide if
current insn is dependent on the processed ones. */
@@ -440,7 +440,7 @@ copy_deps_context (deps_t to, deps_t from)
static deps_t
alloc_deps_context (void)
{
- return XNEW (struct deps_desc);
+ return XNEW (class deps_desc);
}
/* Allocate and initialize dep context. */
@@ -2749,7 +2749,7 @@ init_id_from_df (idata_t id, insn_t insn, bool force_unique_p)
static void
deps_init_id (idata_t id, insn_t insn, bool force_unique_p)
{
- struct deps_desc _dc, *dc = &_dc;
+ class deps_desc _dc, *dc = &_dc;
deps_init_id_data.where = DEPS_IN_NOWHERE;
deps_init_id_data.id = id;
@@ -3390,7 +3390,7 @@ has_dependence_p (expr_t expr, insn_t pred, ds_t **has_dep_pp)
{
int i;
ds_t ds;
- struct deps_desc *dc;
+ class deps_desc *dc;
if (INSN_SIMPLEJUMP_P (pred))
/* Unconditional jump is just a transfer of control flow.
@@ -5397,7 +5397,7 @@ change_loops_latches (basic_block from, basic_block to)
if (current_loop_nest)
{
- struct loop *loop;
+ class loop *loop;
for (loop = current_loop_nest; loop; loop = loop_outer (loop))
if (considered_for_pipelining_p (loop) && loop->latch == from)
@@ -6002,11 +6002,11 @@ bb_top_order_comparator (const void *x, const void *y)
/* Create a region for LOOP and return its number. If we don't want
to pipeline LOOP, return -1. */
static int
-make_region_from_loop (struct loop *loop)
+make_region_from_loop (class loop *loop)
{
unsigned int i;
int new_rgn_number = -1;
- struct loop *inner;
+ class loop *inner;
/* Basic block index, to be assigned to BLOCK_TO_BB. */
int bb_ord_index = 0;
@@ -6095,9 +6095,9 @@ make_region_from_loop_preheader (vec<basic_block> *&loop_blocks)
pipelined before outer loops. Returns true when a region for LOOP
is created. */
static bool
-make_regions_from_loop_nest (struct loop *loop)
+make_regions_from_loop_nest (class loop *loop)
{
- struct loop *cur_loop;
+ class loop *cur_loop;
int rgn_number;
/* Traverse all inner nodes of the loop. */
@@ -6133,7 +6133,7 @@ sel_init_pipelining (void)
recompute_rev_top_order ();
}
-/* Returns a struct loop for region RGN. */
+/* Returns a class loop for region RGN. */
loop_p
get_loop_nest_for_rgn (unsigned int rgn)
{
@@ -6147,7 +6147,7 @@ get_loop_nest_for_rgn (unsigned int rgn)
/* True when LOOP was included into pipelining regions. */
bool
-considered_for_pipelining_p (struct loop *loop)
+considered_for_pipelining_p (class loop *loop)
{
if (loop_depth (loop) == 0)
return false;
@@ -6249,7 +6249,7 @@ make_regions_from_the_rest (void)
/* Free data structures used in pipelining of loops. */
void sel_finish_pipelining (void)
{
- struct loop *loop;
+ class loop *loop;
/* Release aux fields so we don't free them later by mistake. */
FOR_EACH_LOOP (loop, 0)
@@ -6324,7 +6324,7 @@ sel_is_loop_preheader_p (basic_block bb)
{
if (current_loop_nest)
{
- struct loop *outer;
+ class loop *outer;
if (preheader_removed)
return false;
diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h
index 5dd273f..b5824ae 100644
--- a/gcc/sel-sched-ir.h
+++ b/gcc/sel-sched-ir.h
@@ -713,8 +713,9 @@ struct transformed_insns
/* Indexed by INSN_LUID, the collection of all data associated with
a single instruction that is in the stream. */
-struct _sel_insn_data
+class _sel_insn_data
{
+public:
/* The expression that contains vinsn for this insn and some
flow-sensitive data like priority. */
expr_def expr;
@@ -745,7 +746,7 @@ struct _sel_insn_data
htab_t transformed_insns;
/* A context incapsulating this insn. */
- struct deps_desc deps_context;
+ class deps_desc deps_context;
/* This field is initialized at the beginning of scheduling and is used
to handle sched group instructions. If it is non-null, then it points
@@ -774,7 +775,7 @@ struct _sel_insn_data
BOOL_BITFIELD after_stall_p : 1;
};
-typedef struct _sel_insn_data sel_insn_data_def;
+typedef class _sel_insn_data sel_insn_data_def;
typedef sel_insn_data_def *sel_insn_data_t;
extern vec<sel_insn_data_def> s_i_d;
@@ -953,7 +954,7 @@ extern vec<sel_region_bb_info_def> sel_region_bb_info;
extern bitmap_head *forced_ebb_heads;
/* The loop nest being pipelined. */
-extern struct loop *current_loop_nest;
+extern class loop *current_loop_nest;
/* Saves pipelined blocks. Bitmap is indexed by bb->index. */
extern sbitmap bbs_pipelined;
@@ -1042,7 +1043,7 @@ extern bool in_current_region_p (basic_block);
static inline bool
inner_loop_header_p (basic_block bb)
{
- struct loop *inner_loop;
+ class loop *inner_loop;
if (!current_loop_nest)
return false;
@@ -1068,7 +1069,7 @@ inner_loop_header_p (basic_block bb)
/* Return exit edges of LOOP, filtering out edges with the same dest bb. */
static inline vec<edge>
-get_loop_exit_edges_unique_dests (const struct loop *loop)
+get_loop_exit_edges_unique_dests (const class loop *loop)
{
vec<edge> edges = vNULL;
struct loop_exit *exit;
@@ -1141,8 +1142,8 @@ get_all_loop_exits (basic_block bb)
/* And now check whether we should skip over inner loop. */
if (inner_loop_header_p (bb))
{
- struct loop *this_loop;
- struct loop *pred_loop = NULL;
+ class loop *this_loop;
+ class loop *pred_loop = NULL;
int i;
unsigned this_depth;
edge e;
@@ -1641,7 +1642,7 @@ extern void sel_init_pipelining (void);
extern void sel_finish_pipelining (void);
extern void sel_sched_region (int);
extern loop_p get_loop_nest_for_rgn (unsigned int);
-extern bool considered_for_pipelining_p (struct loop *);
+extern bool considered_for_pipelining_p (class loop *);
extern void make_region_from_loop_preheader (vec<basic_block> *&);
extern void sel_add_loop_preheaders (bb_vec_t *);
extern bool sel_is_loop_preheader_p (basic_block);
diff --git a/gcc/selftest.h b/gcc/selftest.h
index d278f0a..75b2cd8 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -30,8 +30,9 @@ namespace selftest {
/* A struct describing the source-location of a selftest, to make it
easier to track down failing tests. */
-struct location
+class location
{
+public:
location (const char *file, int line, const char *function)
: m_file (file), m_line (line), m_function (function) {}
@@ -149,7 +150,7 @@ class auto_fix_quotes
The following struct describes a particular case within our test
matrix. */
-struct line_table_case;
+class line_table_case;
/* A class for overriding the global "line_table" within a selftest,
restoring its value afterwards. At most one instance of this
diff --git a/gcc/sese.c b/gcc/sese.c
index e904731..4b3065a 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -149,7 +149,7 @@ sese_build_liveouts (sese_info_p region)
sese_info_p
new_sese_info (edge entry, edge exit)
{
- sese_info_p region = XNEW (struct sese_info_t);
+ sese_info_p region = XNEW (class sese_info_t);
region->region.entry = entry;
region->region.exit = exit;
@@ -217,10 +217,10 @@ sese_insert_phis_for_liveouts (sese_info_p region, basic_block bb,
/* Returns the outermost loop in SCOP that contains BB. */
-struct loop *
+class loop *
outermost_loop_in_sese_1 (sese_l &region, basic_block bb)
{
- struct loop *nest;
+ class loop *nest;
nest = bb->loop_father;
while (loop_outer (nest)
diff --git a/gcc/sese.h b/gcc/sese.h
index 8931b28..6a62bb6 100644
--- a/gcc/sese.h
+++ b/gcc/sese.h
@@ -26,8 +26,9 @@ typedef struct ifsese_s *ifsese;
/* A Single Entry, Single Exit region is a part of the CFG delimited
by two edges. */
-struct sese_l
+class sese_l
{
+public:
sese_l (edge e, edge x) : entry (e), exit (x) {}
operator bool () const { return entry && exit; }
@@ -71,8 +72,9 @@ vec_find (const vec<T> &v, const T &elem)
}
/* A helper structure for bookkeeping information about a scop in graphite. */
-typedef struct sese_info_t
+typedef class sese_info_t
{
+public:
/* The SESE region. */
sese_l region;
@@ -99,7 +101,7 @@ typedef struct sese_info_t
extern sese_info_p new_sese_info (edge, edge);
extern void free_sese_info (sese_info_p);
extern void sese_insert_phis_for_liveouts (sese_info_p, basic_block, edge, edge);
-extern struct loop *outermost_loop_in_sese (sese_l &, basic_block);
+extern class loop *outermost_loop_in_sese (sese_l &, basic_block);
extern tree scalar_evolution_in_region (const sese_l &, loop_p, tree);
extern bool scev_analyzable_p (tree, sese_l &);
extern bool invariant_in_sese_p_rec (tree, const sese_l &, bool *);
@@ -154,7 +156,7 @@ defined_in_sese_p (tree name, const sese_l &r)
/* Returns true when LOOP is in REGION. */
static inline bool
-loop_in_sese_p (struct loop *loop, const sese_l &region)
+loop_in_sese_p (class loop *loop, const sese_l &region)
{
return (bb_in_sese_p (loop->header, region)
&& bb_in_sese_p (loop->latch, region));
@@ -270,7 +272,7 @@ typedef struct gimple_poly_bb
/* Return the innermost loop that contains the basic block GBB. */
-static inline struct loop *
+static inline class loop *
gbb_loop (gimple_poly_bb_p gbb)
{
return GBB_BB (gbb)->loop_father;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 89a46a9..4892c49 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1504,12 +1504,12 @@ simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
&& CONST_INT_P (XEXP (op, 1))
&& XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
&& (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
- GET_MODE_BITSIZE (op_mode) > INTVAL (XEXP (op, 1))))
+ GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
{
scalar_int_mode tmode;
- gcc_assert (GET_MODE_BITSIZE (int_mode)
- > GET_MODE_BITSIZE (op_mode));
- if (int_mode_for_size (GET_MODE_BITSIZE (op_mode)
+ gcc_assert (GET_MODE_PRECISION (int_mode)
+ > GET_MODE_PRECISION (op_mode));
+ if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
- INTVAL (XEXP (op, 1)), 1).exists (&tmode))
{
rtx inner =
@@ -6697,6 +6697,17 @@ simplify_subreg (machine_mode outermode, rtx op,
}
}
+ /* If OP is a vector comparison and the subreg is not changing the
+ number of elements or the size of the elements, change the result
+ of the comparison to the new mode. */
+ if (COMPARISON_P (op)
+ && VECTOR_MODE_P (outermode)
+ && VECTOR_MODE_P (innermode)
+ && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
+ && known_eq (GET_MODE_UNIT_SIZE (outermode),
+ GET_MODE_UNIT_SIZE (innermode)))
+ return simplify_gen_relational (GET_CODE (op), outermode, innermode,
+ XEXP (op, 0), XEXP (op, 1));
return NULL_RTX;
}
diff --git a/gcc/sreal.c b/gcc/sreal.c
index b991652..5418481 100644
--- a/gcc/sreal.c
+++ b/gcc/sreal.c
@@ -258,7 +258,7 @@ sreal::stream_out (struct output_block *ob)
/* Read sreal value from IB. */
sreal
-sreal::stream_in (struct lto_input_block *ib)
+sreal::stream_in (class lto_input_block *ib)
{
sreal val;
val.m_sig = streamer_read_hwi (ib);
diff --git a/gcc/sreal.h b/gcc/sreal.h
index aa3327b..cb363d4 100644
--- a/gcc/sreal.h
+++ b/gcc/sreal.h
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
#define SREAL_ABS(v) (v < 0 ? -v: v)
struct output_block;
-struct lto_input_block;
+class lto_input_block;
/* Structure for holding a simple real number. */
class sreal
@@ -53,7 +53,7 @@ public:
int64_t to_int () const;
double to_double () const;
void stream_out (struct output_block *);
- static sreal stream_in (struct lto_input_block *);
+ static sreal stream_in (class lto_input_block *);
sreal operator+ (const sreal &other) const;
sreal operator- (const sreal &other) const;
sreal operator* (const sreal &other) const;
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 8ed3bf5..040899e 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -68,8 +68,9 @@ along with GCC; see the file COPYING3. If not see
*/
-struct simple_case_node
+class simple_case_node
{
+public:
simple_case_node (tree low, tree high, tree code_label):
m_low (low), m_high (high), m_code_label (code_label)
{}
diff --git a/gcc/streamer-hooks.h b/gcc/streamer-hooks.h
index 2a45513..14d158e 100644
--- a/gcc/streamer-hooks.h
+++ b/gcc/streamer-hooks.h
@@ -25,8 +25,8 @@ along with GCC; see the file COPYING3. If not see
/* Forward declarations to avoid including unnecessary headers. */
struct output_block;
-struct lto_input_block;
-struct data_in;
+class lto_input_block;
+class data_in;
/* Streamer hooks. These functions do additional processing as
needed by the module. There are two types of callbacks, those that
@@ -49,10 +49,10 @@ struct streamer_hooks {
to the buffer where to read from and a data_in instance with tables
and descriptors needed by the unpickling routines. It returns the
tree instantiated from the stream. */
- tree (*read_tree) (struct lto_input_block *, struct data_in *);
+ tree (*read_tree) (class lto_input_block *, class data_in *);
/* [REQ] Called by every streaming routine that needs to read a location. */
- void (*input_location) (location_t *, struct bitpack_d *, struct data_in *);
+ void (*input_location) (location_t *, struct bitpack_d *, class data_in *);
/* [REQ] Called by every streaming routine that needs to write a location. */
void (*output_location) (struct output_block *, struct bitpack_d *, location_t);
diff --git a/gcc/symtab.c b/gcc/symtab.c
index b1589ea..63e2820 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -956,6 +956,13 @@ symtab_node::dump (FILE *f)
}
void
+symtab_node::dump_graphviz (FILE *f)
+{
+ if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
+ cnode->dump_graphviz (f);
+}
+
+void
symbol_table::dump (FILE *f)
{
symtab_node *node;
@@ -964,6 +971,16 @@ symbol_table::dump (FILE *f)
node->dump (f);
}
+void
+symbol_table::dump_graphviz (FILE *f)
+{
+ symtab_node *node;
+ fprintf (f, "digraph symtab {\n");
+ FOR_EACH_SYMBOL (node)
+ node->dump_graphviz (f);
+ fprintf (f, "}\n");
+}
+
DEBUG_FUNCTION void
symbol_table::debug (void)
{
diff --git a/gcc/target-globals.c b/gcc/target-globals.c
index 94a465c..8928fc1 100644
--- a/gcc/target-globals.c
+++ b/gcc/target-globals.c
@@ -42,7 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "lower-subreg.h"
#if SWITCHABLE_TARGET
-struct target_globals default_target_globals = {
+class target_globals default_target_globals = {
&default_target_flag_state,
&default_target_regs,
&default_target_rtl,
@@ -61,11 +61,11 @@ struct target_globals default_target_globals = {
&default_target_lower_subreg
};
-struct target_globals *
+class target_globals *
save_target_globals (void)
{
- struct target_globals *g = ggc_cleared_alloc <target_globals> ();
- g->flag_state = XCNEW (struct target_flag_state);
+ class target_globals *g = ggc_cleared_alloc <target_globals> ();
+ g->flag_state = XCNEW (class target_flag_state);
g->regs = XCNEW (struct target_regs);
g->rtl = ggc_cleared_alloc<target_rtl> ();
g->recog = XCNEW (struct target_recog);
@@ -76,7 +76,7 @@ save_target_globals (void)
g->libfuncs = ggc_cleared_alloc<target_libfuncs> ();
g->cfgloop = XCNEW (struct target_cfgloop);
g->ira = XCNEW (struct target_ira);
- g->ira_int = XCNEW (struct target_ira_int);
+ g->ira_int = XCNEW (class target_ira_int);
g->builtins = XCNEW (struct target_builtins);
g->gcse = XCNEW (struct target_gcse);
g->bb_reorder = XCNEW (struct target_bb_reorder);
@@ -91,10 +91,10 @@ save_target_globals (void)
correctly when a previous function has changed
*this_target_optabs. */
-struct target_globals *
+class target_globals *
save_target_globals_default_opts ()
{
- struct target_globals *globals;
+ class target_globals *globals;
if (optimization_current_node != optimization_default_node)
{
diff --git a/gcc/target-globals.h b/gcc/target-globals.h
index 5af846c..ceb216a 100644
--- a/gcc/target-globals.h
+++ b/gcc/target-globals.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_GLOBALS_H 1
#if SWITCHABLE_TARGET
-extern struct target_flag_state *this_target_flag_state;
+extern class target_flag_state *this_target_flag_state;
extern struct target_regs *this_target_regs;
extern struct target_rtl *this_target_rtl;
extern struct target_recog *this_target_recog;
@@ -32,17 +32,18 @@ extern struct target_optabs *this_target_optabs;
extern struct target_libfuncs *this_target_libfuncs;
extern struct target_cfgloop *this_target_cfgloop;
extern struct target_ira *this_target_ira;
-extern struct target_ira_int *this_target_ira_int;
+extern class target_ira_int *this_target_ira_int;
extern struct target_builtins *this_target_builtins;
extern struct target_gcse *this_target_gcse;
extern struct target_bb_reorder *this_target_bb_reorder;
extern struct target_lower_subreg *this_target_lower_subreg;
#endif
-struct GTY(()) target_globals {
+class GTY(()) target_globals {
+public:
~target_globals ();
- struct target_flag_state *GTY((skip)) flag_state;
+ class target_flag_state *GTY((skip)) flag_state;
struct target_regs *GTY((skip)) regs;
struct target_rtl *rtl;
struct target_recog *GTY((skip)) recog;
@@ -53,7 +54,7 @@ struct GTY(()) target_globals {
struct target_libfuncs *libfuncs;
struct target_cfgloop *GTY((skip)) cfgloop;
struct target_ira *GTY((skip)) ira;
- struct target_ira_int *GTY((skip)) ira_int;
+ class target_ira_int *GTY((skip)) ira_int;
struct target_builtins *GTY((skip)) builtins;
struct target_gcse *GTY((skip)) gcse;
struct target_bb_reorder *GTY((skip)) bb_reorder;
@@ -61,13 +62,13 @@ struct GTY(()) target_globals {
};
#if SWITCHABLE_TARGET
-extern struct target_globals default_target_globals;
+extern class target_globals default_target_globals;
-extern struct target_globals *save_target_globals (void);
-extern struct target_globals *save_target_globals_default_opts (void);
+extern class target_globals *save_target_globals (void);
+extern class target_globals *save_target_globals_default_opts (void);
static inline void
-restore_target_globals (struct target_globals *g)
+restore_target_globals (class target_globals *g)
{
this_target_flag_state = g->flag_state;
this_target_regs = g->regs;
diff --git a/gcc/target.def b/gcc/target.def
index 4165405..7cc0f37 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1970,7 +1970,7 @@ DEFHOOK
"non-NULL, it identifies the loop being vectorized; otherwise a single block "
"is being vectorized.",
void *,
- (struct loop *loop_info),
+ (class loop *loop_info),
default_init_cost)
/* Target function to record N statements of the given kind using the
@@ -1987,7 +1987,7 @@ DEFHOOK
"revised.",
unsigned,
(void *data, int count, enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info, int misalign,
+ class _stmt_vec_info *stmt_info, int misalign,
enum vect_cost_model_location where),
default_add_stmt_cost)
@@ -2665,7 +2665,7 @@ the loop is to be unrolled. The parameter @var{loop} is a pointer to\n\
the loop, which is going to be checked for unrolling. This target hook\n\
is required only when the target has special constraints like maximum\n\
number of memory accesses.",
- unsigned, (unsigned nunroll, struct loop *loop),
+ unsigned, (unsigned nunroll, class loop *loop),
NULL)
/* True if X is a legitimate MODE-mode immediate operand. */
@@ -3182,7 +3182,7 @@ DEFHOOK
version of this hook assumes the system C library errno location\
is either a declaration of type int or accessed by dereferencing\
a pointer to int.",
- bool, (struct ao_ref *ref),
+ bool, (ao_ref *ref),
default_ref_may_alias_errno)
/* Support for named address spaces. */
@@ -4243,7 +4243,7 @@ for a particular loop. The parameter @var{loop} is a pointer to the loop.\n\
This target hook is required only when the target supports low-overhead\n\
loops, and will help ivopts to make some decisions.\n\
The default version of this hook returns false.",
- bool, (struct loop *loop),
+ bool, (class loop *loop),
default_predict_doloop_p)
DEFHOOK
diff --git a/gcc/target.h b/gcc/target.h
index 008932b..633e384 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -138,20 +138,20 @@ struct _dep;
struct ddg;
/* This is defined in cfgloop.h . */
-struct loop;
+class loop;
/* This is defined in ifcvt.h. */
struct noce_if_info;
/* This is defined in tree-ssa-alias.h. */
-struct ao_ref;
+class ao_ref;
/* This is defined in tree-vectorizer.h. */
-struct _stmt_vec_info;
+class _stmt_vec_info;
/* These are defined in tree-vect-stmts.c. */
-extern tree stmt_vectype (struct _stmt_vec_info *);
-extern bool stmt_in_inner_loop_p (struct _stmt_vec_info *);
+extern tree stmt_vectype (class _stmt_vec_info *);
+extern bool stmt_in_inner_loop_p (class _stmt_vec_info *);
/* Assembler instructions for creating various kinds of integer object. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 676885b..fa797b4 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -651,7 +651,7 @@ default_has_ifunc_p (void)
if the target can take advantage of it. */
bool
-default_predict_doloop_p (struct loop *loop ATTRIBUTE_UNUSED)
+default_predict_doloop_p (class loop *loop ATTRIBUTE_UNUSED)
{
return false;
}
@@ -1366,7 +1366,7 @@ default_empty_mask_is_expensive (unsigned ifn)
array of three unsigned ints, set it to zero, and return its address. */
void *
-default_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED)
+default_init_cost (class loop *loop_info ATTRIBUTE_UNUSED)
{
unsigned *cost = XNEWVEC (unsigned, 3);
cost[vect_prologue] = cost[vect_body] = cost[vect_epilogue] = 0;
@@ -1379,7 +1379,7 @@ default_init_cost (struct loop *loop_info ATTRIBUTE_UNUSED)
unsigned
default_add_stmt_cost (void *data, int count, enum vect_cost_for_stmt kind,
- struct _stmt_vec_info *stmt_info, int misalign,
+ class _stmt_vec_info *stmt_info, int misalign,
enum vect_cost_model_location where)
{
unsigned *cost = (unsigned *) data;
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 50b03ce..ca2e37d 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -85,7 +85,7 @@ extern bool default_fixed_point_supported_p (void);
extern bool default_has_ifunc_p (void);
-extern bool default_predict_doloop_p (struct loop *);
+extern bool default_predict_doloop_p (class loop *);
extern const char * default_invalid_within_doloop (const rtx_insn *);
extern tree default_builtin_vectorized_function (unsigned int, tree, tree);
@@ -114,9 +114,9 @@ extern machine_mode default_split_reduction (machine_mode);
extern void default_autovectorize_vector_sizes (vector_sizes *, bool);
extern opt_machine_mode default_get_mask_mode (poly_uint64, poly_uint64);
extern bool default_empty_mask_is_expensive (unsigned);
-extern void *default_init_cost (struct loop *);
+extern void *default_init_cost (class loop *);
extern unsigned default_add_stmt_cost (void *, int, enum vect_cost_for_stmt,
- struct _stmt_vec_info *, int,
+ class _stmt_vec_info *, int,
enum vect_cost_model_location);
extern void default_finish_cost (void *, unsigned *, unsigned *, unsigned *);
extern void default_destroy_cost_data (void *);
@@ -188,7 +188,7 @@ extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);
extern bool default_target_option_pragma_parse (tree, tree);
extern bool default_target_can_inline_p (tree, tree);
extern bool default_valid_pointer_mode (scalar_int_mode);
-extern bool default_ref_may_alias_errno (struct ao_ref *);
+extern bool default_ref_may_alias_errno (class ao_ref *);
extern scalar_int_mode default_addr_space_pointer_mode (addr_space_t);
extern scalar_int_mode default_addr_space_address_mode (addr_space_t);
extern bool default_addr_space_valid_pointer_mode (scalar_int_mode,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1695bab..8e6b026 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,976 @@
+2019-07-23 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/83518
+ * gcc.dg/tree-ssa/ssa-fre-79.c: New testcase.
+
+2019-07-23 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/task4.adb: New testcase.
+
+2019-07-23 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/range_check5.adb: New testcase.
+
+2019-07-23 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/iter5.adb: Add an expected error.
+ * gnat.dg/iter6.adb: New testcase.
+
+2019-07-23 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/ghost6.adb, gnat.dg/ghost6_pkg.ads: New testcase.
+
+2019-07-22 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ * gcc.target/aarch64/simd/ssra.c: New test.
+ * gcc.target/aarch64/simd/usra.c: New test.
+
+2019-07-22 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/isr-push-pop-main.c: New test.
+ * gcc.target/msp430/isr-push-pop-isr-430.c: Likewise.
+ * gcc.target/msp430/isr-push-pop-isr-430x.c: Likewise.
+ * gcc.target/msp430/isr-push-pop-leaf-isr-430.c: Likewise.
+ * gcc.target/msp430/isr-push-pop-leaf-isr-430x.c: Likewise.
+
+2019-07-22 Andrea Corallo <andrea.corallo@arm.com>
+
+ * jit.dg/test-error-gcc_jit_context_new_unary_op-bad-res-type.c:
+ New testcase.
+ * jit.dg/test-error-gcc_jit_context_new_binary_op-bad-res-type.c:
+ Adjust error message.
+
+2019-07-22 Paul A. Clarke <pc@us.ibm.com>
+
+ * gcc.target/powerpc/sse4_1-check.h: New.
+ * gcc.target/powerpc/sse4_1-pblendvb.c: New.
+ * gcc.target/powerpc/sse4_1-pblendw.c: New.
+ * gcc.target/powerpc/sse4_1-pblendw-2.c: New.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/fixedpnt6.adb: New testcase.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/warn26.adb: New testcase.
+
+2019-07-22 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/class_wide5.adb: New testcase.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/opt80.adb: New testcase.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/warn25.adb: New testcase.
+
+2019-07-22 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/warn24.adb: New testcase.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/inline17.adb, gnat.dg/inline17_pkg1.adb,
+ gnat.dg/inline17_pkg1.ads, gnat.dg/inline17_pkg2.ads,
+ gnat.dg/inline17_pkg3.adb, gnat.dg/inline17_pkg3.ads: New
+ testcase.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/iter5.adb, gnat.dg/iter5_pkg.ads: New testcase.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/enum_val1.adb: New testcase.
+
+2019-07-22 Nicolas Roche <roche@adacore.com>
+
+ * gnat.dg/float_value1.adb: New testcase.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/encode_string1.adb, gnat.dg/encode_string1_pkg.adb,
+ gnat.dg/encode_string1_pkg.ads: New testcase.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/warn23.adb: New testcase.
+
+2019-07-22 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/cpp_constructor2.adb: New testcase.
+
+2019-07-22 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/warn22.adb: New testcase.
+
+2019-07-22 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/loop_invariant1.adb, gnat.dg/loop_invariant1.ads: New
+ testcase.
+
+2019-07-22 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91221
+ * g++.dg/pr91221.C: New testcase.
+
+2019-07-22 Martin Liska <mliska@suse.cz>
+
+ PR driver/91172
+ * gcc.dg/pr91172.c: New test.
+
+2019-07-22 Claudiu Zissulescu <claziss@synopsys.com>
+
+ * gcc.target/arc/tls-2.c: New test.
+ * gcc.target/arc/tls-3.c: Likewise.
+
+2019-07-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/67853
+ * g++.dg/cpp0x/decltype72.C: New test.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ * gcc.target/or1k/ror-4.c: New file.
+ * gcc.target/or1k/shftimm-1.c: Update test from rotate to shift
+ as the shftimm option no longer controls rotate.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ PR target/90362
+ * gcc.target/or1k/div-mul-3.c: New test.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ PR target/90363
+ * gcc.target/or1k/swap-1.c: New test.
+ * gcc.target/or1k/swap-2.c: New test.
+
+2019-07-20 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * gcc.target/powerpc/volatile-mem.c: New testcase.
+
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/91204
+ * gcc.c-torture/compile/pr91204.c: New test.
+
+ * c-c++-common/gomp/cancel-1.c: Adjust expected diagnostic wording.
+ * c-c++-common/gomp/clauses-1.c (foo, baz, bar): Add order(concurrent)
+ clause where allowed. Add combined constructs with loop with all
+ possible clauses.
+ (qux): New function.
+ * c-c++-common/gomp/loop-1.c: New test.
+ * c-c++-common/gomp/loop-2.c: New test.
+ * c-c++-common/gomp/loop-3.c: New test.
+ * c-c++-common/gomp/loop-4.c: New test.
+ * c-c++-common/gomp/loop-5.c: New test.
+ * c-c++-common/gomp/order-3.c: Adjust expected diagnostic wording.
+ * c-c++-common/gomp/simd-setjmp-1.c: New test.
+ * c-c++-common/gomp/teams-2.c: Adjust expected diagnostic wording.
+
+ * gcc.dg/vect/vect-simd-16.c: New test.
+
+2019-07-19 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/ssa-dse-37.c: New test.
+ * gcc.dg/tree-ssa/ssa-dse-38.c: New test.
+
+2019-07-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91211
+ * gcc.dg/torture/pr91211.c: New testcase.
+
+2019-07-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91200
+ * gcc.dg/torture/pr91200.c: New testcase.
+
+2019-07-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91190
+ * gcc.c-torture/compile/pr91190.c: New test.
+
+2019-07-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91207
+ * gcc.dg/torture/pr91207.c: New testcase.
+
+2019-07-18 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91188
+ * gcc.target/i386/pr91188-1a.c: New test.
+ * gcc.target/i386/pr91188-1b.c: Ditto.
+ * gcc.target/i386/pr91188-1c.c: Ditto.
+ * gcc.target/i386/pr91188-2a.c: Ditto.
+ * gcc.target/i386/pr91188-2b.c: Ditto.
+ * gcc.target/i386/pr91188-2c.c: Ditto.
+
+2019-07-18 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ PR target/90317
+ * gcc.target/arm/crypto-vsha1cq_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1C_VEC_SELECT): New.
+ * gcc.target/arm/crypto-vsha1h_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1H_VEC_SELECT): New.
+ * gcc.target/arm/crypto-vsha1mq_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1M_VEC_SELECT): New.
+ * gcc.target/arm/crypto-vsha1pq_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1P_VEC_SELECT): New.
+
+2019-07-18 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/lto/alias-5_0.C: New testcase.
+ * g++.dg/lto/alias-5_1.C: New.
+ * g++.dg/lto/alias-5_2.c: New.
+
+2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com>
+
+ PR tree-optimization/91137
+ * gcc.c-torture/execute/pr91137.c: New test.
+
+2019-07-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * c-c++-common/pr53633-2.c: New test.
+
+2019-07-17 Alexandre Oliva <oliva@adacore.com>
+
+ PR middle-end/81824
+ * g++.dg/Wmissing-attributes-1.C: New. Some of its fragments
+ are from Martin Sebor.
+
+2019-07-17 Marek Polacek <polacek@redhat.com>
+
+ PR c++/90455
+ * g++.dg/cpp0x/nsdmi-list6.C: New test.
+
+2019-07-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/lto/alias-4_0.C
+
+2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91178
+ * gcc.dg/torture/pr91178.c: New testcase.
+
+2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91180
+ * gcc.dg/torture/pr91180.c: New testcase.
+
+2019-07-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91157
+ * gcc.target/i386/avx512f-pr91157.c: New test.
+ * gcc.target/i386/avx512bw-pr91157.c: New test.
+
+2019-07-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91181
+ * gcc.dg/pr91181.c: New testcase.
+
+2019-07-16 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/90903
+ * gfortran.dg/check_bits_1.f90: New testcase.
+
+2019-07-16 Jeff Law <law@redhat.com>
+
+ PR rtl-optimization/91173
+ * g++.dg/pr91173.C: New test.
+
+2019-07-16 Wilco Dijkstra <wdijkstr@arm.com>
+
+ PR target/89190
+ * gcc.target/arm/pr89190.c: New test.
+
+2019-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/91164
+ * g++.dg/opt/pr91164.C: New test.
+
+2019-07-16 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/lto/alias-1_0.C: Use -O3.
+ * g++.dg/lto/alias-2_0.C: Use -O3.
+ * g++.dg/lto/alias-3_0.C: Add loop to enable inlining with
+ -fno-use-linker-plugin.
+ * g++.dg/lto/alias-3_1.C: Remove dg-lto-do and dg-lto-options.
+
+2019-07-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/tree-ssa/pr84512.c: Don't xfail scan-tree-dump on
+ sparcv9.
+
+2019-07-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/autopar/pr91162.c: Require int128 support.
+
+2019-07-15 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91162
+ * gcc.dg/autopar/pr91162.c: New testcase.
+
+2019-07-15 Kewen Lin <linkw@gcc.gnu.org>
+
+ PR tree-optimization/88497
+ * gcc.dg/tree-ssa/pr88497-1.c: New test.
+ * gcc.dg/tree-ssa/pr88497-2.c: Likewise.
+ * gcc.dg/tree-ssa/pr88497-3.c: Likewise.
+ * gcc.dg/tree-ssa/pr88497-4.c: Likewise.
+ * gcc.dg/tree-ssa/pr88497-5.c: Likewise.
+ * gcc.dg/tree-ssa/pr88497-6.c: Likewise.
+ * gcc.dg/tree-ssa/pr88497-7.c: Likewise.
+
+2019-07-14 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+
+ PR fortran/87233
+ * gfortran.dg/initialization_14.f90: Modify to now pass by
+ removing two dg-error commands. Added comments.
+ * gfortran.dg/initialization_30.f90: New test that includes the
+ two tests removed above with the 'dg-options -std=f95'.
+
+2019-07-14 Uroš Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/tree-ssa/pr84512.c (dg-final): Remove XFAIL on alpha*-*-*.
+
+2019-07-14 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/91148
+ * gcc.target/powerpc/bfp/scalar-extract-exp-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-extract-sig-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-5.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-8.c: Adjust.
+ * gcc.target/powerpc/byte-in-set-2.c: Adjust.
+ * gcc.target/powerpc/cmpb-3.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-all-nez-7.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-any-eqz-7.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xl-len-13.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xst-len-12.c: Adjust.
+
+2019-07-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.target/powerpc/stabs-attrib-vect-darwin.c: Require stabs
+ support.
+
+2019-07-13 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/91148
+ * gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-extract-exp-1.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-extract-exp-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-extract-exp-4.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-extract-sig-1.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-extract-sig-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-extract-sig-4.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-1.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-10.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-4.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-5.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-7.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-insert-exp-8.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-test-data-class-11.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-test-data-class-6.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-test-data-class-7.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-test-neg-2.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-test-neg-3.c: Adjust.
+ * gcc.target/powerpc/bfp/scalar-test-neg-5.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-extract-exp-2.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-extract-exp-3.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-extract-sig-2.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-extract-sig-3.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-insert-exp-2.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-insert-exp-3.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-insert-exp-6.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-insert-exp-7.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-test-data-class-2.c: Adjust.
+ * gcc.target/powerpc/bfp/vec-test-data-class-3.c: Adjust.
+ * gcc.target/powerpc/byte-in-either-range-1.c: Adjust.
+ * gcc.target/powerpc/byte-in-range-1.c: Adjust.
+ * gcc.target/powerpc/byte-in-set-1.c: Adjust.
+ * gcc.target/powerpc/byte-in-set-2.c: Adjust.
+ * gcc.target/powerpc/cmpb-3.c: Adjust.
+ * gcc.target/powerpc/crypto-builtin-2.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-1.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-11.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-16.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-21.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-26.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-31.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-36.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-41.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-46.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-51.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-56.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-6.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-61.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-66.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-71.c: Adjust.
+ * gcc.target/powerpc/dfp/dtstsfi-76.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-all-nez-7.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-any-eqz-7.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-cmpnez-7.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xl-len-12.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xl-len-13.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xlx-7.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xrx-7.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xst-len-12.c: Adjust.
+ * gcc.target/powerpc/vsu/vec-xst-len-13.c: Adjust.
+
+2019-07-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/91149
+ * c-c++-common/gomp/reduction-task-3.c: New test.
+
+ * c-c++-common/gomp/order-3.c: New test.
+ * c-c++-common/gomp/order-4.c: New test.
+
+2019-07-12 Bill Seurer <seurer@linux.vnet.ibm.com>
+
+ * gcc.dg/tree-ssa/vector-7.c: Fix typo.
+
+2019-07-12 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.dg/pr57438-2.c: Remove.
+
+2019-07-12 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/Warray-bounds-43.c: New test.
+
+2019-07-12 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/alias-access-path-9.c: New testcase.
+
+2019-07-08 Jiangning Liu <jiangning.liu@amperecomputing.com>
+
+ PR tree-optimization/89430
+ * gcc.dg/tree-ssa/pr89430-1.c: New test.
+ * gcc.dg/tree-ssa/pr89430-2.c: New test.
+ * gcc.dg/tree-ssa/pr89430-3.c: New test.
+ * gcc.dg/tree-ssa/pr89430-4.c: New test.
+ * gcc.dg/tree-ssa/pr89430-5.c: New test.
+ * gcc.dg/tree-ssa/pr89430-6.c: New test.
+
+2019-07-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91145
+ * gcc.dg/torture/pr91145.c: New testcase.
+
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.dg/gimplefe-44.c: New.
+ * gcc.dg/gimplefe-43.c: New.
+
+2019-07-12 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/vector-7.c: New testcase.
+
+2019-07-12 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/order-1.c: New test.
+ * c-c++-common/gomp/order-2.c: New test.
+
+2019-07-11 Sunil K Pandey <sunil.k.pandey@intel.com>
+
+ PR target/90980
+ * gcc.target/i386/pr90980-1.c: New test.
+ * gcc.target/i386/pr90980-2.c: Likewise.
+ * gcc.target/i386/pr90980-3.c: Likewise.
+
+2019-07-11 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/loop_entry1.adb: New testcase.
+
+2019-07-11 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/prot8.adb, gnat.dg/prot8.ads: New testcase.
+
+2019-07-11 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/unreferenced2.adb: New testcase.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * gnat.dg/self_ref1.adb: New testcase.
+
+2019-07-11 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/predicate11.adb: New testcase.
+
+2019-07-11 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * gnat.dg/equal9.adb: New testcase.
+
+2019-07-11 Thomas Quinot <quinot@adacore.com>
+
+ * gnat.dg/scos1.adb: New testcase.
+
+2019-07-11 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/access7.adb: New testcase.
+
+2019-07-11 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/warn21.adb, gnat.dg/warn21.ads: New testcase.
+
+2019-07-11 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91131
+ * gcc.target/i386/pr91131.c: New testcase.
+
+2019-07-10 Martin Sebor <msebor@redhat.com>
+
+ PR testsuite/91132
+ * gcc.dg/strlenopt-67.c: Removed second copy of test.
+
+2019-07-10 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/91102
+ * gcc.target/aarch64/pr91102.c: New test.
+
+2019-07-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91126
+ * gcc.dg/torture/pr91126.c: New testcase.
+
+2019-07-10 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/torture/ssa-fre-5.c: New testcase.
+ * gcc.dg/torture/ssa-fre-6.c: Likewise.
+ * gcc.dg/torture/ssa-fre-7.c: Likewise.
+
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/modular5.adb: New testcase.
+
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/limited3.adb, gnat.dg/limited3_pkg.adb,
+ gnat.dg/limited3_pkg.ads: New testcase.
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * gnat.dg/incomplete7.adb, gnat.dg/incomplete7.ads: New testcase.
+
+2019-07-10 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * gnat.dg/limited2.adb, gnat.dg/limited2_pack_1.adb,
+ gnat.dg/limited2_pack_1.ads, gnat.dg/limited2_pack_2.adb,
+ gnat.dg/limited2_pack_2.ads: New testcase.
+
+2019-07-10 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/equal8.adb, gnat.dg/equal8.ads,
+ gnat.dg/equal8_pkg.ads: New testcase.
+
+2019-07-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/diagnostic/complex-invalid-1.C: New.
+ * g++.dg/diagnostic/static-cdtor-1.C: Likewise.
+ * g++.dg/cpp1z/has-unique-obj-representations2.C: Test location
+ too.
+ * g++.dg/other/anon-union3.C: Adjust expected location.
+ * g++.dg/parse/error8.C: Likewise.
+
+2019-07-09 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/lto/alias-3_0.C: New file.
+ * g++.dg/lto/alias-3_1.c: New file.
+
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/90989
+ * gcc.dg/strlenopt-26.c: Exit with test result status.
+ * gcc.dg/strlenopt-67.c: New test.
+
+2019-07-09 Dragan Mladjenovic <dmladjenovic@wavecomp.com>
+
+ * gcc.target/mips/cfgcleanup-jalr1.c: New test.
+ * gcc.target/mips/cfgcleanup-jalr2.c: New test.
+ * gcc.target/mips/cfgcleanup-jalr3.c: New test.
+
+2019-07-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91114
+ * gcc.dg/vect/pr91114.c: New testcase.
+
+2019-07-09 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ * gcc.target/aarch64/crypto-fuse-1.c: Remove.
+ * gcc.target/aarch64/crypto-fuse-2.c: Remove.
+ * gcc.target/aarch64/aes-fuse-1.c: New testcase.
+ * gcc.target/aarch64/aes-fuse-2.c: New testcase.
+
+2019-07-09 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/arm/cmse/bitfield-1.c: Fix address of .gnu.sgstubs
+ section.
+ * gcc.target/arm/cmse/bitfield-2.c: Likewise.
+ * gcc.target/arm/cmse/bitfield-3.c: Likewise.
+ * gcc.target/arm/cmse/struct-1.c: Likewise.
+
+2019-07-09 Sylvia Taylor <sylvia.taylor@arm.com>
+
+ * gcc.target/arm/aes-fuse-1.c: New.
+ * gcc.target/arm/aes-fuse-2.c: New.
+ * gcc.target/arm/aes_xor_combine.c: New.
+
+2019-07-09 Martin Liska <mliska@suse.cz>
+
+ * gcc.dg/predict-17.c: Test loop optimizer assumption
+ about loop iterations.
+
+2019-07-09 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/alias-access-path-1.c: Scan fre1 dump.
+ * gcc.dg/tree-ssa/alias-access-path-2.c: Likewise.
+ * gcc.dg/tree-ssa/alias-access-path-8.c: Likewise.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/predicate10.adb, gnat.dg/predicate10_pkg.adb,
+ gnat.dg/predicate10_pkg.ads: New testcase.
+
+2019-07-09 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/image1.adb: New testcase.
+
+2019-07-09 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/rep_clause8.adb: New testcase.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/equal7.adb, gnat.dg/equal7_pkg.adb,
+ gnat.dg/equal7_pkg.ads: New testcase.
+
+2019-07-09 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/range_check3.adb, gnat.dg/range_check3_pkg.adb,
+ gnat.dg/range_check3_pkg.ads: New testcase.
+
+2019-07-09 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/generic_inst5.adb, gnat.dg/generic_inst6.adb,
+ gnat.dg/generic_inst6_g1-c.adb, gnat.dg/generic_inst6_g1-c.ads,
+ gnat.dg/generic_inst6_g1.ads, gnat.dg/generic_inst6_i1.ads,
+ gnat.dg/generic_inst6_i2.ads, gnat.dg/generic_inst6_x.ads: New
+ testcases.
+
+2019-07-08 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/71924
+ PR middle-end/90549
+ * gcc.c-torture/execute/return-addr.c: New test.
+ * gcc.dg/Wreturn-local-addr-2.c: New test.
+ * gcc.dg/Wreturn-local-addr-4.c: New test.
+ * gcc.dg/Wreturn-local-addr-5.c: New test.
+ * gcc.dg/Wreturn-local-addr-6.c: New test.
+ * gcc.dg/Wreturn-local-addr-7.c: New test.
+ * gcc.dg/Wreturn-local-addr-8.c: New test.
+ * gcc.dg/Wreturn-local-addr-9.c: New test.
+ * gcc.dg/Wreturn-local-addr-10.c: New test.
+ * gcc.dg/Walloca-4.c: Handle expected warnings.
+ * gcc.dg/pr41551.c: Same.
+ * gcc.dg/pr59523.c: Same.
+ * gcc.dg/tree-ssa/pr88775-2.c: Same.
+ * gcc.dg/tree-ssa/alias-37.c: Same.
+ * gcc.dg/winline-7.c: Same.
+
+2019-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/vect/simd-6.cc: Replace xfail with target x86.
+ * g++.dg/vect/simd-9.cc: Likewise.
+
+ PR c++/91110
+ * g++.dg/gomp/pr91110.C: New test.
+
+2019-07-08 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/88233
+ * gcc.target/powerpc/pr88233.c: New testcase.
+
+2019-07-08 Wilco Dijkstra <wdijkstr@arm.com>
+
+ PR testsuite/91059
+ PR testsuite/78529
+ * gcc.c-torture/execute/builtins/builtins.exp: Add -fno-ipa-ra.
+
+2019-07-08 Robin Dapp <rdapp@linux.ibm.com>
+
+ * gcc.target/s390/rotate-truncation-mask.c: New test.
+
+2019-07-08 Robin Dapp <rdapp@linux.ibm.com>
+
+ * gcc.target/s390/combine-rotate-modulo.c: New test.
+ * gcc.target/s390/combine-shift-rotate-add-mod.c: New test.
+ * gcc.target/s390/vector/combine-shift-vec.c: New test.
+
+2019-07-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91108
+ * gcc.dg/tree-ssa/ssa-fre-61.c: Adjust back.
+ * gcc.dg/tree-ssa/ssa-fre-78.c: New testcase.
+
+2019-07-08 Jim Wilson <jimw@sifive.com>
+
+ * gcc.target/riscv/shift-shift-2.c: Add one more test.
+
+2019-07-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/65143
+ * g++.dg/tree-ssa/final2.C: New.
+ * g++.dg/tree-ssa/final3.C: Likewise.
+
+2019-07-08 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/interface10.adb: New testcase.
+
+2019-07-08 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * gnat.dg/addr13.adb, gnat.dg/addr13.ads: New testcase.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/entry1.adb, gnat.dg/entry1.ads: New testcase.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/fixed_delete.adb: New testcase.
+
+2019-07-08 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/interface9.adb, gnat.dg/interface9_root-child.ads,
+ gnat.dg/interface9_root.ads: New testcase.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/predicate9.adb: New testcase.
+
+2019-07-08 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/sso16.adb: New testcase.
+
+2019-07-08 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/predicate8.adb, gnat.dg/predicate8_pkg.adb,
+ gnat.dg/predicate8_pkg.ads: New testcase.
+
+2019-07-08 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/83518
+ * gcc.dg/tree-ssa/ssa-fre-73.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-fre-74.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-75.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-76.c: Likewise.
+ * g++.dg/tree-ssa/pr83518.C: Likewise.
+
+2019-07-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/guality/guality.h: Include <sys/prctl.h> on Linux targets.
+ (main): Use PR_SET_PTRACER where available.
+
+2019-07-07 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/91077
+ * gfortran.dg/pointer_array_11.f90 : New test.
+
+2019-07-06 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/scan-4.c: Don't expect sorry message.
+
+ PR tree-optimization/91096
+ * gcc.dg/vect/vect-simd-10.c (FLT_MIN_VALUE): Define.
+ (bar, main): Use it instead of -__builtin_inff ().
+ * gcc.dg/vect/vect-simd-14.c (FLT_MIN_VALUE): Define.
+ (bar, main): Use it instead of -__builtin_inff ().
+
+2019-07-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/67184 (again)
+ PR c++/69445
+ * g++.dg/other/final4.C: New.
+
+2019-07-04 Marek Polacek <polacek@redhat.com>
+
+ DR 1813
+ PR c++/83374 - __is_standard_layout wrong for a class with repeated
+ bases.
+ * g++.dg/ext/is_std_layout3.C: New test.
+ * g++.dg/ext/is_std_layout4.C: New test.
+
+2019-07-05 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-fre-77.c: New testcase.
+
+2019-07-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91091
+ * gcc.dg/tree-ssa/pr91091-2.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-fre-70.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-71.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-72.c: Likewise.
+
+2019-07-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91091
+ * gcc.dg/tree-ssa/pr91091-1.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-fre-61.c: Adjust.
+
+2019-07-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/pack23.adb, gnat.dg/pack23_pkg.ads: New testcase.
+
+2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * gnat.dg/task3.adb, gnat.dg/task3.ads, gnat.dg/task3_pkg1.ads,
+ gnat.dg/task3_pkg2.ads: New testcase.
+
+2019-07-05 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/access6.adb: New testcase.
+
+2019-07-05 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/bip_export.adb, gnat.dg/bip_export.ads: New testcase.
+
+2019-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/aggr25.adb, gnat.dg/aggr25.ads: New testcase.
+
+2019-07-05 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/predicate7.adb, gnat.dg/predicate7.ads,
+ gnat.dg/predicate7_pkg.ads: New testcase.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/78884
+ * gcc.dg/gomp/pr78884.c: New test.
+
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+
+ * jit.dg/test-error-gcc_jit_context_new_binary_op-bad-res-type.c:
+ New testcase.
+
+2019-07-04 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * gcc.dg/tree-ssa/cunroll-15.c: Remove XFAIL on arm.
+
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+
+ * jit.dg/all-non-failing-tests.h: Add test-accessing-bitfield.c.
+ * jit.dg/test-accessing-bitfield.c: New testcase.
+ * jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c:
+ Likewise.
+ * jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c:
+ Likewise.
+ * jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c:
+ Likewise.
+
+2019-07-04 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/alias-access-path-3.c: New testcase.
+ * gcc.dg/tree-ssa/alias-access-path-8.c: New testcase.
+
+2019-07-04 Andrew Stubbs <ams@codesourcery.com>
+
+ * g++.dg/gomp/unmappable-1.C: New file.
+
+2019-07-04 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/cpp_constructor.adb, gnat.dg/cpp_constructor_fp.ads,
+ gnat.dg/cpp_constructor_useit.ads: New testcase.
+
+2019-07-04 Gary Dismukes <dismukes@adacore.com>
+
+ * gnat.dg/ghost5.adb, gnat.dg/ghost5.ads,
+ gnat.dg/ghost5_parent.ads: New testcase.
+
+2019-07-04 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/spark3.adb: New testcase.
+
+2019-07-04 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/tagged2.adb, gnat.dg/tagged2.ads: New testcase.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/equal6.adb, gnat.dg/equal6_types.adb,
+ gnat.dg/equal6_types.ads: New testcase.
+
+2019-07-04 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/allocator.adb: New testcase.
+
+2019-07-04 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * gnat.dg/default_initial_condition.adb,
+ gnat.dg/default_initial_condition_pack.adb,
+ gnat.dg/default_initial_condition_pack.ads: New testcase.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/aspect2.adb, gnat.dg/aspect2.ads: New testcase.
+
+2019-07-04 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/synchronized2.adb, gnat.dg/synchronized2.ads,
+ gnat.dg/synchronized2_pkg.ads: New testcase.
+
+2019-07-04 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/generic_inst4.adb, gnat.dg/generic_inst4_gen.ads,
+ gnat.dg/generic_inst4_inst.ads, gnat.dg/generic_inst4_typ.ads:
+ New testcase.
+
+2019-07-04 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/dimensions2.adb, gnat.dg/dimensions2_phys.ads,
+ gnat.dg/dimensions2_real_numbers.ads: New testcase.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91063
+ * gcc.dg/gomp/pr91063.c: New test.
+
+2019-07-04 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR target/88833
+ * gfortran.dg/pr88833.f90: New test.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91069
+ * gcc.dg/pr91069.c (v2df): Use 2 * sizeof (double) instead of
+ hardcoded 16 for better portability.
+ (v2di): Change from long vector to long long vector. Use
+ 2 * sizeof (long long) instead of hardcoded 16.
+
+ PR rtl-optimization/90756
+ * gcc.dg/pr90756.c: New test.
+
+2019-07-04 Chenghua Xu <paul.hua.gm@gmail.com>
+
+ * gcc.target/mips/mips-fmadd.c: Rename to ...
+ * gcc.target/mips/mips-fmadd-o32.c: ... Here; add abi=32.
+ * gcc.target/mips/mips-fmadd-n64.c: New.
+
2019-07-03 Wilco Dijkstra <wdijkstr@arm.com>
* gcc.dg/store_merging_27.c: Fix test for Arm.
@@ -33,7 +1006,7 @@
PR tree-optimization/91033
* gcc.target/i386/pr91033.c: New test.
-
+
2019-07-03 Bob Duff <duff@adacore.com>
* gnat.dg/task2.adb, gnat.dg/task2_pkg.adb,
@@ -1329,8 +2302,8 @@
2019-06-12 Przemyslaw Wirkus <przemyslaw.wirkus@arm.com>
- * gcc.target/arm/ssadv16qi.c: New test.
- * gcc.target/arm/usadv16qi.c: Likewise.
+ * gcc.target/arm/ssadv16qi.c: New test.
+ * gcc.target/arm/usadv16qi.c: Likewise.
2019-06-12 Jakub Jelinek <jakub@redhat.com>
@@ -2613,123 +3586,123 @@
2019-05-16 Martin Sebor <msebor@redhat.com>
- * c-c++-common/Wbool-operation-1.c: Adjust text of expected diagnostics.
- * c-c++-common/Wvarargs-2.c: Same.
- * c-c++-common/Wvarargs.c: Same.
- * c-c++-common/pr51768.c: Same.
- * c-c++-common/tm/inline-asm.c: Same.
- * c-c++-common/tm/safe-1.c: Same.
- * g++.dg/asm-qual-1.C: Same.
- * g++.dg/asm-qual-3.C: Same.
- * g++.dg/conversion/dynamic1.C: Same.
- * g++.dg/cpp0x/constexpr-89599.C: Same.
- * g++.dg/cpp0x/constexpr-cast.C: Same.
- * g++.dg/cpp0x/constexpr-shift1.C: Same.
- * g++.dg/cpp0x/lambda/lambda-conv11.C: Same.
- * g++.dg/cpp0x/nullptr04.C: Same.
- * g++.dg/cpp0x/static_assert12.C: Same.
- * g++.dg/cpp0x/static_assert8.C: Same.
- * g++.dg/cpp1y/lambda-conv1.C: Same.
- * g++.dg/cpp1y/pr79393-3.C: Same.
- * g++.dg/cpp1y/static_assert1.C: Same.
- * g++.dg/cpp1z/constexpr-if4.C: Same.
- * g++.dg/cpp1z/constexpr-if5.C: Same.
- * g++.dg/cpp1z/constexpr-if9.C: Same.
- * g++.dg/eh/goto2.C: Same.
- * g++.dg/eh/goto3.C: Same.
- * g++.dg/expr/static_cast8.C: Same.
- * g++.dg/ext/flexary5.C: Same.
- * g++.dg/ext/utf-array-short-wchar.C: Same.
- * g++.dg/ext/utf-array.C: Same.
- * g++.dg/ext/utf8-2.C: Same.
- * g++.dg/gomp/loop-4.C: Same.
- * g++.dg/gomp/macro-4.C: Same.
- * g++.dg/gomp/udr-1.C: Same.
- * g++.dg/init/initializer-string-too-long.C: Same.
- * g++.dg/other/offsetof9.C: Same.
- * g++.dg/ubsan/pr63956.C: Same.
- * g++.dg/warn/Wbool-operation-1.C: Same.
- * g++.dg/warn/Wtype-limits-Wextra.C: Same.
- * g++.dg/warn/Wtype-limits.C: Same.
- * g++.dg/wrappers/pr88680.C: Same.
- * g++.old-deja/g++.mike/eh55.C: Same.
- * gcc.dg/Wsign-compare-1.c: Same.
- * gcc.dg/Wtype-limits-Wextra.c: Same.
- * gcc.dg/Wtype-limits.c: Same.
- * gcc.dg/Wunknownprag.c: Same.
- * gcc.dg/Wunsuffixed-float-constants-1.c: Same.
- * gcc.dg/asm-6.c: Same.
- * gcc.dg/asm-qual-1.c: Same.
- * gcc.dg/cast-1.c: Same.
- * gcc.dg/cast-2.c: Same.
- * gcc.dg/cast-3.c: Same.
- * gcc.dg/cpp/source_date_epoch-2.c: Same.
- * gcc.dg/debug/pr85252.c: Same.
- * gcc.dg/dfp/cast-bad.c: Same.
- * gcc.dg/format/gcc_diag-1.c: Same.
- * gcc.dg/format/gcc_diag-11.c: Same.
- * gcc.dg/gcc_diag-11.c: Same.
- * gcc.dg/gnu-cond-expr-2.c: Same.
- * gcc.dg/gnu-cond-expr-3.c: Same.
- * gcc.dg/gomp/macro-4.c: Same.
- * gcc.dg/init-bad-1.c: Same.
- * gcc.dg/init-bad-2.c: Same.
- * gcc.dg/init-bad-3.c: Same.
- * gcc.dg/pr27528.c: Same.
- * gcc.dg/pr48552-1.c: Same.
- * gcc.dg/pr48552-2.c: Same.
- * gcc.dg/pr59846.c: Same.
- * gcc.dg/pr61096-1.c: Same.
- * gcc.dg/pr8788-1.c: Same.
- * gcc.dg/pr90082.c: Same.
- * gcc.dg/simd-2.c: Same.
- * gcc.dg/spellcheck-params-2.c: Same.
- * gcc.dg/spellcheck-params.c: Same.
- * gcc.dg/strlenopt-49.c: Same.
- * gcc.dg/tm/pr52141.c: Same.
- * gcc.dg/torture/pr51106-1.c: Same.
- * gcc.dg/torture/pr51106-2.c: Same.
- * gcc.dg/utf-array-short-wchar.c: Same.
- * gcc.dg/utf-array.c: Same.
- * gcc.dg/utf8-2.c: Same.
- * gcc.dg/warn-sprintf-no-nul.c: Same.
- * gcc.target/i386/asm-flag-0.c: Same.
- * gcc.target/i386/inline_error.c: Same.
- * gcc.target/i386/pr30848.c: Same.
- * gcc.target/i386/pr39082-1.c: Same.
- * gcc.target/i386/pr39678.c: Same.
- * gcc.target/i386/pr57756.c: Same.
- * gcc.target/i386/pr68843-1.c: Same.
- * gcc.target/i386/pr79804.c: Same.
- * gcc.target/i386/pr82673.c: Same.
- * obj-c++.dg/class-protocol-1.mm: Same.
- * obj-c++.dg/exceptions-3.mm: Same.
- * obj-c++.dg/exceptions-4.mm: Same.
- * obj-c++.dg/exceptions-5.mm: Same.
- * obj-c++.dg/exceptions-6.mm: Same.
- * obj-c++.dg/method-12.mm: Same.
- * obj-c++.dg/method-13.mm: Same.
- * obj-c++.dg/method-6.mm: Same.
- * obj-c++.dg/method-7.mm: Same.
- * obj-c++.dg/method-9.mm: Same.
- * obj-c++.dg/method-lookup-1.mm: Same.
- * obj-c++.dg/proto-lossage-4.mm: Same.
- * obj-c++.dg/protocol-qualifier-2.mm: Same.
- * objc.dg/call-super-2.m: Same.
- * objc.dg/class-protocol-1.m: Same.
- * objc.dg/desig-init-1.m: Same.
- * objc.dg/exceptions-3.m: Same.
- * objc.dg/exceptions-4.m: Same.
- * objc.dg/exceptions-5.m: Same.
- * objc.dg/exceptions-6.m: Same.
- * objc.dg/method-19.m: Same.
- * objc.dg/method-2.m: Same.
- * objc.dg/method-5.m: Same.
- * objc.dg/method-6.m: Same.
- * objc.dg/method-7.m: Same.
- * objc.dg/method-lookup-1.m: Same.
- * objc.dg/proto-hier-1.m: Same.
- * objc.dg/proto-lossage-4.m: Same.
+ * c-c++-common/Wbool-operation-1.c: Adjust text of expected diagnostics.
+ * c-c++-common/Wvarargs-2.c: Same.
+ * c-c++-common/Wvarargs.c: Same.
+ * c-c++-common/pr51768.c: Same.
+ * c-c++-common/tm/inline-asm.c: Same.
+ * c-c++-common/tm/safe-1.c: Same.
+ * g++.dg/asm-qual-1.C: Same.
+ * g++.dg/asm-qual-3.C: Same.
+ * g++.dg/conversion/dynamic1.C: Same.
+ * g++.dg/cpp0x/constexpr-89599.C: Same.
+ * g++.dg/cpp0x/constexpr-cast.C: Same.
+ * g++.dg/cpp0x/constexpr-shift1.C: Same.
+ * g++.dg/cpp0x/lambda/lambda-conv11.C: Same.
+ * g++.dg/cpp0x/nullptr04.C: Same.
+ * g++.dg/cpp0x/static_assert12.C: Same.
+ * g++.dg/cpp0x/static_assert8.C: Same.
+ * g++.dg/cpp1y/lambda-conv1.C: Same.
+ * g++.dg/cpp1y/pr79393-3.C: Same.
+ * g++.dg/cpp1y/static_assert1.C: Same.
+ * g++.dg/cpp1z/constexpr-if4.C: Same.
+ * g++.dg/cpp1z/constexpr-if5.C: Same.
+ * g++.dg/cpp1z/constexpr-if9.C: Same.
+ * g++.dg/eh/goto2.C: Same.
+ * g++.dg/eh/goto3.C: Same.
+ * g++.dg/expr/static_cast8.C: Same.
+ * g++.dg/ext/flexary5.C: Same.
+ * g++.dg/ext/utf-array-short-wchar.C: Same.
+ * g++.dg/ext/utf-array.C: Same.
+ * g++.dg/ext/utf8-2.C: Same.
+ * g++.dg/gomp/loop-4.C: Same.
+ * g++.dg/gomp/macro-4.C: Same.
+ * g++.dg/gomp/udr-1.C: Same.
+ * g++.dg/init/initializer-string-too-long.C: Same.
+ * g++.dg/other/offsetof9.C: Same.
+ * g++.dg/ubsan/pr63956.C: Same.
+ * g++.dg/warn/Wbool-operation-1.C: Same.
+ * g++.dg/warn/Wtype-limits-Wextra.C: Same.
+ * g++.dg/warn/Wtype-limits.C: Same.
+ * g++.dg/wrappers/pr88680.C: Same.
+ * g++.old-deja/g++.mike/eh55.C: Same.
+ * gcc.dg/Wsign-compare-1.c: Same.
+ * gcc.dg/Wtype-limits-Wextra.c: Same.
+ * gcc.dg/Wtype-limits.c: Same.
+ * gcc.dg/Wunknownprag.c: Same.
+ * gcc.dg/Wunsuffixed-float-constants-1.c: Same.
+ * gcc.dg/asm-6.c: Same.
+ * gcc.dg/asm-qual-1.c: Same.
+ * gcc.dg/cast-1.c: Same.
+ * gcc.dg/cast-2.c: Same.
+ * gcc.dg/cast-3.c: Same.
+ * gcc.dg/cpp/source_date_epoch-2.c: Same.
+ * gcc.dg/debug/pr85252.c: Same.
+ * gcc.dg/dfp/cast-bad.c: Same.
+ * gcc.dg/format/gcc_diag-1.c: Same.
+ * gcc.dg/format/gcc_diag-11.c: Same.
+ * gcc.dg/gcc_diag-11.c: Same.
+ * gcc.dg/gnu-cond-expr-2.c: Same.
+ * gcc.dg/gnu-cond-expr-3.c: Same.
+ * gcc.dg/gomp/macro-4.c: Same.
+ * gcc.dg/init-bad-1.c: Same.
+ * gcc.dg/init-bad-2.c: Same.
+ * gcc.dg/init-bad-3.c: Same.
+ * gcc.dg/pr27528.c: Same.
+ * gcc.dg/pr48552-1.c: Same.
+ * gcc.dg/pr48552-2.c: Same.
+ * gcc.dg/pr59846.c: Same.
+ * gcc.dg/pr61096-1.c: Same.
+ * gcc.dg/pr8788-1.c: Same.
+ * gcc.dg/pr90082.c: Same.
+ * gcc.dg/simd-2.c: Same.
+ * gcc.dg/spellcheck-params-2.c: Same.
+ * gcc.dg/spellcheck-params.c: Same.
+ * gcc.dg/strlenopt-49.c: Same.
+ * gcc.dg/tm/pr52141.c: Same.
+ * gcc.dg/torture/pr51106-1.c: Same.
+ * gcc.dg/torture/pr51106-2.c: Same.
+ * gcc.dg/utf-array-short-wchar.c: Same.
+ * gcc.dg/utf-array.c: Same.
+ * gcc.dg/utf8-2.c: Same.
+ * gcc.dg/warn-sprintf-no-nul.c: Same.
+ * gcc.target/i386/asm-flag-0.c: Same.
+ * gcc.target/i386/inline_error.c: Same.
+ * gcc.target/i386/pr30848.c: Same.
+ * gcc.target/i386/pr39082-1.c: Same.
+ * gcc.target/i386/pr39678.c: Same.
+ * gcc.target/i386/pr57756.c: Same.
+ * gcc.target/i386/pr68843-1.c: Same.
+ * gcc.target/i386/pr79804.c: Same.
+ * gcc.target/i386/pr82673.c: Same.
+ * obj-c++.dg/class-protocol-1.mm: Same.
+ * obj-c++.dg/exceptions-3.mm: Same.
+ * obj-c++.dg/exceptions-4.mm: Same.
+ * obj-c++.dg/exceptions-5.mm: Same.
+ * obj-c++.dg/exceptions-6.mm: Same.
+ * obj-c++.dg/method-12.mm: Same.
+ * obj-c++.dg/method-13.mm: Same.
+ * obj-c++.dg/method-6.mm: Same.
+ * obj-c++.dg/method-7.mm: Same.
+ * obj-c++.dg/method-9.mm: Same.
+ * obj-c++.dg/method-lookup-1.mm: Same.
+ * obj-c++.dg/proto-lossage-4.mm: Same.
+ * obj-c++.dg/protocol-qualifier-2.mm: Same.
+ * objc.dg/call-super-2.m: Same.
+ * objc.dg/class-protocol-1.m: Same.
+ * objc.dg/desig-init-1.m: Same.
+ * objc.dg/exceptions-3.m: Same.
+ * objc.dg/exceptions-4.m: Same.
+ * objc.dg/exceptions-5.m: Same.
+ * objc.dg/exceptions-6.m: Same.
+ * objc.dg/method-19.m: Same.
+ * objc.dg/method-2.m: Same.
+ * objc.dg/method-5.m: Same.
+ * objc.dg/method-6.m: Same.
+ * objc.dg/method-7.m: Same.
+ * objc.dg/method-lookup-1.m: Same.
+ * objc.dg/proto-hier-1.m: Same.
+ * objc.dg/proto-lossage-4.m: Same.
2019-05-17 Dragan Mladjenovic <dmladjenovic@wavecomp.com>
@@ -2842,7 +3815,7 @@
2019-05-15 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/90461
- * gfortran.dg/open_errors_2.f90: Add -std=f2008, adjust line number.
+ * gfortran.dg/open_errors_2.f90: Add -std=f2008, adjust line number.
* gfortran.dg/open_errors_3.f90: New test.
2019-05-15 H.J. Lu <hongjiu.lu@intel.com>
@@ -3570,10 +4543,10 @@
2019-04-29 Vladislav Ivanishin <vlad@ispras.ru>
- * gcc.dg/uninit-25-gimple.c: New test.
- * gcc.dg/uninit-25.c: New test.
- * gcc.dg/uninit-26.c: New test.
- * gcc.dg/uninit-27-gimple.c: New test.
+ * gcc.dg/uninit-25-gimple.c: New test.
+ * gcc.dg/uninit-25.c: New test.
+ * gcc.dg/uninit-26.c: New test.
+ * gcc.dg/uninit-27-gimple.c: New test.
2019-04-29 Richard Biener <rguenther@suse.de>
diff --git a/gcc/testsuite/c-c++-common/gomp/cancel-1.c b/gcc/testsuite/c-c++-common/gomp/cancel-1.c
index 03aedeb..5255dd3 100644
--- a/gcc/testsuite/c-c++-common/gomp/cancel-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/cancel-1.c
@@ -336,14 +336,14 @@ f2 (void)
}
#pragma omp target teams
{
- #pragma omp cancel parallel /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
- #pragma omp cancel for /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
- #pragma omp cancel sections /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
- #pragma omp cancel taskgroup /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
- #pragma omp cancellation point parallel /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
- #pragma omp cancellation point for /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
- #pragma omp cancellation point sections /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
- #pragma omp cancellation point taskgroup /* { dg-error "only .distribute. or .parallel. regions are allowed to be strictly nested" } */
+ #pragma omp cancel parallel /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
+ #pragma omp cancel for /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
+ #pragma omp cancel sections /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
+ #pragma omp cancel taskgroup /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
+ #pragma omp cancellation point parallel /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
+ #pragma omp cancellation point for /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
+ #pragma omp cancellation point sections /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
+ #pragma omp cancellation point taskgroup /* { dg-error "only .distribute., .parallel. or .loop. regions are allowed to be strictly nested" } */
}
#pragma omp target teams distribute
for (i = 0; i < 10; i++)
diff --git a/gcc/testsuite/c-c++-common/gomp/clauses-1.c b/gcc/testsuite/c-c++-common/gomp/clauses-1.c
index 652270c..be42797 100644
--- a/gcc/testsuite/c-c++-common/gomp/clauses-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/clauses-1.c
@@ -14,22 +14,32 @@ foo (int d, int m, int i1, int i2, int p, int *idp, int s,
#pragma omp distribute parallel for \
private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
- lastprivate (l) schedule(static, 4)
+ lastprivate (l) schedule(static, 4) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp distribute parallel for simd \
private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
lastprivate (l) schedule(static, 4) nontemporal(ntm) \
- safelen(8) simdlen(4) aligned(q: 32)
+ safelen(8) simdlen(4) aligned(q: 32) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp distribute simd \
private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
- safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm)
+ safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
}
+
+void
+qux (int p)
+{
+ #pragma omp loop bind(teams) order(concurrent) \
+ private (p) lastprivate (l) collapse(1) reduction(+:r)
+ for (l = 0; l < 64; ++l)
+ ll++;
+}
#pragma omp end declare target
void
@@ -39,21 +49,26 @@ baz (int d, int m, int i1, int i2, int p, int *idp, int s,
#pragma omp distribute parallel for \
private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
- lastprivate (l) schedule(static, 4) copyin(t)
+ lastprivate (l) schedule(static, 4) copyin(t) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp distribute parallel for simd \
private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
if (parallel: i2) if(simd: i1) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
lastprivate (l) schedule(static, 4) nontemporal(ntm) \
- safelen(8) simdlen(4) aligned(q: 32) copyin(t)
+ safelen(8) simdlen(4) aligned(q: 32) copyin(t) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp distribute simd \
private (p) firstprivate (f) collapse(1) dist_schedule(static, 16) \
- safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm)
+ safelen(8) simdlen(4) aligned(q: 32) reduction(+:r) if(i1) nontemporal(ntm) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
+ #pragma omp loop bind(parallel) order(concurrent) \
+ private (p) lastprivate (l) collapse(1) reduction(+:r)
+ for (l = 0; l < 64; ++l)
+ ll++;
}
void
@@ -62,7 +77,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
{
#pragma omp for simd \
private (p) firstprivate (f) lastprivate (l) linear (ll:1) reduction(+:r) schedule(static, 4) collapse(1) nowait \
- safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) if(i1)
+ safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) if(i1) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp parallel for \
@@ -70,10 +85,15 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
lastprivate (l) linear (ll:1) ordered schedule(static, 4) collapse(1)
for (int i = 0; i < 64; i++)
ll++;
+ #pragma omp parallel for \
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \
+ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) order(concurrent)
+ for (int i = 0; i < 64; i++)
+ ll++;
#pragma omp parallel for simd \
private (p) firstprivate (f) if (i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \
lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) \
- safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm)
+ safelen(8) simdlen(4) aligned(q: 32) nontemporal(ntm) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp parallel sections \
@@ -96,11 +116,17 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
lastprivate (l) linear (ll:1) ordered schedule(static, 4) collapse(1) nowait depend(inout: dd[0])
for (int i = 0; i < 64; i++)
ll++;
+ #pragma omp target parallel for \
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
+ lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) nowait depend(inout: dd[0]) order(concurrent)
+ for (int i = 0; i < 64; i++)
+ ll++;
#pragma omp target parallel for simd \
device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
lastprivate (l) linear (ll:1) schedule(static, 4) collapse(1) \
- safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3)
+ safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp target teams \
@@ -118,7 +144,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
collapse(1) dist_schedule(static, 16) \
if (parallel: i2) num_threads (nth) proc_bind(spread) \
- lastprivate (l) schedule(static, 4) nowait depend(inout: dd[0])
+ lastprivate (l) schedule(static, 4) nowait depend(inout: dd[0]) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp target teams distribute parallel for simd \
@@ -126,39 +152,42 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
collapse(1) dist_schedule(static, 16) \
if (parallel: i2) num_threads (nth) proc_bind(spread) \
- lastprivate (l) schedule(static, 4) \
+ lastprivate (l) schedule(static, 4) order(concurrent) \
safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm) if (simd: i3)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp target teams distribute simd \
device(d) map (tofrom: m) if (i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
- collapse(1) dist_schedule(static, 16) \
+ collapse(1) dist_schedule(static, 16) order(concurrent) \
safelen(8) simdlen(4) aligned(q: 32) nowait depend(inout: dd[0]) nontemporal(ntm)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp target simd \
device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
safelen(8) simdlen(4) lastprivate (l) linear(ll: 1) aligned(q: 32) reduction(+:r) \
- nowait depend(inout: dd[0]) nontemporal(ntm) if(simd:i3)
+ nowait depend(inout: dd[0]) nontemporal(ntm) if(simd:i3) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp taskgroup task_reduction(+:r2)
#pragma omp taskloop simd \
private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
- safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp taskgroup task_reduction(+:r)
#pragma omp taskloop simd \
private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(i1) final(fi) mergeable nogroup priority (pp) \
- safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r) nontemporal(ntm)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) in_reduction(+:r) nontemporal(ntm) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp taskwait
#pragma omp taskloop simd \
private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) if(taskloop: i1) final(fi) priority (pp) \
- safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) if (simd: i3) nontemporal(ntm)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(+:r) if (simd: i3) nontemporal(ntm) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp target nowait depend(inout: dd[0])
@@ -172,7 +201,7 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
collapse(1) dist_schedule(static, 16) \
if (parallel: i2) num_threads (nth) proc_bind(spread) \
- lastprivate (l) schedule(static, 4)
+ lastprivate (l) schedule(static, 4) order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp target
@@ -180,20 +209,20 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
collapse(1) dist_schedule(static, 16) \
if (parallel: i2) num_threads (nth) proc_bind(spread) \
- lastprivate (l) schedule(static, 4) \
+ lastprivate (l) schedule(static, 4) order(concurrent) \
safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp target
#pragma omp teams distribute simd \
private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
- collapse(1) dist_schedule(static, 16) \
+ collapse(1) dist_schedule(static, 16) order(concurrent) \
safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp teams distribute parallel for \
private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
- collapse(1) dist_schedule(static, 16) \
+ collapse(1) dist_schedule(static, 16) order(concurrent) \
if (parallel: i2) num_threads (nth) proc_bind(spread) \
lastprivate (l) schedule(static, 4) copyin(t)
for (int i = 0; i < 64; i++)
@@ -202,13 +231,13 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
collapse(1) dist_schedule(static, 16) \
if (parallel: i2) num_threads (nth) proc_bind(spread) \
- lastprivate (l) schedule(static, 4) \
+ lastprivate (l) schedule(static, 4) order(concurrent) \
safelen(8) simdlen(4) aligned(q: 32) if (simd: i3) nontemporal(ntm) copyin(t)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp teams distribute simd \
private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
- collapse(1) dist_schedule(static, 16) \
+ collapse(1) dist_schedule(static, 16) order(concurrent) \
safelen(8) simdlen(4) aligned(q: 32) if(i3) nontemporal(ntm)
for (int i = 0; i < 64; i++)
ll++;
@@ -225,7 +254,8 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
#pragma omp taskgroup task_reduction (+:r2)
#pragma omp master taskloop simd \
private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
- safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp parallel master taskloop \
@@ -235,7 +265,8 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
ll++;
#pragma omp parallel master taskloop simd \
private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) grainsize (g) collapse(1) untied if(taskloop: i1) if(simd: i2) final(fi) mergeable priority (pp) \
- safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) if (parallel: i2) num_threads (nth) proc_bind(spread) copyin(t) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp taskgroup task_reduction (+:r2)
@@ -247,7 +278,8 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
#pragma omp taskgroup task_reduction (+:r2)
#pragma omp master taskloop simd \
private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
- safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) in_reduction(+:r2) nontemporal(ntm) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
#pragma omp parallel master taskloop \
@@ -257,7 +289,56 @@ bar (int d, int m, int i1, int i2, int i3, int p, int *idp, int s,
ll++;
#pragma omp parallel master taskloop simd \
private (p) firstprivate (f) lastprivate (l) shared (s) default(shared) num_tasks (nta) collapse(1) untied if(i1) final(fi) mergeable priority (pp) \
- safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t)
+ safelen(8) simdlen(4) linear(ll: 1) aligned(q: 32) reduction(default, +:r) nontemporal(ntm) num_threads (nth) proc_bind(spread) copyin(t) \
+ order(concurrent)
for (int i = 0; i < 64; i++)
ll++;
+ #pragma omp loop bind(thread) order(concurrent) \
+ private (p) lastprivate (l) collapse(1) reduction(+:r)
+ for (l = 0; l < 64; ++l)
+ ll++;
+ #pragma omp parallel loop \
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \
+ lastprivate (l) collapse(1) bind(parallel) order(concurrent)
+ for (l = 0; l < 64; l++)
+ ll++;
+ #pragma omp parallel loop \
+ private (p) firstprivate (f) if (parallel: i2) default(shared) shared(s) copyin(t) reduction(+:r) num_threads (nth) proc_bind(spread) \
+ lastprivate (l) collapse(1)
+ for (l = 0; l < 64; l++)
+ ll++;
+ #pragma omp teams loop \
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+ collapse(1) lastprivate (l) bind(teams)
+ for (l = 0; l < 64; ++l)
+ ;
+ #pragma omp teams loop \
+ private(p) firstprivate (f) shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) \
+ collapse(1) lastprivate (l) order(concurrent)
+ for (l = 0; l < 64; ++l)
+ ;
+ #pragma omp target parallel loop \
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
+ nowait depend(inout: dd[0]) lastprivate (l) bind(parallel) order(concurrent) collapse(1)
+ for (l = 0; l < 64; ++l)
+ ;
+ #pragma omp target parallel loop \
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
+ if (parallel: i2) default(shared) shared(s) reduction(+:r) num_threads (nth) proc_bind(spread) \
+ nowait depend(inout: dd[0]) lastprivate (l) order(concurrent) collapse(1)
+ for (l = 0; l < 64; ++l)
+ ;
+ #pragma omp target teams loop \
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0]) \
+ lastprivate (l) bind(teams) collapse(1)
+ for (l = 0; l < 64; ++l)
+ ;
+ #pragma omp target teams loop \
+ device(d) map (tofrom: m) if (target: i1) private (p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \
+ shared(s) default(shared) reduction(+:r) num_teams(nte) thread_limit(tl) nowait depend(inout: dd[0]) \
+ lastprivate (l) order(concurrent) collapse(1)
+ for (l = 0; l < 64; ++l)
+ ;
}
diff --git a/gcc/testsuite/c-c++-common/gomp/loop-1.c b/gcc/testsuite/c-c++-common/gomp/loop-1.c
new file mode 100644
index 0000000..d2f943a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/loop-1.c
@@ -0,0 +1,271 @@
+void foo (void);
+int v;
+#ifdef __cplusplus
+extern "C" {
+#endif
+int omp_get_thread_num (void);
+int omp_get_num_threads (void);
+int omp_target_is_present (const void *, int);
+int omp_get_cancellation (void);
+#ifdef __cplusplus
+}
+#endif
+
+void
+f1 (int *a)
+{
+ int i;
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp loop
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+}
+
+void
+f2 (int *a)
+{
+ int i;
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp loop
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+}
+
+void
+f3 (int *a)
+{
+ int i;
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp loop
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+}
+
+void
+f4 (int *a)
+{
+ int i;
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp parallel
+ foo ();
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp simd
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp loop
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp critical /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ foo ();
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp ordered simd /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ foo ();
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ v++;
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic read
+ a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic write /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */
+ v = a[i]; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */
+ }
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_thread_num (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_thread_num\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_num_threads (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_num_threads\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_target_is_present (a + i, 0); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_target_is_present\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop order(concurrent) bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_cancellation (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_cancellation\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+}
+
+void
+f5 (int *a)
+{
+ int i;
+ #pragma omp parallel
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp parallel
+ foo ();
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp simd
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp loop
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp critical /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ foo ();
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp ordered simd /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ foo ();
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ v++;
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic read
+ a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic write /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */
+ v = a[i]; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_thread_num (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_thread_num\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_num_threads (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_num_threads\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_target_is_present (a + i, 0); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_target_is_present\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_cancellation (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_cancellation\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ }
+}
+
+void
+f6 (int *a)
+{
+ int i;
+ #pragma omp master
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp parallel
+ foo ();
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp simd
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp loop
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp critical /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ foo ();
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp ordered simd /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ foo ();
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ v++;
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic read
+ a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" } */
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic write /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c++ } } */
+ v = a[i]; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a 'loop' region" "" { target c } } */
+ }
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_thread_num (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_thread_num\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_num_threads (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_num_threads\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_target_is_present (a + i, 0); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_target_is_present\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_cancellation (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_cancellation\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ }
+}
+
diff --git a/gcc/testsuite/c-c++-common/gomp/loop-2.c b/gcc/testsuite/c-c++-common/gomp/loop-2.c
new file mode 100644
index 0000000..ce9b6c9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/loop-2.c
@@ -0,0 +1,294 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+int omp_get_thread_num (void);
+#ifdef __cplusplus
+}
+#endif
+
+void
+f0 (int *a)
+{
+ int i;
+ #pragma omp loop bind(teams) order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+}
+
+void
+f1 (int *a)
+{
+ int i;
+ #pragma omp teams
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp teams
+ {
+ #pragma omp loop bind(teams)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp teams
+ {
+ #pragma omp loop bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp teams
+ {
+ #pragma omp loop lastprivate (i) bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+}
+
+void
+f2 (int *a)
+{
+ int i;
+ #pragma omp loop bind(parallel) order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ #pragma omp parallel
+ {
+ #pragma omp loop private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp parallel
+ {
+ #pragma omp loop lastprivate (i) bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp parallel
+ {
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp taskgroup
+ {
+ #pragma omp loop bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp teams
+ {
+ int j;
+ #pragma omp distribute
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ }
+ #pragma omp target
+ {
+ #pragma omp loop bind(parallel)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+}
+
+void
+f3 (int *a)
+{
+ int i, j;
+ #pragma omp loop order ( concurrent )bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ #pragma omp parallel num_threads (4)
+ {
+ int j = omp_get_thread_num ();
+ #pragma omp loop private (i) bind(thread)
+ for (i = 0; i < 64; i++)
+ a[j * 64 + i] = i;
+ }
+ #pragma omp critical
+ {
+ #pragma omp loop lastprivate (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp critical
+ {
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp master
+ {
+ #pragma omp loop private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp master
+ {
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp sections
+ {
+ #pragma omp loop private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp sections
+ {
+ #pragma omp loop bind(thread) lastprivate(i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp single
+ {
+ #pragma omp loop private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp single
+ {
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp task
+ {
+ #pragma omp loop private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp task
+ {
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp taskgroup
+ {
+ #pragma omp loop private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp taskgroup
+ {
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp teams
+ {
+ #pragma omp distribute
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ }
+ #pragma omp for
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp parallel
+ #pragma omp loop
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp loop bind(thread)
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp loop bind(parallel)
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp for ordered
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp ordered
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp ordered threads
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp simd
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp taskloop
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp target
+ {
+ #pragma omp loop
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+}
+
+void
+f4 (int *a)
+{
+ int i;
+ #pragma omp ordered
+ {
+ #pragma omp loop private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/loop-3.c b/gcc/testsuite/c-c++-common/gomp/loop-3.c
new file mode 100644
index 0000000..186b8cc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/loop-3.c
@@ -0,0 +1,145 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+int omp_get_thread_num (void);
+#ifdef __cplusplus
+}
+#endif
+
+void
+f1 (int *a)
+{
+ int i;
+ #pragma omp loop /* { dg-error "'bind' clause not specified on a 'loop' construct not nested inside another OpenMP construct" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+}
+
+void
+f2 (int *a)
+{
+ int i, j;
+ #pragma omp parallel num_threads (4)
+ {
+ int j = omp_get_thread_num ();
+ #pragma omp loop private (i) bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[j * 64 + i] = i;
+ }
+ #pragma omp critical
+ {
+ #pragma omp loop lastprivate (i) bind(teams)/* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp master
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp sections
+ {
+ #pragma omp loop bind(teams) lastprivate(i) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp single
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp task
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp taskgroup
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+ #pragma omp teams
+ {
+ #pragma omp distribute
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ }
+ #pragma omp for
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp parallel
+ #pragma omp loop
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp loop bind(thread)
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp loop bind(parallel)
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp for ordered
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp ordered threads
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp simd
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp taskloop
+ for (j = 0; j < 64; ++j)
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+ #pragma omp target
+ {
+ #pragma omp loop bind(teams) /* { dg-error "'bind\\(teams\\)' on a 'loop' region not strictly nested inside of a 'teams' region" } */
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ }
+}
+
+void
+f3 (int *a)
+{
+ int i, j;
+ #pragma omp simd
+ for (j = 0; j < 64; j++)
+ {
+ #pragma omp loop bind(parallel) /* { dg-error "'bind\\(parallel\\)' on a 'loop' construct nested inside 'simd' construct" } */
+ for (i = 0; i < 64; i++)
+ a[64 * j + i] = i;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/loop-4.c b/gcc/testsuite/c-c++-common/gomp/loop-4.c
new file mode 100644
index 0000000..b77f8c9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/loop-4.c
@@ -0,0 +1,46 @@
+int r, l;
+
+void
+f1 (int *a)
+{
+ int i;
+ #pragma omp master
+ {
+ #pragma omp loop bind /* { dg-error "expected" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind ) /* { dg-error "expected" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind ( /* { dg-error "expected" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind () /* { dg-error "expected" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind ( foobar ) /* { dg-error "expected" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind (default) /* { dg-error "expected" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind (parallel /* { dg-error "expected" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ }
+}
+
+void
+f2 (int *a)
+{
+ int i;
+ #pragma omp loop bind(parallel) reduction(task, +: r) /* { dg-error "invalid 'task' reduction modifier on construct other than 'parallel', 'for' or 'sections'" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind(thread) reduction(inscan, +: r) /* { dg-error "'inscan' 'reduction' clause on 'loop' construct" } */
+ for (i = 0; i < 64; ++i)
+ a[i] = i;
+ #pragma omp loop bind(parallel) lastprivate (l) /* { dg-error "'lastprivate' clause on a 'loop' construct refers to a variable 'l' which is not the loop iterator" } */
+ for (i = 0; i < 64; ++i)
+ l = i;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/loop-5.c b/gcc/testsuite/c-c++-common/gomp/loop-5.c
new file mode 100644
index 0000000..b9b2ad9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/loop-5.c
@@ -0,0 +1,56 @@
+__attribute__((noipa)) int
+foo (int *a, int *r3)
+{
+ int r = 0, r2[2] = { 0, 0 }, i;
+ #pragma omp parallel loop default (none) reduction (+:r, r2[:2], r3[:2]) shared (a) lastprivate (i)
+ for (i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ r2[0] += a[i];
+ r3[1] += a[i];
+ };
+ return r + r2[0] + r3[1] + i;
+}
+
+__attribute__((noipa)) int
+bar (int *a, int *r3)
+{
+ int r = 0, r2[2] = { 0, 0 }, i;
+ #pragma omp target parallel loop default (none) reduction (+:r, r2[0:2], r3[0:2]) shared (a) lastprivate (i)
+ for (i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ r2[1] += a[i];
+ r3[0] += a[i];
+ }
+ return r + r2[1] + r3[0] + i;
+}
+
+__attribute__((noipa)) int
+baz (int *a, int *r3)
+{
+ int r = 0, r2[2] = { 0, 0 }, i;
+ #pragma omp teams loop default (none) reduction (+:r, r2[0:2], r3[1:1]) shared (a) lastprivate (i)
+ for (i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ r2[0] += a[i];
+ r3[1] += a[i];
+ }
+ return r + r2[0] + r3[1] + i;
+}
+
+__attribute__((noipa)) int
+qux (int *a, int *r3)
+{
+ int r = 0, r2[2] = { 0, 0 }, i;
+ #pragma omp target teams loop default (none) reduction (+:r, r2[1:1], r3[0:2]) shared (a) lastprivate (i)
+ for (i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ r2[1] += a[i];
+ r3[0] += a[i] - 1;
+ r3[1] += a[i];
+ }
+ return r + r2[1] + r3[0] + r3[1] + i;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/order-1.c b/gcc/testsuite/c-c++-common/gomp/order-1.c
new file mode 100644
index 0000000..da4b73d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/order-1.c
@@ -0,0 +1,53 @@
+void
+f1 (int *a)
+{
+ int i;
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp simd order ( concurrent )
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+}
+
+void
+f2 (int *a)
+{
+ int i;
+ #pragma omp parallel for order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp parallel for simd order (concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp teams distribute parallel for order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp teams distribute parallel for simd order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp teams
+ {
+ #pragma omp distribute parallel for order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp distribute parallel for simd order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ }
+ #pragma omp taskloop simd order (concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+}
+
+void
+f3 (int *a)
+{
+ int i;
+ #pragma omp for order(concurrent) order(concurrent) order(concurrent)
+ for (i = 0; i < 128; i++)
+ a[i]++;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/order-2.c b/gcc/testsuite/c-c++-common/gomp/order-2.c
new file mode 100644
index 0000000..1a9adb0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/order-2.c
@@ -0,0 +1,57 @@
+void
+f1 (int *a)
+{
+ int i;
+ #pragma omp for order /* { dg-error "expected" } */
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp for simd order : /* { dg-error "expected" } */
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp simd order ( foobar ) /* { dg-error "expected" } */
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp for simd order( concurrent /* { dg-error "expected" } */
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp for simd order( concurrent : foo )/* { dg-error "expected" } */
+ for (i = 0; i < 128; i++)
+ a[i]++;
+}
+
+void
+f2 (int *a)
+{
+ int i;
+ #pragma omp teams
+ #pragma omp distribute order(concurrent) /* { dg-error "'order' is not valid for '#pragma omp distribute'" } */
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp taskloop order (concurrent) /* { dg-error "'order' is not valid for '#pragma omp taskloop'" } */
+ for (i = 0; i < 128; i++)
+ a[i]++;
+ #pragma omp for order(concurrent) ordered /* { dg-error "'order' clause must not be used together with 'ordered'" } */
+ for (i = 0; i < 128; i++)
+ {
+ #pragma omp ordered
+ a[i]++;
+ }
+ #pragma omp for ordered order(concurrent) /* { dg-error "'order' clause must not be used together with 'ordered'" } */
+ for (i = 0; i < 128; i++)
+ {
+ #pragma omp ordered
+ a[i]++;
+ }
+ #pragma omp for ordered (1) order(concurrent) /* { dg-error "'order' clause must not be used together with 'ordered'" } */
+ for (i = 0; i < 128; i++)
+ {
+ #pragma omp ordered depend (sink: i - 1)
+ #pragma omp ordered depend (source)
+ }
+ #pragma omp for order(concurrent)ordered (1) /* { dg-error "'order' clause must not be used together with 'ordered'" } */
+ for (i = 0; i < 128; i++)
+ {
+ #pragma omp ordered depend (sink: i - 1)
+ #pragma omp ordered depend (source)
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/order-3.c b/gcc/testsuite/c-c++-common/gomp/order-3.c
new file mode 100644
index 0000000..2d51bf3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/order-3.c
@@ -0,0 +1,212 @@
+void foo (void);
+int v;
+#ifdef __cplusplus
+extern "C" {
+#endif
+int omp_get_thread_num (void);
+int omp_get_num_threads (void);
+int omp_target_is_present (const void *, int);
+int omp_get_cancellation (void);
+#ifdef __cplusplus
+}
+#endif
+
+void
+f1 (int *a)
+{
+ int i;
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp parallel /* { dg-error "OpenMP constructs other than 'ordered simd', 'simd', 'loop' or 'atomic' may not be nested inside 'simd' region" } */
+ foo ();
+ }
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp simd
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp critical /* { dg-error "OpenMP constructs other than 'ordered simd', 'simd', 'loop' or 'atomic' may not be nested inside 'simd' region" } */
+ foo ();
+ }
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp ordered simd /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ foo ();
+ }
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ v++;
+ }
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic read
+ a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ }
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic write /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */
+ v = a[i]; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */
+ }
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_thread_num (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_thread_num\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_num_threads (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_num_threads\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_target_is_present (a + i, 0); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_target_is_present\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_cancellation (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_cancellation\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+}
+
+void
+f2 (int *a)
+{
+ int i;
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp parallel /* { dg-error "OpenMP constructs other than 'ordered simd', 'simd', 'loop' or 'atomic' may not be nested inside 'simd' region" } */
+ foo ();
+ }
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp simd
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp critical /* { dg-error "OpenMP constructs other than 'ordered simd', 'simd', 'loop' or 'atomic' may not be nested inside 'simd' region" } */
+ foo ();
+ }
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp ordered simd /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ foo ();
+ }
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ v++;
+ }
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic read
+ a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ }
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic write /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */
+ v = a[i]; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */
+ }
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_thread_num (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_thread_num\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_num_threads (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_num_threads\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_target_is_present (a + i, 0); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_target_is_present\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp for simd order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_cancellation (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_cancellation\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+}
+
+void
+f3 (int *a)
+{
+ int i;
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp parallel
+ foo ();
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp simd
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp critical /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ foo ();
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp ordered simd /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ foo ();
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ v++;
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic read
+ a[i] = v; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp atomic write /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c++ } } */
+ v = a[i]; /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" "" { target c } } */
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ #pragma omp task /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ a[i]++;
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ {
+ int j;
+ #pragma omp taskloop /* { dg-error "OpenMP constructs other than 'parallel', 'loop' or 'simd' may not be nested inside a region with the 'order\\(concurrent\\)' clause" } */
+ for (j = 0; j < 64; j++)
+ a[64 * i + j] = i + j;
+ }
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_thread_num (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_thread_num\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_num_threads (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_num_threads\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_target_is_present (a + i, 0); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_target_is_present\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+ #pragma omp for order(concurrent)
+ for (i = 0; i < 64; i++)
+ a[i] += omp_get_cancellation (); /* { dg-error "OpenMP runtime API call '\[^\n\r]*omp_get_cancellation\[^\n\r]*' in a region with 'order\\(concurrent\\)' clause" } */
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/order-4.c b/gcc/testsuite/c-c++-common/gomp/order-4.c
new file mode 100644
index 0000000..f916772
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/order-4.c
@@ -0,0 +1,29 @@
+int t;
+#pragma omp threadprivate(t)
+
+void
+f1 (void)
+{
+ int i;
+ #pragma omp simd order(concurrent) /* { dg-error "enclosing region" } */
+ for (i = 0; i < 64; i++)
+ t++; /* { dg-error "threadprivate variable 't' used in a region with 'order\\(concurrent\\)' clause" } */
+}
+
+void
+f2 (void)
+{
+ int i;
+ #pragma omp for simd order(concurrent) /* { dg-error "enclosing region" } */
+ for (i = 0; i < 64; i++) /* { dg-error "enclosing region" "" { target c++ } } */
+ t++; /* { dg-error "threadprivate variable 't' used in a region with 'order\\(concurrent\\)' clause" } */
+}
+
+void
+f3 (void)
+{
+ int i;
+ #pragma omp for order(concurrent) /* { dg-error "enclosing region" } */
+ for (i = 0; i < 64; i++)
+ t++; /* { dg-error "threadprivate variable 't' used in a region with 'order\\(concurrent\\)' clause" } */
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/reduction-task-3.c b/gcc/testsuite/c-c++-common/gomp/reduction-task-3.c
new file mode 100644
index 0000000..bde2ccb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/reduction-task-3.c
@@ -0,0 +1,12 @@
+/* PR c/91149 */
+
+int r;
+
+void
+foo (void)
+{
+ #pragma omp parallel reduction(task, +: r)
+ r++;
+ #pragma omp target parallel reduction(task, +: r)
+ r++;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/scan-4.c b/gcc/testsuite/c-c++-common/gomp/scan-4.c
index 32d4006..b2e22e8 100644
--- a/gcc/testsuite/c-c++-common/gomp/scan-4.c
+++ b/gcc/testsuite/c-c++-common/gomp/scan-4.c
@@ -8,7 +8,7 @@ f1 (int *c, int *d)
for (i = 0; i < 64; i++)
{
d[i] = a;
- #pragma omp scan exclusive (a) /* { dg-message "sorry, unimplemented: '#pragma omp scan' not supported yet" } */
+ #pragma omp scan exclusive (a)
a += c[i];
}
}
diff --git a/gcc/testsuite/c-c++-common/gomp/simd-setjmp-1.c b/gcc/testsuite/c-c++-common/gomp/simd-setjmp-1.c
new file mode 100644
index 0000000..453e001
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/simd-setjmp-1.c
@@ -0,0 +1,68 @@
+typedef long int jmp_buf[8];
+extern
+#ifdef __cplusplus
+"C"
+#endif
+int setjmp (jmp_buf);
+
+void
+foo (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < 64; i++)
+ {
+ jmp_buf buf;
+ setjmp (buf); /* { dg-error "setjmp/longjmp inside 'simd' construct" } */
+ }
+}
+
+void
+bar (void)
+{
+ int i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ {
+ jmp_buf buf;
+ setjmp (buf);
+ }
+}
+
+#ifdef __cplusplus
+struct S
+{
+ static int setjmp (jmp_buf);
+};
+
+namespace N
+{
+ int setjmp (jmp_buf);
+}
+
+void
+baz (void)
+{
+ int i;
+ #pragma omp simd
+ for (i = 0; i < 64; i++)
+ {
+ jmp_buf buf;
+ S::setjmp (buf);
+ N::setjmp (buf);
+ }
+}
+
+void
+qux (void)
+{
+ int i;
+ #pragma omp loop bind(thread)
+ for (i = 0; i < 64; i++)
+ {
+ jmp_buf buf;
+ S::setjmp (buf);
+ N::setjmp (buf);
+ }
+}
+#endif
diff --git a/gcc/testsuite/c-c++-common/gomp/teams-2.c b/gcc/testsuite/c-c++-common/gomp/teams-2.c
index 011c284..85a5be7 100644
--- a/gcc/testsuite/c-c++-common/gomp/teams-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/teams-2.c
@@ -10,7 +10,7 @@ foo (void)
}
#pragma omp teams
{
- #pragma omp teams /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp teams /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
}
#pragma omp target
@@ -72,48 +72,48 @@ bar (void)
#pragma omp teams
{
int x, y, v = 4;
- #pragma omp target /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp target /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp target data map (to: v) /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp target data map (to: v) /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp for /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp for /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
for (int i = 0; i < 64; ++i)
;
- #pragma omp simd /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp simd /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
for (int i = 0; i < 64; ++i)
;
- #pragma omp for simd /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp for simd /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
for (int i = 0; i < 64; ++i)
;
- #pragma omp single /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp single /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp master /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp master /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp sections /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp sections /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
{
x = 1;
#pragma omp section
y = 2;
}
- #pragma omp critical /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp critical /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp target enter data map (to: v) /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
- #pragma omp target exit data map (from: v) /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
- #pragma omp cancel parallel /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
- #pragma omp cancellation point parallel /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
- #pragma omp barrier /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
- #pragma omp ordered /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp target enter data map (to: v) /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp target exit data map (from: v) /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp cancel parallel /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp cancellation point parallel /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp barrier /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp ordered /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp task /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp task /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp taskloop /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp taskloop /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
for (int i = 0; i < 64; ++i)
;
- #pragma omp atomic /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp atomic /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
v++;
- #pragma omp taskgroup /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp taskgroup /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
;
- #pragma omp taskwait /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
- #pragma omp taskyield /* { dg-error "only 'distribute' or 'parallel' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp taskwait /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
+ #pragma omp taskyield /* { dg-error "only 'distribute', 'parallel' or 'loop' regions are allowed to be strictly nested inside 'teams' region" } */
}
}
diff --git a/gcc/testsuite/c-c++-common/pr53633-2.c b/gcc/testsuite/c-c++-common/pr53633-2.c
new file mode 100644
index 0000000..c26cb10
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr53633-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target naked_functions } */
+/* { dg-options "-O2 -Wall" } */
+/* Check that we do not get warnings about missing return statements
+ or bogus looking noreturn functions. */
+static int __attribute__((naked))
+foo (void)
+{
+ __asm__ ("");
+}
+
+static int __attribute__((naked,noreturn))
+bar (void)
+{
+ __asm__ ("");
+}
+
+int foo_caller (void) { return foo (); }
+int bar_caller (void) { return bar (); }
diff --git a/gcc/testsuite/g++.dg/Wmissing-attributes-1.C b/gcc/testsuite/g++.dg/Wmissing-attributes-1.C
new file mode 100644
index 0000000..972e683
--- /dev/null
+++ b/gcc/testsuite/g++.dg/Wmissing-attributes-1.C
@@ -0,0 +1,66 @@
+// { dg-do compile }
+// { dg-options "-Wmissing-attributes" }
+
+#define ATTR(list) __attribute__ (list)
+
+/* Type attributes are normally absent in template functions, and the
+ mere presence of any such attribute used to cause the
+ -Wmissing-attributes checks, that checked for attributes typically
+ associated with functions rather than types, to report any missing
+ attributes twice: once for the specialization attribute list, once
+ for its type attribute list.
+
+ This test uses both decl and type attributes to exercise the code
+ that avoids reporting duplicates, in ways that failed in the past
+ but that were not covered in other tests. */
+typedef void* ATTR ((alloc_size (1))) f_type (int);
+
+template <class T>
+f_type
+ATTR ((malloc))
+missing_malloc; // { dg-message "missing primary template attribute .malloc." }
+
+template <>
+f_type
+missing_malloc<char>; // { dg-warning "explicit specialization .\[^\n\r\]+. may be missing attributes" }
+
+
+/* Check that even an attribute that appears in both lists (decl and
+ type) in a template declaration is reported as missing only
+ once. */
+
+template <class T>
+f_type
+ATTR ((alloc_size (1))) // In both attr lists, decl's and type's.
+missing_alloc_size; // { dg-message "missing primary template attribute .alloc_size." }
+
+template <>
+void *
+missing_alloc_size<char>(int); // { dg-warning "explicit specialization .\[^\n\r\]+. may be missing attributes" }
+
+
+/* Check that even an attribute that appears in both lists (decl and
+ type) is not reported as missing if it's present only in the type
+ list. */
+
+template <class T>
+f_type
+ATTR ((alloc_size (1))) // In both attr lists, decl's and type's.
+missing_nothing;
+
+template <>
+f_type
+missing_nothing<char>;
+
+
+/* For completeness, check that a type attribute is matched by a decl
+ attribute in the specialization. */
+
+template <class T>
+f_type
+missing_nothing2;
+
+template <>
+void *
+ATTR ((alloc_size (1)))
+missing_nothing2<char>(int);
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype72.C b/gcc/testsuite/g++.dg/cpp0x/decltype72.C
new file mode 100644
index 0000000..071e0e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype72.C
@@ -0,0 +1,19 @@
+// PR c++/67853
+// { dg-do compile { target c++11 } }
+
+template<typename T, typename U>
+struct is_same
+{
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T>
+{
+ static const bool value = true;
+};
+
+struct Member {};
+struct A { Member x; };
+A MakeA();
+static_assert(is_same<decltype((MakeA().x)), Member&&>::value, "");
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-list6.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list6.C
new file mode 100644
index 0000000..83ab2e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list6.C
@@ -0,0 +1,28 @@
+// PR c++/90455
+// { dg-do compile { target c++11 } }
+
+struct B;
+template <typename a> struct b {
+ void operator()(a *) { sizeof(a); }
+};
+struct c {
+ struct D {
+ using d = B *;
+ };
+
+ using e = D::d;
+ e f();
+};
+template <typename> class g {
+ c h;
+ using i = b<B>;
+public:
+ ~g() {
+ auto j = h.f();
+ k()(j);
+ }
+ i k();
+};
+struct l {
+ g<int> m{};
+};
diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction67.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction67.C
new file mode 100644
index 0000000..4624794
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction67.C
@@ -0,0 +1,21 @@
+// Deduction from inherited constructors isn't supported yet, but we shouldn't
+// crash. It may well be supported in C++23.
+
+//{ dg-do compile { target c++17 } }
+
+template <class T> struct A
+{
+ A(T);
+};
+
+template <class T> struct B: A<T>
+{
+ using A<T>::A;
+};
+
+int main()
+{
+ B b = 42; // { dg-line init }
+ // { dg-prune-output "no matching function" }
+ // { dg-error "class template argument deduction" "" { target *-*-* } init }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C
index c4ae555..f1f3388 100644
--- a/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C
+++ b/gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C
@@ -1,7 +1,7 @@
struct S;
struct T { S t; }; // { dg-error "incomplete type" }
struct U { int u[sizeof (S)]; }; // { dg-error "incomplete type" }
-union V { char c; char d[]; }; // { dg-error "flexible array member in union" }
+union V { char c; char d[]; }; // { dg-error "24:flexible array member in union" }
bool a = __has_unique_object_representations (S); // { dg-error "incomplete type" }
bool b = __has_unique_object_representations (T);
bool c = __has_unique_object_representations (U);
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class18.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class18.C
new file mode 100644
index 0000000..22f4788
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class18.C
@@ -0,0 +1,17 @@
+// PR c++/90101
+// { dg-do compile { target c++2a } }
+
+template<typename List>
+struct A;
+
+template<template<auto...> typename List>
+struct A<List<>> {};
+
+template<template<auto...> typename List, auto V>
+struct A<List<V>> {};
+
+template<auto>
+struct B {};
+
+struct X { int value; };
+A<B<X{1}>> a2;
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class19.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class19.C
new file mode 100644
index 0000000..91267ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class19.C
@@ -0,0 +1,13 @@
+// PR c++/90099
+// { dg-do compile { target c++2a } }
+
+struct Unit {
+ int value;
+ // auto operator<=>(const Unit&) = default;
+};
+
+template<Unit U, typename... Ts>
+struct X {};
+
+template<Unit U, typename T, typename... Rest>
+struct X<U, T, Rest...> {};
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class20.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class20.C
new file mode 100644
index 0000000..5d3479c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class20.C
@@ -0,0 +1,13 @@
+// PR c++/90098
+// { dg-do compile { target c++2a } }
+
+struct A {
+ int value;
+ // auto operator<=>(const A&) = default;
+};
+
+template<A... Us>
+struct Z {};
+
+template<A V, A... Rest>
+struct Z<V, Rest...> {};
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class21.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class21.C
new file mode 100644
index 0000000..c58fe05
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class21.C
@@ -0,0 +1,10 @@
+// PR c++/90101
+// { dg-do compile { target c++2a } }
+
+template<int N>
+struct A{};
+
+template<int N, A<N>>
+struct B {};
+
+B<2,A<2>{}> b;
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class22.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class22.C
new file mode 100644
index 0000000..026855f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class22.C
@@ -0,0 +1,21 @@
+// PR c++/90100
+// { dg-do compile { target c++2a } }
+
+template<typename T>
+inline constexpr bool is_nontype_list = false;
+
+template<template<auto...> typename T, auto... NonTypes>
+inline constexpr bool is_nontype_list<T<NonTypes...>> = true;
+
+// works
+template<auto...>
+struct A {};
+
+static_assert(is_nontype_list<A<1, 2, 3>>);
+
+// fails
+struct X {
+ int v;
+};
+
+static_assert(is_nontype_list<A<X{1}, X{2}, X{3}>>);
diff --git a/gcc/testsuite/g++.dg/diagnostic/complex-invalid-1.C b/gcc/testsuite/g++.dg/diagnostic/complex-invalid-1.C
new file mode 100644
index 0000000..5a61765
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/complex-invalid-1.C
@@ -0,0 +1 @@
+__complex__ bool b; // { dg-error "1:complex invalid" }
diff --git a/gcc/testsuite/g++.dg/diagnostic/static-cdtor-1.C b/gcc/testsuite/g++.dg/diagnostic/static-cdtor-1.C
new file mode 100644
index 0000000..ae3fd56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/static-cdtor-1.C
@@ -0,0 +1,5 @@
+struct S
+{
+ static S(); // { dg-error "3:constructor" }
+ static ~S(); // { dg-error "3:destructor" }
+};
diff --git a/gcc/testsuite/g++.dg/ext/is_std_layout3.C b/gcc/testsuite/g++.dg/ext/is_std_layout3.C
new file mode 100644
index 0000000..b0555c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_std_layout3.C
@@ -0,0 +1,18 @@
+// DR 1813
+// PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
+// { dg-do compile { target c++11 } }
+
+struct B { int i; }; // standard-layout class
+struct C : B { }; // standard-layout class
+struct D : C { }; // standard-layout class
+struct E : D { char : 4; }; // not a standard-layout class
+static_assert( __is_standard_layout(B), "" );
+static_assert( __is_standard_layout(C), "" );
+static_assert( __is_standard_layout(D), "" );
+static_assert( ! __is_standard_layout(E), "" );
+
+struct Q {};
+struct S : Q { };
+struct T : Q { };
+struct U : S, T { }; // not a standard-layout class
+static_assert( ! __is_standard_layout(U), "" );
diff --git a/gcc/testsuite/g++.dg/ext/is_std_layout4.C b/gcc/testsuite/g++.dg/ext/is_std_layout4.C
new file mode 100644
index 0000000..09c0098
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_std_layout4.C
@@ -0,0 +1,11 @@
+// DR 1813
+// PR c++/83374 - __is_standard_layout wrong for a class with repeated bases.
+// { dg-do compile { target c++11 } }
+
+struct R { };
+struct Q { };
+struct S : R { };
+struct T : Q { };
+struct U : S, T { };
+// No repeated base class subobjects.
+static_assert(__is_standard_layout(U), "");
diff --git a/gcc/testsuite/g++.dg/gomp/pr91110.C b/gcc/testsuite/g++.dg/gomp/pr91110.C
new file mode 100644
index 0000000..332c99a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr91110.C
@@ -0,0 +1,11 @@
+// PR c++/91110
+// { dg-do compile }
+
+void
+foo ()
+{
+ X b[2]; // { dg-error "'X' was not declared in this scope" }
+ b[0] = 1; // { dg-error "'b' was not declared in this scope" }
+ #pragma omp target map(to: b) // { dg-error "'b' does not have a mappable type in 'map' clause" }
+ ;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/unmappable-1.C b/gcc/testsuite/g++.dg/gomp/unmappable-1.C
new file mode 100644
index 0000000..d00ccb5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/unmappable-1.C
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+class C /* { dg-message "type .C. with virtual members is not mappable" } */
+{
+public:
+ static int static_member; /* { dg-message "static field .C::static_member. is not mappable" } */
+ virtual void f() {}
+};
+
+extern C v[];
+
+int
+main ()
+{
+#pragma omp target map(v) /* { dg-error ".v. does not have a mappable type in .map. clause" } */
+ /* { dg-message "incomplete type .C \\\[\\\]. is not mappable" "" { target *-*-* } .-1 } */
+ {
+ }
+}
diff --git a/gcc/testsuite/g++.dg/lto/alias-1_0.C b/gcc/testsuite/g++.dg/lto/alias-1_0.C
index 333bcf0..9a79bda 100644
--- a/gcc/testsuite/g++.dg/lto/alias-1_0.C
+++ b/gcc/testsuite/g++.dg/lto/alias-1_0.C
@@ -1,5 +1,5 @@
/* { dg-lto-do run } */
-/* { dg-lto-options { { -O2 -flto } } } */
+/* { dg-lto-options { { -O3 -flto } } } */
/* With LTO we consider all pointers to incomplete types to be possibly
aliasing. This makes *bptr to alias with aptr.
diff --git a/gcc/testsuite/g++.dg/lto/alias-2_0.C b/gcc/testsuite/g++.dg/lto/alias-2_0.C
index adad3ec..07b432c 100644
--- a/gcc/testsuite/g++.dg/lto/alias-2_0.C
+++ b/gcc/testsuite/g++.dg/lto/alias-2_0.C
@@ -1,5 +1,5 @@
/* { dg-lto-do run } */
-/* { dg-lto-options { { -O2 -flto } } } */
+/* { dg-lto-options { { -O3 -flto } } } */
/* With LTO we consider all pointers to incomplete types to be possibly
aliasing. This makes *bptr to alias with aptr.
diff --git a/gcc/testsuite/g++.dg/lto/alias-3_0.C b/gcc/testsuite/g++.dg/lto/alias-3_0.C
new file mode 100644
index 0000000..9ed95304
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/alias-3_0.C
@@ -0,0 +1,29 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
+
+struct a
+{
+ int foo,bar;
+};
+struct b
+{
+ struct a a[10];
+};
+
+__attribute__ ((used)) struct b b, *bptr=&b, *bptr2=&b;
+__attribute__ ((used)) int i,j;
+
+extern "C" void inline_me_late (void);
+int n=1;
+
+int
+main (void)
+{
+ int jj=j;
+ bptr2->a[jj].bar = 0;
+ for (int i=0; i<n; i++)
+ inline_me_late ();
+ if (!__builtin_constant_p (bptr2->a[jj].bar == 0))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/lto/alias-3_1.c b/gcc/testsuite/g++.dg/lto/alias-3_1.c
new file mode 100644
index 0000000..f633271
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/alias-3_1.c
@@ -0,0 +1,18 @@
+struct a
+{
+ int foo,bar;
+};
+struct b
+{
+ struct a a[10];
+};
+
+extern struct b *bptr;
+extern int i;
+
+void
+inline_me_late (void)
+{
+ bptr->a[i].foo=1;
+}
+
diff --git a/gcc/testsuite/g++.dg/lto/alias-4_0.C b/gcc/testsuite/g++.dg/lto/alias-4_0.C
new file mode 100644
index 0000000..410c314
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/alias-4_0.C
@@ -0,0 +1,31 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O3 -flto -fno-early-inlining } } } */
+__attribute__ ((used))
+short *ptr_init, **ptr=&ptr_init;
+
+__attribute__ ((used))
+struct a {
+ int *aptr;
+} a, *aptr=&a;
+
+void
+write_ptr ()
+{
+ *aptr = a;
+}
+
+__attribute__ ((used))
+void
+test ()
+{
+ *ptr = (short int *)0;
+ write_ptr ();
+ if (!__builtin_constant_p (*ptr == (void *)0))
+ __builtin_abort ();
+}
+int
+main()
+{
+ test ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/lto/alias-5_0.C b/gcc/testsuite/g++.dg/lto/alias-5_0.C
new file mode 100644
index 0000000..779cc39
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/alias-5_0.C
@@ -0,0 +1,35 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O3 -flto } } } */
+/* This testcase tests that anonymous namespaces in different TUs are treated
+ as different types by LTO TBAA and that they never alias with structurally
+ same C types. */
+namespace {
+ __attribute__((used))
+ struct a {int a;} *p,**ptr=&p;
+};
+void
+set1()
+{
+ *ptr=0;
+}
+void
+get1()
+{
+ if (!__builtin_constant_p (*ptr==0))
+ __builtin_abort ();
+}
+extern void set2();
+extern "C" void set3();
+int n = 1;
+int
+main()
+{
+ for (int i = 0; i < n; i++)
+ {
+ set1();
+ set2();
+ set3();
+ get1();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/lto/alias-5_1.C b/gcc/testsuite/g++.dg/lto/alias-5_1.C
new file mode 100644
index 0000000..f12bd56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/alias-5_1.C
@@ -0,0 +1,9 @@
+namespace {
+ __attribute__((used))
+ struct a {int a;} *p,**ptr=&p,q;
+};
+void
+set2()
+{
+ *ptr=&q;
+}
diff --git a/gcc/testsuite/g++.dg/lto/alias-5_2.c b/gcc/testsuite/g++.dg/lto/alias-5_2.c
new file mode 100644
index 0000000..d126833
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/alias-5_2.c
@@ -0,0 +1,7 @@
+ __attribute__((used))
+ struct a {int a;} *p,**ptr=&p,q;
+void
+set3()
+{
+ *ptr=&q;
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr91164.C b/gcc/testsuite/g++.dg/opt/pr91164.C
new file mode 100644
index 0000000..8cf4fd0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr91164.C
@@ -0,0 +1,89 @@
+// PR rtl-optimization/91164
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fdelete-dead-exceptions -fnon-call-exceptions -fno-rerun-cse-after-loop -fno-tree-forwprop" }
+
+template <typename, typename = int> class b;
+template <int v> struct d { static constexpr int e = v; };
+template <bool, typename f> using g = f;
+struct h { template <typename i> using j = i; };
+template <typename, typename f> using k = h::j<f>;
+void *operator new(__SIZE_TYPE__, void *);
+struct l { l(); };
+struct m;
+template <typename n> n aa(m);
+struct o { template <typename> using ab = l; };
+template <typename, typename> struct b {
+ struct q : o::ab<int> { q(int, l = l()) : p() {} int p; } ac;
+ void ad();
+ b() : ac(0) {}
+ ~b() { bool r = ac.p == 0; if (r) ad(); }
+ const wchar_t *ae();
+};
+struct m {};
+struct t { virtual void f(); };
+struct u { l a; };
+struct af : t {
+ struct ag { ag(l); };
+ af(l ah) : ai(ah) {}
+ ag ai;
+};
+struct w {
+ template <typename f, typename x> w(f, x y) { new (0) af(y.a); }
+};
+struct z {
+ using aj = int;
+ template <typename x> z(x ah) : ak(al, ah) {}
+ aj al;
+ w ak;
+};
+struct am : z { template <typename x> am(x ah) : z(ah) {} };
+template <typename, typename x> am an(x) { return u{}; }
+template <typename> am ao() { return an<int>(l()); }
+struct ap {
+ k<int, int> aq;
+ k<int, int> ar;
+ k<int, int> as;
+};
+struct at { ap a; long au; ap av; ap aw; };
+struct ax { at c; ax() : c() {} };
+enum ay : int;
+ay az, ba;
+struct bb { bb(wchar_t *, wchar_t *, ay, m); };
+template <typename bc> struct bd {
+ typedef typename bc::be *bf;
+ bd(bf, bf, const typename bc::bg &, ay);
+ ay bh;
+ bb bi;
+ am bj;
+ typename bc::bk e;
+ ax bl;
+ int bm;
+};
+template <typename, typename> using bn = g<d<false>::e, am>;
+template <typename bc>
+bd<bc>::bd(bf ah, bf y, const typename bc::bg &bu, ay)
+ : bi(ah, y, bh, bu), bj(ao<bc>()), bm(aa<int>(bu)) {}
+struct bt { typedef wchar_t be; typedef b<be> bk; typedef m bg; };
+template <typename bc, typename bo> bn<bo, bc> bar();
+template <typename bc, typename bo> bn<bo, bc> bq(bo) {
+ typename bc::bg bp;
+ auto bs = nullptr;
+ using br = bd<bc>;
+ br(bs, bs, bp, ba);
+ return bar<bc, bo>();
+}
+struct bw {
+ bw();
+ template <typename bv, typename x> void assign(b<bv, x> ah) {
+ const wchar_t by = *ah.ae();
+ bw(&by, ah.ae(), bp, az);
+ }
+ template <typename bo> bw(bo, bo y, m, ay) : automaton(bq<bt>(y)) {}
+ m bp;
+ am automaton;
+};
+void bx() {
+ b<wchar_t> s;
+ bw ca;
+ ca.assign(s);
+}
diff --git a/gcc/testsuite/g++.dg/other/anon-union3.C b/gcc/testsuite/g++.dg/other/anon-union3.C
index ca59d02..6f2946b 100644
--- a/gcc/testsuite/g++.dg/other/anon-union3.C
+++ b/gcc/testsuite/g++.dg/other/anon-union3.C
@@ -3,9 +3,9 @@
class C
{
auto union // { dg-error "storage class" "" { target { ! c++11 } } }
- { // { dg-error "auto" "" { target c++11 } .-1 }
+ { // { dg-error "auto|multiple types" "" { target c++11 } .-1 }
int a;
- }; // { dg-error "multiple types" "" { target c++11 } }
+ };
register union // { dg-error "storage class" }
{
int b;
diff --git a/gcc/testsuite/g++.dg/other/final4.C b/gcc/testsuite/g++.dg/other/final4.C
new file mode 100644
index 0000000..867ef38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/final4.C
@@ -0,0 +1,16 @@
+// PR c++/67184
+// { dg-do compile { target c++11 } }
+// { dg-options "-fdump-tree-original" }
+
+struct B
+{
+ virtual void operator()();
+ virtual operator int();
+ virtual int operator++();
+};
+
+struct D final : B { };
+
+void foo(D& d) { d(); int t = d; ++d; }
+
+// { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "original" } }
diff --git a/gcc/testsuite/g++.dg/parse/error8.C b/gcc/testsuite/g++.dg/parse/error8.C
index 61e42e0..135f078 100644
--- a/gcc/testsuite/g++.dg/parse/error8.C
+++ b/gcc/testsuite/g++.dg/parse/error8.C
@@ -5,5 +5,5 @@ struct A { friend typename struct B; };
// { dg-error "28:expected nested-name-specifier before 'struct'" "expected" { target *-*-* } 4 }
-// { dg-error "35:multiple types in one declaration" "multiple" { target *-*-* } 4 }
+// { dg-error "19:multiple types in one declaration" "multiple" { target *-*-* } 4 }
// { dg-error "12:friend declaration does not name a class or function" "friend decl" { target *-*-* } 4 }
diff --git a/gcc/testsuite/g++.dg/pr91173.C b/gcc/testsuite/g++.dg/pr91173.C
new file mode 100644
index 0000000..b8fb41b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr91173.C
@@ -0,0 +1,45 @@
+class a {
+ int b;
+ void *c;
+
+public:
+ bool aa();
+ int &ab() {
+ if (aa()) {
+ void *d(c);
+ return static_cast<int *>(d)[b];
+ }
+ return *(int *)0;
+ }
+};
+typedef enum {E} e;
+class f : public a {
+ int g;
+
+public:
+ int ac() {
+ if (g)
+ return 1;
+ return ac();
+ }
+};
+int *ad;
+struct h {
+ static int ae(e, int *m) {
+ f ag;
+ int *ah;
+ while (!0) {
+ ad = &ag.ab();
+ ah = ad + ag.ac();
+ while (ad < ah)
+ *m = *ad++;
+ }
+ }
+};
+template <class, class>
+void i(int *, int *, int, int *, e n, int *o) {
+ h::ae(n, o);
+}
+int aq, ar, as, at, au;
+void aw() { i<int, bool>(&aq, &ar, as, &at, (e)0, &au); }
+
diff --git a/gcc/testsuite/g++.dg/pr91221.C b/gcc/testsuite/g++.dg/pr91221.C
new file mode 100644
index 0000000..3036f1b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr91221.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-O2 -fno-ipa-pure-const -fpack-struct -Wno-address-of-packed-member" }
+
+void printf(...);
+struct A {
+ A() : bar_(), dbar_() {
+ for (int i;; i++)
+ printf(i, bar_[i]);
+ }
+ int bar_[5];
+ double dbar_[5];
+};
+void fn1() { A a; }
diff --git a/gcc/testsuite/g++.dg/tree-ssa/final2.C b/gcc/testsuite/g++.dg/tree-ssa/final2.C
new file mode 100644
index 0000000..b0fc860
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/final2.C
@@ -0,0 +1,35 @@
+// PR c++/65143
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -fdump-tree-gimple }
+// { dg-final { scan-tree-dump-times "vptr" 1 gimple } }
+
+struct A
+{
+ int i();
+};
+
+struct B : public virtual A
+{
+ int get()
+ {
+ return A::i() + 1;
+ }
+};
+
+struct C final : public B
+{
+ int get()
+ {
+ return A::i() + 2;
+ }
+};
+
+int foo(C& c)
+{
+ return c.get(); // Need not go via vtable pointer as class C is final
+}
+
+int foo(B& b2)
+{
+ return b2.get(); // This has to go via vtable as most derived class can change the location of A
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/final3.C b/gcc/testsuite/g++.dg/tree-ssa/final3.C
new file mode 100644
index 0000000..9489fc12
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/final3.C
@@ -0,0 +1,23 @@
+// PR c++/65143
+// { dg-do compile { target c++11 } }
+// { dg-additional-options -fdump-tree-gimple }
+// { dg-final { scan-tree-dump-not "vptr" gimple } }
+
+struct A
+{
+ int j;
+};
+
+struct B : public virtual A
+{
+};
+
+struct C final : public B
+{
+ int get();
+};
+
+int C::get()
+{
+ return A::j;
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr83518.C b/gcc/testsuite/g++.dg/tree-ssa/pr83518.C
new file mode 100644
index 0000000..3e153c5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr83518.C
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+
+unsigned test()
+{
+ int arr[] = {5,4,3,2,1};
+ int sum = 0;
+
+ for(int i = 0;i < 5;++i)
+ {
+ for(int j = 0; j < 5; ++j)
+ {
+ int t = arr[i];
+ arr[i] = arr[j];
+ arr[j] = t;
+ }
+ }
+
+ for(int i = 0; i < 5; ++i)
+ {
+ sum += arr[i];
+ }
+
+ return sum;
+}
+
+/* { dg-final { scan-tree-dump "return 15;" "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/vect/simd-6.cc b/gcc/testsuite/g++.dg/vect/simd-6.cc
index 997f7b1..883b769 100644
--- a/gcc/testsuite/g++.dg/vect/simd-6.cc
+++ b/gcc/testsuite/g++.dg/vect/simd-6.cc
@@ -1,7 +1,7 @@
// { dg-require-effective-target size32plus }
// { dg-additional-options "-fopenmp-simd" }
// { dg-additional-options "-mavx" { target avx_runtime } }
-// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } }
#include "../../gcc.dg/vect/tree-vect.h"
diff --git a/gcc/testsuite/g++.dg/vect/simd-9.cc b/gcc/testsuite/g++.dg/vect/simd-9.cc
index bfef445..4c5b050 100644
--- a/gcc/testsuite/g++.dg/vect/simd-9.cc
+++ b/gcc/testsuite/g++.dg/vect/simd-9.cc
@@ -1,7 +1,7 @@
// { dg-require-effective-target size32plus }
// { dg-additional-options "-fopenmp-simd" }
// { dg-additional-options "-mavx" { target avx_runtime } }
-// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { xfail *-*-* } } }
+// { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } }
#include "../../gcc.dg/vect/tree-vect.h"
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr91190.c b/gcc/testsuite/gcc.c-torture/compile/pr91190.c
new file mode 100644
index 0000000..10b792f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr91190.c
@@ -0,0 +1,31 @@
+/* PR middle-end/91190 */
+
+unsigned a[1], c;
+long d, h;
+int e[2], f, g;
+char i;
+
+int
+main ()
+{
+ char k = 0;
+ int l;
+ while (i || d)
+ {
+ if (g)
+ while (1)
+ ;
+ e[1] = 0;
+ long m[2], n = ~(3 & (5 | (h | 9) * 2237420170));
+ g = 90 * n;
+ char b = m[300000000], j = 0;
+ c = 5 ^ a[c ^ (b & 5)];
+ int o = d;
+ k = o ? : j;
+ if (k)
+ for (l = 0; l < 3; l++)
+ if (m[200000000000000000])
+ __builtin_printf ("%d", f);
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr91204.c b/gcc/testsuite/gcc.c-torture/compile/pr91204.c
new file mode 100644
index 0000000..dc26732
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr91204.c
@@ -0,0 +1,11 @@
+/* PR target/91204 */
+
+int a, b, c[64];
+
+void
+foo (void)
+{
+ int i;
+ for (i = 2; i < 64; i++)
+ c[i] &= b ^ c[i] ^ c[i - 2];
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp b/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp
index fb9d3ec..d62f78c 100644
--- a/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp
+++ b/gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp
@@ -37,7 +37,7 @@ load_lib c-torture.exp
torture-init
set-torture-options $C_TORTURE_OPTIONS {{}} $LTO_TORTURE_OPTIONS
-set additional_flags "-fno-tree-dse -fno-tree-loop-distribute-patterns -fno-tracer"
+set additional_flags "-fno-tree-dse -fno-tree-loop-distribute-patterns -fno-tracer -fno-ipa-ra"
if [istarget "powerpc-*-darwin*"] {
lappend additional_flags "-Wl,-multiply_defined,suppress"
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr91137.c b/gcc/testsuite/gcc.c-torture/execute/pr91137.c
new file mode 100644
index 0000000..aa6bb6c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr91137.c
@@ -0,0 +1,34 @@
+long long a;
+unsigned b;
+int c[70];
+int d[70][70];
+int e;
+
+__attribute__ ((noinline)) void f(long long *g, int p2) {
+ *g = p2;
+}
+
+__attribute__ ((noinline)) void fn2() {
+ for (int j = 0; j < 70; j++) {
+ for (int i = 0; i < 70; i++) {
+ if (b)
+ c[i] = 0;
+ for (int l = 0; l < 70; l++)
+ d[i][1] = d[l][i];
+ }
+ for (int k = 0; k < 70; k++)
+ e = c[0];
+ }
+}
+
+int main() {
+ b = 5;
+ for (int j = 0; j < 70; ++j)
+ c[j] = 2075593088;
+ fn2();
+ f(&a, e);
+ if (a)
+ __builtin_abort();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/return-addr.c b/gcc/testsuite/gcc.c-torture/execute/return-addr.c
new file mode 100644
index 0000000..7981818
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/return-addr.c
@@ -0,0 +1,122 @@
+/* Test to verify that a function that returns either the address
+ of a local variable or a non-local via a MAX_EXPR or MIN_EXPR
+ doesn't return null when the result of the expression is
+ the latter. */
+
+#define NOIPA __attribute__ ((noclone, noinline, noipa))
+
+#define A(expr) \
+ ((expr) \
+ ? (void)0 \
+ : (__builtin_printf ("assertion failed on line %i: %s\n", \
+ __LINE__, #expr), \
+ __builtin_abort ()))
+
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+/* Return a bigger value than P. The address still points (just
+ past) the local variable pointed to by P so the caller does
+ return the address of a local variable but that's hidden from
+ GCC by the attribute and the point of the test is to verify
+ that the address in the return statement in the caller isn't
+ replaced by null when GCC cannot prove the address doesn't
+ reference a non-local variable. */
+
+NOIPA char* get_max_2 (char *p)
+{
+ return p + 1;
+}
+
+NOIPA char* get_max_3 (char *p, char *q)
+{
+ return p < q ? q + 1 : p + 1;
+}
+
+/* Analogous to the above. The expressions are undefined because
+ they form an address prior to the beginning of the object but
+ it's hidden from GCC by the attributes. */
+
+NOIPA char* get_min_2 (char *p)
+{
+ return p - 1;
+}
+
+NOIPA char* get_min_3 (char *p, char *q)
+{
+ return p < q ? p - 1 : q - 1;
+}
+
+
+NOIPA void* test_max_2 (void)
+{
+ char c;
+
+ char *p = get_max_2 (&c);
+
+ void *q = p > &c ? p : &c; /* MAX_EXPR */
+ return q;
+}
+
+NOIPA void* test_max_3 (void)
+{
+ char c;
+ char d;
+
+ char *p = get_max_3 (&c, &d);
+
+ void *q = p < &c ? &c < &d ? &d : &c : p;
+ return q;
+}
+
+NOIPA void* test_min_2 (void)
+{
+ char c;
+
+ char *p = get_min_2 (&c);
+
+ void *q = p < &c ? p : &c; /* MIN_EXPR" */
+ return q;
+}
+
+NOIPA void* test_min_3 (void)
+{
+ char c;
+ char d;
+
+ char *p = get_min_3 (&c, &d);
+
+ void *q = p > &c ? &c > &d ? &d : &c : p;
+ return q;
+}
+
+NOIPA void* test_min_3_phi (int i)
+{
+ char a, b;
+
+ char *p0 = &a;
+ char *p1 = &b;
+ char *p2 = get_min_3 (&a, &b);
+ char *p3 = get_min_3 (&a, &b);
+
+ char *p4 = p2 < p0 ? p2 : p0;
+ char *p5 = p3 < p1 ? p3 : p1;
+
+ __builtin_printf ("%p %p %p %p\n", p2, p3, p4, p5);
+
+ if (i == 1)
+ return p4;
+ else
+ return p5;
+}
+
+int main ()
+{
+ A (0 != test_max_2 ());
+ A (0 != test_max_3 ());
+
+ A (0 != test_min_2 ());
+ A (0 != test_min_3 ());
+
+ A (0 != test_min_3_phi (0));
+}
diff --git a/gcc/testsuite/gcc.dg/Walloca-4.c b/gcc/testsuite/gcc.dg/Walloca-4.c
index 85dcb7b..1fbed59 100644
--- a/gcc/testsuite/gcc.dg/Walloca-4.c
+++ b/gcc/testsuite/gcc.dg/Walloca-4.c
@@ -7,11 +7,12 @@
{
char *src;
- _Bool
- use_alloca = (((rear_ptr - w) * sizeof (char)) < 4096U);
- if (use_alloca)
+ _Bool use_alloca = (((rear_ptr - w) * sizeof (char)) < 4096U);
+ if (use_alloca)
src = (char *) __builtin_alloca ((rear_ptr - w) * sizeof (char));
else
src = (char *) __builtin_malloc ((rear_ptr - w) * sizeof (char));
return src;
}
+
+/* { dg-prune-output "-Wreturn-local-addr" } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
new file mode 100644
index 0000000..8892921
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
@@ -0,0 +1,133 @@
+/* Test to verify that --param ssa_name_def_chain_limit can be used to
+ limit the maximum number of SSA_NAME assignments the warning follows.
+ { dg-do compile }
+ { dg-options "-O2 -Wall --param ssa-name-def-chain-limit=4" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+const char a0[] = "";
+const char a1[] = "1";
+const char a2[] = "12";
+const char a3[] = "123";
+const char a4[] = "1234";
+const char a5[] = "12345";
+const char a6[] = "123456";
+const char a7[] = "1234567";
+const char a8[] = "12345678";
+const char a9[] = "123456789";
+
+void f (const char*, ...);
+
+int i0, i1, i2, i3, i4, i5, i6, i7, i8;
+
+NOIPA int g2 (int i)
+{
+ if (i < 1) i = 1;
+
+ const char *p0 = a9;
+ const char *p1 = p0 + i;
+ const char *p2 = p1 + i;
+
+ f (p0, p1, p2);
+
+ return p2[8]; // { dg-warning "\\\[-Warray-bounds]" }
+}
+
+NOIPA int g3 (int i)
+{
+ if (i < 1) i = 1;
+
+ const char *p0 = a9;
+ const char *p1 = p0 + i;
+ const char *p2 = p1 + i;
+ const char *p3 = p2 + i;
+
+ f (p0, p1, p2, p3);
+
+ return p3[7]; // { dg-warning "\\\[-Warray-bounds]" }
+}
+
+NOIPA int g4 (int i)
+{
+ if (i < 1) i = 1;
+
+ const char *p0 = a9;
+ const char *p1 = p0 + i;
+ const char *p2 = p1 + i;
+ const char *p3 = p2 + i;
+ const char *p4 = p3 + i;
+
+ f (p0, p1, p2, p3, p4);
+
+ return p4[6]; // { dg-warning "\\\[-Warray-bounds]" }
+}
+
+NOIPA int g5 (int i)
+{
+ if (i < 1) i = 1;
+
+ const char *p0 = a9;
+ const char *p1 = p0 + i;
+ const char *p2 = p1 + i;
+ const char *p3 = p2 + i;
+ const char *p4 = p3 + i;
+ const char *p5 = p4 + i;
+
+ f (p0, p1, p2, p3, p4, p5);
+
+ return p5[5];
+}
+
+NOIPA int g6 (int i)
+{
+ if (i < 1) i = 1;
+
+ const char *p0 = a9;
+ const char *p1 = p0 + i;
+ const char *p2 = p1 + i;
+ const char *p3 = p2 + i;
+ const char *p4 = p3 + i;
+ const char *p5 = p4 + i;
+ const char *p6 = p5 + i;
+
+ f (p0, p1, p2, p3, p4, p5, p6);
+
+ return p6[4];
+}
+
+NOIPA int g7 (int i)
+{
+ if (i < 1) i = 1;
+
+ const char *p0 = a9;
+ const char *p1 = p0 + i;
+ const char *p2 = p1 + i;
+ const char *p3 = p2 + i;
+ const char *p4 = p3 + i;
+ const char *p5 = p4 + i;
+ const char *p6 = p5 + i;
+ const char *p7 = p6 + i;
+
+ f (p0, p1, p2, p3, p4, p5, p6, p7);
+
+ return p7[3];
+}
+
+NOIPA int g8 (int i)
+{
+ if (i < 1) i = 1;
+
+ const char *p0 = a9;
+ const char *p1 = p0 + i;
+ const char *p2 = p1 + i;
+ const char *p3 = p2 + i;
+ const char *p4 = p3 + i;
+ const char *p5 = p4 + i;
+ const char *p6 = p5 + i;
+ const char *p7 = p6 + i;
+ const char *p8 = p7 + i;
+
+ f (p0, p1, p2, p3, p4, p5, p6, p7, p8);
+
+ return p8[2];
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-10.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-10.c
new file mode 100644
index 0000000..ddd2c36
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-10.c
@@ -0,0 +1,56 @@
+/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
+ Test reduced from libstdc++-v3/testsuite/ext/ext_pointer/1.cc.
+ It verifies that iteration in find_implicit_erroneous_behavior
+ in gimple-ssa-isolate-path.c terminates under specific conditions.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+struct A { int i; };
+struct P { uintptr_t d; };
+
+static inline struct A* get (const struct P *p)
+{
+ if (p->d == 1)
+ return 0;
+
+ return (struct A*)((uintptr_t)p + p->d);
+}
+
+static inline void set (struct P *p, struct A* q)
+{
+ /* The basic block below would cause an infinite loop in
+ find_implicit_erroneous_behavior due to assuming the DUPLICATE
+ pointer returned from isolate_path would distinct from the one
+ passed to it. (Replacing the if statement with the ternary ?:
+ expression did not have this effect (it gets optimized early
+ on).
+ <bb 4> [local count: 1073741823]:
+ # _14 = PHI <0B(2), &MEM <struct A[2]> [(void *)&a + 4B](3)>
+ _2 = _14->i;
+ if (_2 != 2)
+ goto <bb 5>; [0.00%]
+ else
+ goto <bb 6>; [100.00%]
+ */
+ if (!q)
+ p->d = 1;
+ else
+ p->d = (uintptr_t)(q) - (uintptr_t)(p);
+}
+
+void f (void)
+{
+ struct A a[2] = { { 1 }, { 2 } };
+
+ struct P p, q;
+ set (&p, a);
+ set (&q, get (&p));
+
+ set (&q, get (&q) + 0);
+ set (&q, get (&q) + 1);
+
+ if (get (&q)[0].i != get (&p)[1].i)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c
new file mode 100644
index 0000000..0e3435c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c
@@ -0,0 +1,293 @@
+/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+
+struct A { int a, b, c; };
+struct B { int a, b, c[]; };
+
+void sink (void*, ...);
+
+ATTR (noipa) void*
+return_alloca (int n)
+{
+ void *p = __builtin_alloca (n);
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_index_cst (int n)
+{
+ int *p = (int*)__builtin_alloca (n);
+ p = &p[1];
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_plus_cst (int n)
+{
+ int *p = (int*)__builtin_alloca (n);
+ p += 1;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_plus_var (int n, int i)
+{
+ char *p = (char*)__builtin_alloca (n);
+ p += i;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_member_1 (int n)
+{
+ struct A *p = (struct A*)__builtin_alloca (n);
+ sink (&p->a);
+ return &p->a; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_member_2 (int n)
+{
+ struct A *p = (struct A*)__builtin_alloca (n);
+ sink (&p->b);
+ return &p->b; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_flexarray (int n)
+{
+ struct B *p = (struct B*)__builtin_alloca (n);
+ sink (p->c);
+ return p->c; /* { dg-warning "function returns address of local" } */
+}
+
+
+ATTR (noipa) void*
+return_array (void)
+{
+ int a[32];
+ void *p = a;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_array_index_cst (void)
+{
+ int a[32];
+ void *p = &a[2];
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_array_plus_cst (void)
+{
+ int a[32];
+ void *p = a + 2;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_array_plus_var (int i)
+{
+ int a[32];
+ void *p = a + i;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_array_member_1 (void)
+{
+ struct A a[2];
+ int *p = &a[1].a;
+ sink (a, p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_array_member_2 (void)
+{
+ struct A a[32];
+ int *p = &a[1].b;
+ sink (a, p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+
+ATTR (noipa) void*
+return_vla (int n)
+{
+ char a[n];
+ void *p = a;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_vla_index_cst (int n)
+{
+ char a[n];
+ char *p = &a[3];
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_vla_plus_cst (int n)
+{
+ char a[n];
+ char *p = a + 3;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_vla_index_var (int n, int i)
+{
+ char a[n];
+ char *p = &a[i];
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_vla_plus_var (int n, int i)
+{
+ char a[n];
+ char *p = a + i;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_vla_member_1 (int n, int i)
+{
+ struct A a[n];
+ void *p = &a[i].a;
+ sink (a, p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_vla_member_2 (int n, int i)
+{
+ struct A a[n];
+ void *p = &a[i].b;
+ sink (a, p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+
+ATTR (noipa) void*
+return_alloca_or_alloca (int n, int i)
+{
+ void *p = i ? __builtin_alloca (n * i) : __builtin_alloca (n);
+ sink (p);
+ /* The warning here should really be "function returns". */
+ return p; /* { dg-warning "function (returns|may return) address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_or_alloca_2 (int n, int i)
+{
+ void *p0 = __builtin_alloca (n);
+ void *p1 = __builtin_alloca (n * 2);
+ void *p = i ? p0 : p1;
+ sink (p0, p1, p);
+ /* Same as above. */
+ return p; /* { dg-warning "function (returns|may return) address of local" } */
+}
+
+ATTR (noipa) void*
+return_array_or_array (int i)
+{
+ int a[5];
+ int b[7];
+ void *p = i ? a : b;
+ sink (a, b, p);
+ /* The warning here should really be "function returns". */
+ return p; /* { dg-warning "function (returns|may return) address of local" } */
+}
+
+ATTR (noipa) void*
+return_array_or_array_plus_var (int i, int j)
+{
+ int a[5];
+ int b[7];
+
+ void *p0 = a + i;
+ void *p1 = b + j;
+
+ void *p = i < j ? p0 : p1;
+ sink (a, b, p0, p1, p);
+ /* The warning here should really be "function returns". */
+ return p; /* { dg-warning "function (returns|may return) address of local" } */
+}
+
+extern int global[32];
+
+ATTR (noipa) void*
+may_return_global_or_alloca (int n, int i)
+{
+ void *p = i ? global : __builtin_alloca (n);
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+
+ATTR (noipa) void*
+may_return_global_or_alloca_plus_cst (int n, int i)
+{
+ int *p = i ? global : (int*)__builtin_alloca (n);
+ p += 7;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+may_return_global_or_array (int n, int i)
+{
+ int a[32];
+ void *p = i ? global : a;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+may_return_global_or_array_plus_cst (int n, int i)
+{
+ int a[32];
+ int *p = i ? global : a;
+ p += 4;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+may_return_global_or_vla (int n, int i)
+{
+ int a[n];
+ void *p = i ? global : a;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+may_return_global_or_vla_plus_cst (int n, int i)
+{
+ int a[n];
+ int *p = i ? global : a;
+ p += 4;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c
new file mode 100644
index 0000000..6dad7af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c
@@ -0,0 +1,248 @@
+/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+
+typedef __INTPTR_TYPE__ intptr_t;
+
+struct A { int a, b, c; };
+struct B { int a, b, c[]; };
+
+extern int g1[5], g2[5], g3[5], g4[5], g5[5];
+
+void sink (void*, ...);
+
+/* Verify that a pointer difference expression is handled correctly
+ even when converted to a pointer. */
+
+ATTR (noipa) void*
+return_local_diff_cst (void)
+{
+ int a[5];
+ void *p = (void*)(&a[4] - &a[1]);
+ return p;
+}
+
+ATTR (noipa) void*
+return_local_diff_var (int i, int j)
+{
+ int a[5];
+ void *p = (void*)(&a[j] - &a[i]);
+ return p;
+}
+
+ATTR (noipa) void*
+return_2_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ void *p = i < 0 ? a : b;
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+/* Verify that returning the address of a local converted to intptr_t
+ is not diagnosed (see bug 90737 for a case the front-end gets wrong). */
+
+ATTR (noipa) intptr_t
+return_int_2_locals (int i)
+{
+ int a[1];
+ int b[2];
+ void *p = i < 0 ? a : b;
+ return (intptr_t)p;
+}
+
+/* Verify that a conditional expression with a pointer first operand
+ is handled correctly. */
+
+ATTR (noipa) void*
+return_2_locals_ptrcond (void *q)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ void *p = q ? a : b;
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+/* Verify that a preincrement expression with a pointer operand is
+ handled correctly. */
+
+ATTR (noipa) void*
+return_2_locals_ptrinc (void *q)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int *p = q ? a : b;
+ return ++p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+
+ void *p = i < 0 ? a : 0 < i ? c : b;
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+/* Verify that a conditional expression with a pointer first operand
+ is handled correctly. */
+
+ATTR (noipa) void*
+return_3_locals_ptrcond (void *p, void *q)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+
+ void *r = q ? r ? a : b : c;
+ return r; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_5_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+ int d[4]; /* { dg-message "declared here" } */
+ int e[5]; /* { dg-message "declared here" } */
+
+ void *p = i < -1 ? a : i < 0 ? b : 1 < i ? e : 0 < i ? d : c;
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_1_global_4_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+ int d[4]; /* { dg-message "declared here" } */
+
+ void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? d : c;
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_2_globals_3_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+
+ void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : c;
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_globals_2_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ void *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3;
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_4_globals_1_local (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+
+ void *p = i < -1 ? a : i < 0 ? g1 : 1 < i ? g2 : 0 < i ? g4 : g3;
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_all_globals (int i)
+{
+ void *p = i < -1 ? g1 : i < 0 ? g2 : 1 < i ? g3 : 0 < i ? g5 : g4;
+ return p;
+}
+
+
+ATTR (noipa) void*
+return_2_alloca_local_cstoff (int n, int i)
+{
+ int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int *p = i < 0 ? a : b;
+ p += 1;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_local_cstoff (int n, int i)
+{
+ int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int *p = i < 0 ? a : b;
+ p += 1;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_local_alloca_cstoff (int n, int i)
+{
+ int a[2]; /* { dg-message "declared here" } */
+ int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int *p = i < 0 ? a : b;
+ p += 1;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_2_locals_cstoff (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int *p = i < 0 ? a : b;
+ p += 1;
+ sink (p);
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_2_globals_3_locals_cstoff (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+
+ int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : c;
+ p += 1;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_globals_alloca_local_varoff (int n, int i, int j)
+{
+ int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3;
+ p += j;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_globals_2_locals_varoff (int i, int j)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ int *p = i < -1 ? a : i < 0 ? b : 1 < i ? g1 : 0 < i ? g2 : g3;
+ p += j;
+ sink (p);
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c
new file mode 100644
index 0000000..0a451ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c
@@ -0,0 +1,370 @@
+/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define ATTR(...) __attribute__ ((__VA_ARGS__))
+
+struct A { int a, b, c; };
+struct B { int a, b, c[]; };
+
+extern int g1[5], g2[5], g3[5], g4[5], g5[5];
+
+void sink (void*, ...);
+
+ATTR (noipa) void*
+return_2_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ void *p = b;
+ if (i < 0)
+ p = a;
+
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_2_locals_after_2_globals (int i, int j)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ int *p;
+ if (i < 0)
+ p = g1;
+ else
+ p = g2;
+
+ sink (p);
+
+ if (j < 0)
+ p = a;
+ else
+ p = b;
+
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+
+ void *p = b + 1;
+ if (i < 0)
+ p = a;
+ else if (0 < i)
+ p = c + 2;
+
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_5_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+ int d[4]; /* { dg-message "declared here" } */
+ int e[5]; /* { dg-message "declared here" } */
+
+ void *p = &c[2];
+ if (i < -1)
+ p = a;
+ else if (i < 0)
+ p = &b[1];
+ else if (1 < i)
+ p = &e[4];
+ else if (0 < i)
+ p = &d[3];
+
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_5_locals_switch (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+ int d[4]; /* { dg-message "declared here" } */
+ int e[5]; /* { dg-message "declared here" } */
+
+ void *p = 0;
+
+ switch (i)
+ {
+ case 0: p = &a[1]; break;
+ case 1: p = &b[2]; break;
+ case 2: p = &c[3]; break;
+ case 3: p = &d[4]; break;
+ default: p = &e[5]; break;
+ }
+
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_1_global_4_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+ int d[4]; /* { dg-message "declared here" } */
+
+ void *p = c;
+ if (i < -1)
+ sink (p = a);
+ else if (i < 0)
+ sink (p = b);
+ else if (1 < i)
+ sink (p = g1);
+ else if (0 < i)
+ sink (p = d);
+
+ sink (p, a, b, c, d);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_1_global_4_locals_switch (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+ int d[4]; /* { dg-message "declared here" } */
+
+ void *p = 0;
+
+ switch (i)
+ {
+ case 0: p = &a[0]; break;
+ case 1: p = &b[1]; break;
+ case 2: p = &c[2]; break;
+ case 3: p = &d[3]; break;
+ }
+
+ sink (p);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_2_globals_3_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+
+ void *p = c;
+ if (i < -1)
+ p = a;
+ else if (i < 0)
+ p = b;
+ else if (1 < i)
+ p = g1;
+ else if (0 < i)
+ p = g2;
+
+ sink (p);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_globals_2_locals (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ void *p = g3;
+ if (i < -1)
+ p = a;
+ else if (i < 0)
+ p = b;
+ else if (1 < i)
+ p = g1;
+ else if (0 < i)
+ p = g2;
+
+ sink (p);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_4_globals_1_local (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+
+ void *p = g3;
+ if (i < -1)
+ p = a;
+ else if (i < 0)
+ p = g1;
+ else if (1 < i)
+ p = g2;
+ else if (0 < i)
+ p = g4;
+
+ sink (p);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_all_globals (int i)
+{
+ void *p = g4;
+ if (i < -1)
+ p = g1;
+ else if (i < 0)
+ p = g2;
+ else if (1 < i)
+ p = g3;
+ else if (0 < i)
+ p = g5;
+ return p;
+}
+
+
+ATTR (noipa) void*
+return_2_alloca_local_cstoff (int n, int i)
+{
+ int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int *p = i < 0 ? a : b;
+
+ p += 1;
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_alloca_local_cstoff (int n, int i)
+{
+ int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ int *p = b;
+ if (i < 0)
+ p = a;
+
+ p += 1;
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_local_alloca_cstoff (int n, int i)
+{
+ int a[2]; /* { dg-message "declared here" } */
+ int *b = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int *p = b;
+ if (i < 0)
+ p = a;
+
+ p += 1;
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_2_locals_cstoff (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ int *p = b;
+ if (i < 0)
+ p = a;
+
+ p += 1;
+ sink (p);
+
+ return p; /* { dg-warning "function returns address of local" } */
+}
+
+ATTR (noipa) void*
+return_2_globals_3_locals_cstoff (int i)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+ int c[3]; /* { dg-message "declared here" } */
+
+ int *p = c;
+ if (i < -1)
+ p = a;
+ else if (i < 0)
+ p = b;
+ else if (1 < i)
+ p = g1;
+ else if (0 < i)
+ p = g2;
+
+ p += 1;
+ sink (p);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_globals_alloca_local_varoff (int n, int i, int j)
+{
+ int *a = __builtin_alloca (n); /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ int *p = g3;
+ if (i < -1)
+ p = a;
+ else if (i < 0)
+ p = b;
+ else if (1 < i)
+ p = g1;
+ else if (0 < i)
+ p = g2;
+
+ p += j;
+ sink (p);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
+ATTR (noipa) void*
+return_3_globals_2_locals_varoff (int i, int j)
+{
+ int a[1]; /* { dg-message "declared here" } */
+ int b[2]; /* { dg-message "declared here" } */
+
+ int *p = g3;
+ if (i < -1)
+ p = a;
+ else if (i < 0)
+ p = b;
+ else if (1 < i)
+ p = g1;
+ else if (0 < i)
+ p = g2;
+
+ p += j;
+ sink (p);
+
+ return p; /* { dg-warning "function may return address of local" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-5.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-5.c
new file mode 100644
index 0000000..bdf1cd4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-5.c
@@ -0,0 +1,40 @@
+/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+void sink (void*);
+
+void* loop_idx (int x)
+{
+ char a[32]; /* { dg-message "declared here" } */
+ char *p = a;
+
+ sink (a);
+
+ int i;
+ for (i = 0; i != 32; ++i)
+ if (p[i] == x)
+ break;
+
+ p = i < 32 ? &p[i] : 0;
+ return p; /* { dg-warning "may return address of local variable" } */
+}
+
+
+void* loop_ptr (int i, int x)
+{
+ char a[32]; /* { dg-message "declared here" } */
+ char *p;
+
+ sink (a);
+
+ /* The warning for the statement below would ideally be a "returns"
+ because it definitely returns the address of a, but when both
+ returns get merged into one we end up with a "may return". */
+ for (p = a; *p; ++p)
+ if (*p == x)
+ return p; /* { dg-warning "(returns|may return) address of local variable" "missing location" { xfail *-*-* } } */
+ /* { dg-warning "(returns|may return) address of local variable" "pr90735" { target *-*-* } 0 } */
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c
new file mode 100644
index 0000000..70138b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c
@@ -0,0 +1,203 @@
+/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* memcpy (void*, const void*, size_t);
+void* mempcpy (void*, const void*, size_t);
+void* memmove (void*, const void*, size_t);
+
+char* stpcpy (char*, const char*);
+char* stpncpy (char*, const char*, size_t);
+
+size_t strlen (const char*);
+size_t strnlen (const char*, size_t);
+
+char* strcat (char*, const char*);
+char* strncat (char*, const char*, size_t);
+
+char* strcpy (char*, const char*);
+char* strncpy (char*, const char*, size_t);
+
+char* strdup (const char*);
+
+char* strchr (const char*, int);
+char* strrchr (const char*, int);
+char* strstr (const char*, const char*);
+
+void sink (void*, ...);
+
+
+void* return_memcpy (const void *s, unsigned n)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ void *p = memcpy (a, s, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+void* return_memcpy_cst (const void *s, unsigned n)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ void *p = memcpy (a + 1, s, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+void* return_memcpy_var (const void *s, unsigned n, int i)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ void *p = memcpy (a + i, s, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+void* return_mempcpy (const void *s, unsigned n)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ void *p = mempcpy (a, s, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+void* return_memmove_cst (unsigned n)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ void *p = memmove (a + 1, a, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+void* return_memmove_var (unsigned n, int i)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ void *p = memmove (a + i, a, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_stpcpy (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ char *p = stpcpy (a, s);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_stpncpy (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ char *p = stpncpy (a, s, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strcat (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ char *p = strcat (a, s);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strncat (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ char *p = strncat (a, s, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+
+}
+char* return_strcpy (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ char *p = strcpy (a, s);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strcpy_plus_strlen (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ char *p = strcpy (a, s);
+ sink (p);
+ p += strlen (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strcpy_cst_plus_strlen (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ char *p = strcpy (a + 1, s);
+ sink (p);
+ p += strlen (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strcpy_var_plus_strlen (unsigned n, const char *s, int i)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ char *p = strcpy (a + i, s);
+ sink (p);
+ p += strlen (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strncpy (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ char *p = strncpy (a, s, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strncpy_plus_strnlen (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ char *p = strncpy (a, s, n);
+ p += strnlen (p, n);
+ sink (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strdup (unsigned n)
+{
+ char a[n];
+ sink (a);
+ char *p = strdup (a);
+ return p;
+}
+
+char* return_strchr (unsigned n, int c)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ char *p = strchr (a, c);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strstr (unsigned n, const char *s)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ char *p = strstr (a, s);
+ if (p)
+ p += strlen (p);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+}
+
+char* return_strrchr (unsigned n, int c)
+{
+ char a[n]; /* { dg-message "declared here" } */
+ sink (a);
+ char *p = strrchr (a, c);
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr]" } */
+
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-7.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-7.c
new file mode 100644
index 0000000..ac1fb76
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-7.c
@@ -0,0 +1,50 @@
+/* Test to verify that a PHI with a COND_EXPR argument in a return
+ statement is handled correctly.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+extern struct S s;
+
+void* f (int n)
+{
+ void *p;
+ int x = 0;
+
+ for (int i = n; i >= 0; i--)
+ {
+ p = &s;
+ if (p == (void*)-1)
+ x = 1;
+ else if (p)
+ return p;
+ }
+
+ /* The return statement below ends up with the following IL:
+ <bb 6> [local count: 59055800]:
+ # x_10 = PHI <1(5), 0(2)>
+ _5 = x_10 != 0 ? -1B : 0B;
+
+ <bb 7> [local count: 114863532]:
+ # _3 = PHI <&s(4), _5(6), &s(3)>
+ return _3; */
+ return x ? (void*)-1 : 0;
+}
+
+void* g (int n)
+{
+ void *p;
+ int x = 0; /* { dg-message "declared here" } */
+
+ for (int i = n; i >= 0; i--)
+ {
+ p = &s;
+ if (p == (void*)-1)
+ x = 1;
+ else if (p)
+ return p;
+ }
+
+ /* The return statement below does not reference a COND_EXPR argument. */
+ return x ? &x : 0; /* { dg-warning "may return address of local variable" "missing location" { xfail *-*-* } } */
+ /* { dg-warning "may return address of local variable" "pr90735" { target *-*-* } 0 } */
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-8.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-8.c
new file mode 100644
index 0000000..98a3805
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-8.c
@@ -0,0 +1,88 @@
+/* Test to verify that a MAX_EXPR and MIN_EXPR in a return statement
+ is handled correctly and that all local variables whose address
+ is or may be returned are identified.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+char* sink (char*, ...);
+
+void* test_max_2 (void)
+{
+ char c; /* { dg-message "declared here" } */
+
+ char *p = sink (&c);
+
+ void *q = p > &c ? p : &c; /* MAX_EXPR */
+ return q; /* { dg-warning "\\\[-Wreturn-local-addr" } */
+}
+
+void* test_max_3 (void)
+{
+ char c; /* { dg-message "declared here" } */
+ char d; /* { dg-message "declared here" } */
+
+ char *p = sink (&c, &d);
+
+ void *q = p < &c ? &c < &d ? &d : &c : p;
+ return q; /* { dg-warning "\\\[-Wreturn-local-addr" } */
+}
+
+void* test_min_2 (void)
+{
+ char c; /* { dg-message "declared here" } */
+
+ char *p = sink (&c);
+
+ void *q = p < &c ? p : &c; /* MIN_EXPR" */
+ return q; /* { dg-warning "\\\[-Wreturn-local-addr" } */
+}
+
+void* test_min_3 (void)
+{
+ char c; /* { dg-message "declared here" } */
+ char d; /* { dg-message "declared here" } */
+
+ char *p = sink (&c, &d);
+
+ void *q = p > &c ? &c > &d ? &d : &c : p;
+ return q; /* { dg-warning "\\\[-Wreturn-local-addr" } */
+}
+
+void* test_min_2_phi (int i)
+{
+ char a; /* { dg-message "declared here" } */
+
+ char *p = &a;
+ char *q = sink (&a);
+ p = p < q ? p : q;
+ if (i == 1)
+ return p;
+ /* { dg-warning "may return address of local variable" "missing location" { xfail *-*-* } } */
+ else
+ return q;
+}
+
+void* test_min_3_phi (int i)
+{
+ char a; /* { dg-message "declared here" } */
+ char b; /* { dg-message "declared here" } */
+
+ char *p0 = &a;
+ char *p1 = &b;
+ char *p2 = sink (&a, &b);
+ char *p3 = sink (&a, &b);
+
+ char *p4 = p2 < p0 ? p2 : p0;
+ char *p5 = p3 < p1 ? p3 : p1;
+
+ if (i == 1)
+ /* { dg-warning "may return address of local variable" "missing location" { xfail *-*-* } } */
+ return p4;
+ else
+ /* { dg-warning "may return address of local variable" "missing location" { xfail *-*-* } } */
+ return p5;
+}
+
+/* The directive below "swallows" warnings for both test_min_2_phi
+ and test_min_3_phi.
+ { dg-warning "may return address of local variable" "pr90735" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-9.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-9.c
new file mode 100644
index 0000000..d24f911
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-9.c
@@ -0,0 +1,73 @@
+/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
+ Test derived from gcc.c-torture/execute/20071108-1.c. It shows
+ a false positive at -Os caused by the jump threading/vrp1 pass.
+ { dg-do compile }
+ { dg-options "-Os -fdump-tree-optimized" } */
+
+struct S
+{
+ int i;
+};
+
+void* f (void);
+
+__attribute__ ((noinline))
+struct S* g (int i)
+{
+ struct S *p = f (), q;
+
+ if (p == 0)
+ p = &q;
+
+ p->i = i;
+
+ if (p == &q)
+ p = 0;
+
+ /* With -Os the warning pass sees:
+
+ ...
+ <bb 4>
+ # p_1 = PHI <&q(2), p_5(3)>
+ p_1->i = i_6(D);
+ if (&q == p_1)
+ goto <bb 6>; [14.90%]
+ else
+ goto <bb 5>; [85.10%]
+
+ <bb 5>
+
+ <bb 6>
+ # p_2 = PHI <0B(4), p_1(5)>
+ q ={v} {CLOBBER};
+ return p_2;
+ }
+
+ which leads to: */
+ return p; /* { dg-bogus "may return address of local variable" "" { xfail *-*-* } } */
+
+ /* Whereas as -O2 the pass sees:
+
+ <bb 2>
+ p_5 = f ();
+ if (p_5 == 0B)
+ goto <bb 4>; [30.00%]
+ else
+ goto <bb 3>; [70.00%]
+
+ <bb 3>
+ # p_2 = PHI <0B(5), p_5(4)>
+ q ={v} {CLOBBER};
+ return p_2;
+
+ <bb 4>
+ p_5->i = i_6(D);
+ goto <bb 3>; [100.00%]
+
+ <bb 5>
+ q.i = i_6(D);
+ goto <bb 3>; [100.00%]
+ }
+
+ and no warning. */
+}
diff --git a/gcc/testsuite/gcc.dg/autopar/pr91162.c b/gcc/testsuite/gcc.dg/autopar/pr91162.c
new file mode 100644
index 0000000..ff243e4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/autopar/pr91162.c
@@ -0,0 +1,25 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O -ftree-parallelize-loops=2 -fno-tree-dominator-opts --param parloops-min-per-thread=30" } */
+
+void
+zf (__int128 ct)
+{
+ __int128 *rk = &ct;
+
+ if (0)
+ {
+ int jj;
+
+t9:
+ for (jj = 0; jj < 60; ++jj)
+ {
+ }
+
+ __builtin_unreachable ();
+ }
+
+ while (*rk < 1)
+ ++*rk;
+
+ goto t9;
+}
diff --git a/gcc/testsuite/gcc.dg/gimplefe-43.c b/gcc/testsuite/gcc.dg/gimplefe-43.c
new file mode 100644
index 0000000..5fd66e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-43.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple" } */
+
+void __GIMPLE foo()
+{
+ try
+ {
+ try
+ {
+ ;
+ }
+ finally
+ {
+ ;
+ }
+ else
+ {
+ ;
+ }
+ }
+ finally
+ {
+ ;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/gimplefe-44.c b/gcc/testsuite/gcc.dg/gimplefe-44.c
new file mode 100644
index 0000000..a9a92b1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-44.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-fexceptions -fgimple -fdump-tree-eh-eh" } */
+
+void __GIMPLE foo()
+{
+ try
+ {
+ try
+ {
+ extern void might_throw1 ();
+ might_throw1 ();
+ }
+ finally
+ {
+ extern void might_throw2 ();
+ might_throw2 ();
+ }
+ else
+ {
+ extern void might_throw3 ();
+ might_throw3 ();
+ }
+ }
+ finally
+ {
+ extern void might_throw4 ();
+ might_throw4 ();
+ }
+}
+
+/* { dg-final { scan-tree-dump ".LP 1. might_throw1" "eh" } } */
+/* { dg-final { scan-tree-dump ".LP 2. might_throw2" "eh" } } */
+/* { dg-final { scan-tree-dump ".LP 2. might_throw3" "eh" } } */
diff --git a/gcc/testsuite/gcc.dg/gomp/pr78884.c b/gcc/testsuite/gcc.dg/gomp/pr78884.c
new file mode 100644
index 0000000..3e03df5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr78884.c
@@ -0,0 +1,16 @@
+/* PR middle-end/78884 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+void bar (int *);
+
+void
+foo (int n)
+{
+#pragma omp simd
+ for (int i = 0; i < 1024; i++)
+ {
+ int vla[n];
+ bar (vla);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr91063.c b/gcc/testsuite/gcc.dg/gomp/pr91063.c
new file mode 100644
index 0000000..32938f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr91063.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/91063 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp-simd" } */
+/* { dg-additional-options "-mavx512f" { target { i?86-*-* x86_64-*-* } } } */
+
+struct S { void *s; };
+
+int
+foo (struct S *x)
+{
+ int r = 0;
+ int i;
+#pragma omp simd reduction (+ : r)
+ for (i = 0; i < 64; ++i)
+ r += (int) (x->s != 0);
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/guality.h b/gcc/testsuite/gcc.dg/guality/guality.h
index 7a16475..d41327c 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.h
+++ b/gcc/testsuite/gcc.dg/guality/guality.h
@@ -23,6 +23,9 @@ along with GCC; see the file COPYING3. If not see
#include <string.h>
#include <stdint.h>
#include <unistd.h>
+#ifdef __linux
+#include <sys/prctl.h>
+#endif
/* This is a first cut at checking that debug information matches
run-time. The idea is to annotate programs with GUALCHK* macros
@@ -214,6 +217,10 @@ main (int argc, char *argv[])
int i;
char *argv0 = argv[0];
+#if defined(PR_SET_PTRACER_ANY)
+ prctl (PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+#endif
+
guality_gdb_command = getenv ("GUALITY_GDB");
if (!guality_gdb_command)
{
diff --git a/gcc/testsuite/gcc.dg/pr41551.c b/gcc/testsuite/gcc.dg/pr41551.c
index 2f2ad2b..e112320 100644
--- a/gcc/testsuite/gcc.dg/pr41551.c
+++ b/gcc/testsuite/gcc.dg/pr41551.c
@@ -10,3 +10,5 @@ int main(void)
int var, *p = &var;
return (double)(uintptr_t)(p);
}
+
+/* { dg-prune-output "-Wreturn-local-addr" } */
diff --git a/gcc/testsuite/gcc.dg/pr57438-2.c b/gcc/testsuite/gcc.dg/pr57438-2.c
deleted file mode 100644
index f3ff1dc..0000000
--- a/gcc/testsuite/gcc.dg/pr57438-2.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* { dg-do compile { target *-*-darwin* } } */
-/* { dg-options "--param case-values-threshold=3 -O2" } */
-/* { dg-additional-options "-funwind-tables" { target powerpc*-*-darwin* } }
-
-/* This is testing that a trailing local label is followed by a
- nop where required. */
-
-int foo (int x)
-{
- switch (x)
- {
- case 0:
- return 10;
- case 3:
- return -1;
- case 5:
- return 29;
- default:
- __builtin_unreachable();
- }
-}
-
-/* { dg-final { scan-assembler "nop\\nLFE.*" { target { *-*-darwin* } } } } */
diff --git a/gcc/testsuite/gcc.dg/pr59523.c b/gcc/testsuite/gcc.dg/pr59523.c
index a6c3302..49cbe5d 100644
--- a/gcc/testsuite/gcc.dg/pr59523.c
+++ b/gcc/testsuite/gcc.dg/pr59523.c
@@ -16,3 +16,5 @@ foo (int a, int *b, int *c, int *d)
r[i] = 1;
return r;
}
+
+/* { dg-prune-output "-Wreturn-local-addr" } */
diff --git a/gcc/testsuite/gcc.dg/pr90756.c b/gcc/testsuite/gcc.dg/pr90756.c
new file mode 100644
index 0000000..3507aa2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr90756.c
@@ -0,0 +1,26 @@
+/* PR rtl-optimization/90756 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wno-psabi" } */
+/* { dg-additional-options "-mno-sse" { target ia32 } } */
+
+typedef float B __attribute__((vector_size(4 * sizeof (float))));
+typedef unsigned long long C __attribute__((vector_size(4 * sizeof (long long))));
+typedef short D __attribute__((vector_size(4 * sizeof (short))));
+B z;
+void foo (C);
+C bar (D);
+B baz ();
+D qux (B);
+
+void
+quux (int x)
+{
+ B n = z, b = z;
+ while (1)
+ switch (x)
+ {
+ case 0: n = baz (); /* FALLTHRU */
+ case 1: { B o = n; n = b; b = o; } /* FALLTHRU */
+ case 2: { D u = qux (b); C v = bar (u); foo (v); }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr91069.c b/gcc/testsuite/gcc.dg/pr91069.c
index 221da30..fdb2cfd 100644
--- a/gcc/testsuite/gcc.dg/pr91069.c
+++ b/gcc/testsuite/gcc.dg/pr91069.c
@@ -1,8 +1,8 @@
/* { dg-do run } */
/* { dg-options "-std=gnu11" } */
-typedef double v2df __attribute__((vector_size(16)));
-typedef long v2di __attribute__((vector_size(16)));
+typedef double v2df __attribute__((vector_size(2 * sizeof (double))));
+typedef long long v2di __attribute__((vector_size(2 * sizeof (long long))));
void foo (v2df *res, v2df *src)
{
diff --git a/gcc/testsuite/gcc.dg/pr91172.c b/gcc/testsuite/gcc.dg/pr91172.c
new file mode 100644
index 0000000..a38a058
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91172.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-Werror=target-lifetime" } */
+/* { dg-warning "'-Werror\=' argument '-Werror=target-lifetime' is not valid for C" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/pr91181.c b/gcc/testsuite/gcc.dg/pr91181.c
new file mode 100644
index 0000000..63e3362
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91181.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+/* { dg-additional-options "-mavx" { target x86_64-*-* i?86-*-* } } */
+
+enum { a, b, c };
+float *d, *e;
+int f, g, h, i;
+int j()
+{
+ float a;
+ for (; h; h++)
+ {
+ i = h * 4;
+ a = d[i + b];
+ if (a) {
+ e[i + b] = g < d[i + b] * f * a ? g : d[i + b] * f * a;
+ e[i + c] = g < d[i + c] * f * a ? g : d[i + c] * f * a;
+ }
+ e[i + b] = e[i + c];
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/predict-17.c b/gcc/testsuite/gcc.dg/predict-17.c
index 5069aa4..45b618a 100644
--- a/gcc/testsuite/gcc.dg/predict-17.c
+++ b/gcc/testsuite/gcc.dg/predict-17.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
+/* { dg-options "-O2 -fdump-tree-profile_estimate-details" } */
extern int global;
@@ -11,3 +11,5 @@ void foo (int base)
/* { dg-final { scan-tree-dump "first match heuristics: 5.00%" "profile_estimate"} } */
/* { dg-final { scan-tree-dump "__builtin_expect_with_probability heuristics of edge .*->.*: 5.00%" "profile_estimate"} } */
+/* { dg-final { scan-tree-dump "is probably executed at most 19" "profile_estimate"} } */
+
diff --git a/gcc/testsuite/gcc.dg/strlenopt-26.c b/gcc/testsuite/gcc.dg/strlenopt-26.c
index da2f465..6bb0263 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-26.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-26.c
@@ -17,8 +17,7 @@ main (void)
{
char p[] = "foobar";
const char *volatile q = "xyzzy";
- fn1 (p, q);
- return 0;
+ return fn1 (p, q);
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-67.c b/gcc/testsuite/gcc.dg/strlenopt-67.c
new file mode 100644
index 0000000..e1b1de2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-67.c
@@ -0,0 +1,52 @@
+/* PR tree-optimization/90989 - incorrrect strlen result after second strcpy
+ into the same destination.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+// #include "strlenopt.h"
+
+char a[4];
+
+int f4 (void)
+{
+ char b[4];
+ __builtin_strcpy (b, "12");
+
+ int i = __builtin_strcmp (a, b);
+
+ __builtin_strcpy (b, "123");
+ if (__builtin_strlen (b) != 3)
+ __builtin_abort ();
+
+ return i;
+}
+
+int f6 (void)
+{
+ char b[6];
+ __builtin_strcpy (b, "1234");
+
+ int i = __builtin_strcmp (a, b);
+
+ __builtin_strcpy (b, "12345");
+ if (__builtin_strlen (b) != 5)
+ __builtin_abort ();
+
+ return i;
+}
+
+int f8 (void)
+{
+ char b[8];
+ __builtin_strcpy (b, "1234");
+
+ int i = __builtin_strcmp (a, b);
+
+ __builtin_strcpy (b, "1234567");
+ if (__builtin_strlen (b) != 7)
+ __builtin_abort ();
+
+ return i;
+}
+
+/* { dg-final { scan-tree-dump-times "abort|strlen" 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr91126.c b/gcc/testsuite/gcc.dg/torture/pr91126.c
new file mode 100644
index 0000000..8e34815
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91126.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+
+struct S
+{
+ __INT32_TYPE__ a : 24;
+ __INT32_TYPE__ b : 8;
+} s;
+
+int
+main()
+{
+ s.a = 0xfefefe;
+ s.b = 0xfe;
+ unsigned char c;
+ c = ((unsigned char *)&s)[0];
+ if (c != 0xfe)
+ __builtin_abort ();
+ c = ((unsigned char *)&s)[1];
+ if (c != 0xfe)
+ __builtin_abort ();
+ c = ((unsigned char *)&s)[2];
+ if (c != 0xfe)
+ __builtin_abort ();
+ c = ((unsigned char *)&s)[3];
+ if (c != 0xfe)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91145.c b/gcc/testsuite/gcc.dg/torture/pr91145.c
new file mode 100644
index 0000000..7d62ad1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91145.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=skylake-avx512" { target x86_64-*-* i?86-*-* } } */
+
+int a, c;
+unsigned b, e;
+extern unsigned d[100];
+
+void f()
+{
+ for (int g = 0; g < 70; g++)
+ {
+
+ b += d[g] - c;
+ e -= g ^ a;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91178.c b/gcc/testsuite/gcc.dg/torture/pr91178.c
new file mode 100644
index 0000000..b7a2dbe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91178.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+int a;
+extern int f[10][91125];
+int b[50];
+void c()
+{
+ for (int d = 6; d <= a; d++)
+ for (int e = 16; e <= 24; e++)
+ b[e] -= f[d][d];
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91180.c b/gcc/testsuite/gcc.dg/torture/pr91180.c
new file mode 100644
index 0000000..02b2425
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91180.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+
+int
+main ()
+{
+#if __SIZEOF_INT__ == 4
+ unsigned x = 0xffffffff;
+ __builtin_memset (1 + (char *) &x, 0, 2);
+ if (x != 0xff0000ff)
+ __builtin_abort ();
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91200.c b/gcc/testsuite/gcc.dg/torture/pr91200.c
new file mode 100644
index 0000000..09db9e1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91200.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+
+int printf (const char *, ...);
+
+char a;
+int b, c, **d;
+
+int main ()
+{
+ int f = -128, *g, *h[2] = {0, 0}, i;
+ printf("0");
+ if (a)
+ {
+ while (f > a) {
+ int *j = &i;
+ *j |= 0;
+ }
+ h[i] = &c;
+ }
+ if (h[1])
+ {
+ int **k = &g;
+ *k = &f;
+ while (i)
+ {
+ int **l[] = {&g};
+ }
+ int **m = &g;
+ *d = *m = &b;
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91207.c b/gcc/testsuite/gcc.dg/torture/pr91207.c
new file mode 100644
index 0000000..36d71d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91207.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+
+long long a;
+int b[92][32];
+unsigned int c, d;
+
+void e(long long *f, int p2) { *f = p2; }
+
+int main()
+{
+ for (int i = 6; i <= 20; d = i++)
+ for (int j = 6; j <= 91; j++) {
+ for (int k = 16; k <= 31;k++)
+ b[j][k] ^= 7;
+ c *= d;
+ }
+
+ for (int i = 0; i < 21; ++i)
+ for (int j = 0; j < 32; ++j)
+ e(&a, b[i][j]);
+
+ if (a != 7)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91211.c b/gcc/testsuite/gcc.dg/torture/pr91211.c
new file mode 100644
index 0000000..84db92d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91211.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+typedef __UINT32_TYPE__ u32;
+
+int
+main (void)
+{
+ u32 b = 0x027C5902;
+ u32 a = 0;
+ __builtin_memset (1 + (char *) &b, 0, 2);
+ __builtin_memcpy (&a, 2 + (char *) &b, 2);
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (a != 0x00000200)
+#else
+ if (a != 0x00020000)
+#endif
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
new file mode 100644
index 0000000..5ee9d64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+int __GIMPLE (ssa,startwith("fre"))
+foo ()
+{
+ int * p;
+ int i;
+ int x[4];
+ long unsigned int _1;
+ long unsigned int _2;
+ int _7;
+
+ __BB(2):
+ i_3 = 0;
+ _1 = (long unsigned int) i_3;
+ _2 = _1 * 4ul;
+ p_4 = _Literal (int *) &x + _2;
+ __MEM <v4si> ((v4si *)p_4) = _Literal (v4si) { 1, 2, 3, 4 };
+ _7 = x[0];
+ return _7;
+}
+
+/* { dg-final { scan-tree-dump "return 1;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
new file mode 100644
index 0000000..ecdd8f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+int __GIMPLE (ssa,startwith("fre"))
+foo ()
+{
+ int * p;
+ int i;
+ int x[4];
+ long unsigned int _1;
+ long unsigned int _2;
+ int _7;
+
+ __BB(2):
+ i_3 = 0;
+ _1 = (long unsigned int) i_3;
+ _2 = _1 * 4ul;
+ p_4 = _Literal (int *) &x + _2;
+ __MEM <v4si> ((v4si *)p_4) = _Literal (v4si) {};
+ _7 = x[0];
+ return _7;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-7.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-7.c
new file mode 100644
index 0000000..07f3c9d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-7.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
+/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+int __GIMPLE (ssa,startwith("fre"))
+foo (int c)
+{
+ int * p;
+ int i;
+ int x[4];
+ long unsigned int _1;
+ long unsigned int _2;
+ int _7;
+ v4si _6;
+
+ __BB(2):
+ i_3 = 0;
+ _1 = (long unsigned int) i_3;
+ _2 = _1 * 4ul;
+ p_4 = _Literal (int *) &x + _2;
+ _6 = _Literal (v4si) { c_5(D), c_5(D), c_5(D), c_5(D) };
+ __MEM <v4si> ((v4si *)p_4) = _6;
+ _7 = x[0];
+ return _7;
+}
+
+/* { dg-final { scan-tree-dump "return c_5\\(D\\);" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-37.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-37.c
index 2fb0e0c..c913d26 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/alias-37.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-37.c
@@ -12,7 +12,7 @@ int *foo (int bogus, int n)
p = &a[2];
else
p = &i;
- return p;
+ return p; /* { dg-warning "\\\[-Wreturn-local-addr" } */
}
/* { dg-final { scan-tree-dump "Deleted dead store" "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-1.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-1.c
index ba90b56..7676aa6 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-fre3" } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
struct foo
{
int val;
@@ -18,4 +18,4 @@ test ()
return barptr->val2;
}
-/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c
index 974cdb0..fdc3055 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-fre3" } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
struct a {
int val;
};
@@ -19,4 +19,4 @@ test (int i, int j, int k, int l)
dptr->c.b[k].a2[l].val=2;
return cptr->b[i].a[j].val;
}
-/* { dg-final { scan-tree-dump-times "return 123" 1 "fre3"} } */
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
new file mode 100644
index 0000000..ef4ffac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-3.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+struct a {int v1;
+ int v2;};
+struct b {struct a a[0];};
+
+int
+test (struct b *bptr1, struct b *bptr2, int i, int j)
+{
+ bptr1->a[i].v1=123;
+ bptr2->a[j].v2=1;
+ return bptr1->a[i].v1;
+}
+int
+test2 (struct b *bptr1, struct b *bptr2, int i, int j)
+{
+ bptr1->a[i].v1=123;
+ bptr2->a[j].v1=1;
+ return bptr1->a[i].v1;
+}
+/* test should be optimized, while test2 should not. */
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
new file mode 100644
index 0000000..85f2c6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-8.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+struct a {
+ int val;
+};
+struct b {
+ struct a a[10],a2[10];
+};
+struct c {
+ struct b b[10];
+} *cptr,*cptr2;
+
+
+int
+test (int i, int j, int k, int l)
+{
+ cptr->b[i].a[j].val=123;
+ cptr2->b[k].a2[l].val=2;
+ return cptr->b[i].a[j].val;
+}
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c
new file mode 100644
index 0000000..fdc4789
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-9.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+/* This testcase tests nonoverlapping_component_refs_since_match_p in presence
+ of non-trivial mem-refs. */
+struct a {int a,b;};
+struct b {struct a a[10];};
+struct c {int c; struct b b;} c, *cptr;
+
+void
+set_a(struct a *a, int p)
+{
+ a->a=p;
+}
+void
+set_b(struct a *a, int p)
+{
+ a->b=p;
+}
+int
+get_a(struct a *a)
+{
+ return a->a;
+}
+
+int
+test(int i, int j)
+{
+ struct b *bptr = &c.b;
+ set_a (&bptr->a[i], 123);
+ set_b (&bptr->a[j], 124);
+ return get_a (&bptr->a[i]);
+}
+
+int
+test2(int i, int j)
+{
+ struct b *bptr = &cptr->b;
+ set_a (&bptr->a[i], 125);
+ set_b (&bptr->a[j], 126);
+ return get_a (&bptr->a[i]);
+}
+/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */
+/* { dg-final { scan-tree-dump-times "return 125" 1 "fre1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-15.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-15.c
index 55cdcff..a681450 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-15.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-15.c
@@ -20,4 +20,4 @@ int Test(void)
/* When SLP vectorization is enabled the following will fail because DOM
doesn't know how to deal with the vectorized initializer of in. */
/* DOM also doesn't know to CSE in[1] with in = *.LC0 thus the list of targets this fails. */
-/* { dg-final { scan-tree-dump "return 1;" "optimized" { xfail { arm*-*-* powerpc-*-* } } } } */
+/* { dg-final { scan-tree-dump "return 1;" "optimized" { xfail { powerpc-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c b/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c
index 3975757..48d829a 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr84512.c
@@ -13,4 +13,4 @@ int foo()
}
/* Listed targets xfailed due to PR84958. */
-/* { dg-final { scan-tree-dump "return 285;" "optimized" { xfail { { alpha*-*-* amdgcn*-*-* nvptx*-*-* } || { sparc*-*-* && lp64 } } } } } */
+/* { dg-final { scan-tree-dump "return 285;" "optimized" { xfail { amdgcn*-*-* nvptx*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88497-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-1.c
new file mode 100644
index 0000000..b6dd7ba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-1.c
@@ -0,0 +1,60 @@
+/* { dg-do run } */
+/* { dg-require-effective-target vect_double } */
+/* { dg-require-effective-target vsx_hw { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target sse2_runtime { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-reassoc1" } */
+/* { dg-additional-options "-mvsx" { target { powerpc*-*-* } } } */
+/* { dg-additional-options "-msse2" { target { i?86-*-* x86_64-*-* } } } */
+
+/* To test reassoc can undistribute vector bit_field_ref summation.
+
+ arg1 and arg2 are two arrays whose elements of type vector double.
+ Assuming:
+ A0 = arg1[0], A1 = arg1[1], A2 = arg1[2], A3 = arg1[3],
+ B0 = arg2[0], B1 = arg2[1], B2 = arg2[2], B3 = arg2[3],
+
+ Then:
+ V0 = A0 * B0, V1 = A1 * B1, V2 = A2 * B2, V3 = A3 * B3,
+
+ reassoc transforms
+
+ accumulator += V0[0] + V0[1] + V1[0] + V1[1] + V2[0] + V2[1]
+ + V3[0] + V3[1];
+
+ into:
+
+ T = V0 + V1 + V2 + V3
+ accumulator += T[0] + T[1];
+
+ Fewer bit_field_refs, only two for 128 or more bits vector. */
+
+typedef double v2df __attribute__ ((vector_size (16)));
+__attribute__ ((noinline)) double
+test (double accumulator, v2df arg1[], v2df arg2[])
+{
+ v2df temp;
+ temp = arg1[0] * arg2[0];
+ accumulator += temp[0] + temp[1];
+ temp = arg1[1] * arg2[1];
+ accumulator += temp[0] + temp[1];
+ temp = arg1[2] * arg2[2];
+ accumulator += temp[0] + temp[1];
+ temp = arg1[3] * arg2[3];
+ accumulator += temp[0] + temp[1];
+ return accumulator;
+}
+
+extern void abort (void);
+
+int
+main ()
+{
+ v2df v2[4] = {{1.0, 2.0}, {4.0, 8.0}, {1.0, 3.0}, {9.0, 27.0}};
+ v2df v3[4] = {{1.0, 4.0}, {16.0, 64.0}, {1.0, 2.0}, {3.0, 4.0}};
+ double acc = 100.0;
+ double res = test (acc, v2, v3);
+ if (res != 827.0)
+ abort ();
+ return 0;
+}
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 2 "reassoc1" { target { powerpc*-*-* i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88497-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-2.c
new file mode 100644
index 0000000..8da5920
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-2.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+/* { dg-require-effective-target powerpc_altivec_ok { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target sse2 { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-reassoc1" } */
+/* { dg-additional-options "-maltivec" { target { powerpc*-*-* } } } */
+/* { dg-additional-options "-msse2" { target { i?86-*-* x86_64-*-* } } } */
+
+/* To test reassoc can undistribute vector bit_field_ref on multiplication.
+
+ v1, v2, v3, v4 of type vector float.
+
+ reassoc transforms
+
+ accumulator *= v1[0] * v1[1] * v1[2] * v1[3] *
+ v2[0] * v2[1] * v2[2] * v2[3] *
+ v3[0] * v3[1] * v3[2] * v3[3] *
+ v4[0] * v4[1] * v4[2] * v4[3] ;
+
+ into:
+
+ T = v1 * v2 * v3 * v4;
+ accumulator *= T[0] * T[1] * T[2] * T[3];
+
+ Fewer bit_field_refs, only four for 128 or more bits vector. */
+
+typedef float v4sf __attribute__ ((vector_size (16)));
+float
+test (float accumulator, v4sf v1, v4sf v2, v4sf v3, v4sf v4)
+{
+ accumulator *= v1[0] * v1[1] * v1[2] * v1[3];
+ accumulator *= v2[0] * v2[1] * v2[2] * v2[3];
+ accumulator *= v3[0] * v3[1] * v3[2] * v3[3];
+ accumulator *= v4[0] * v4[1] * v4[2] * v4[3];
+ return accumulator;
+}
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 4 "reassoc1" { target { powerpc*-*-* i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88497-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-3.c
new file mode 100644
index 0000000..449f282
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-3.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target powerpc_altivec_ok { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target sse2 { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-reassoc1" } */
+/* { dg-additional-options "-maltivec" { target { powerpc*-*-* } } } */
+/* { dg-additional-options "-msse2" { target { i?86-*-* x86_64-*-* } } } */
+
+/* To test reassoc can undistribute vector bit_field_ref on bitwise AND.
+
+ v1, v2, v3, v4 of type vector int.
+
+ reassoc transforms
+
+ accumulator &= v1[0] & v1[1] & v1[2] & v1[3] &
+ v2[0] & v2[1] & v2[2] & v2[3] &
+ v3[0] & v3[1] & v3[2] & v3[3] &
+ v4[0] & v4[1] & v4[2] & v4[3] ;
+
+ into:
+
+ T = v1 & v2 & v3 & v4;
+ accumulator &= T[0] & T[1] & T[2] & T[3];
+
+ Fewer bit_field_refs, only four for 128 or more bits vector. */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+int
+test (int accumulator, v4si v1, v4si v2, v4si v3, v4si v4)
+{
+ accumulator &= v1[0] & v1[1] & v1[2] & v1[3];
+ accumulator &= v2[0] & v2[1] & v2[2] & v2[3];
+ accumulator &= v3[0] & v3[1] & v3[2] & v3[3];
+ accumulator &= v4[0] & v4[1] & v4[2] & v4[3];
+ return accumulator;
+}
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 4 "reassoc1" { target { powerpc*-*-* i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88497-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-4.c
new file mode 100644
index 0000000..f7b6c91
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-4.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target powerpc_altivec_ok { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target sse2 { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-reassoc1" } */
+/* { dg-additional-options "-maltivec" { target { powerpc*-*-* } } } */
+/* { dg-additional-options "-msse2" { target { i?86-*-* x86_64-*-* } } } */
+
+/* To test reassoc can undistribute vector bit_field_ref on bitwise IOR.
+
+ v1, v2, v3, v4 of type vector int.
+
+ reassoc transforms
+
+ accumulator |= v1[0] | v1[1] | v1[2] | v1[3] |
+ v2[0] | v2[1] | v2[2] | v2[3] |
+ v3[0] | v3[1] | v3[2] | v3[3] |
+ v4[0] | v4[1] | v4[2] | v4[3] ;
+
+ into:
+
+ T = v1 | v2 | v3 | v4;
+ accumulator |= T[0] | T[1] | T[2] | T[3];
+
+ Fewer bit_field_refs, only four for 128 or more bits vector. */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+int
+test (int accumulator, v4si v1, v4si v2, v4si v3, v4si v4)
+{
+ accumulator |= v1[0] | v1[1] | v1[2] | v1[3];
+ accumulator |= v2[0] | v2[1] | v2[2] | v2[3];
+ accumulator |= v3[0] | v3[1] | v3[2] | v3[3];
+ accumulator |= v4[0] | v4[1] | v4[2] | v4[3];
+ return accumulator;
+}
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 4 "reassoc1" { target { powerpc*-*-* i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88497-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-5.c
new file mode 100644
index 0000000..cbd1224
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-5.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target powerpc_altivec_ok { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target sse2 { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-reassoc1" } */
+/* { dg-additional-options "-maltivec" { target { powerpc*-*-* } } } */
+/* { dg-additional-options "-msse2" { target { i?86-*-* x86_64-*-* } } } */
+
+/* To test reassoc can undistribute vector bit_field_ref on bitwise XOR.
+
+ v1, v2, v3, v4 of type vector int.
+
+ reassoc transforms
+
+ accumulator ^= v1[0] ^ v1[1] ^ v1[2] ^ v1[3] ^
+ v2[0] ^ v2[1] ^ v2[2] ^ v2[3] ^
+ v3[0] ^ v3[1] ^ v3[2] ^ v3[3] ^
+ v4[0] ^ v4[1] ^ v4[2] ^ v4[3] ;
+
+ into:
+
+ T = v1 ^ v2 ^ v3 ^ v4;
+ accumulator ^= T[0] ^ T[1] ^ T[2] ^ T[3];
+
+ Fewer bit_field_refs, only four for 128 or more bits vector. */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+int
+test (int accumulator, v4si v1, v4si v2, v4si v3, v4si v4)
+{
+ accumulator ^= v1[0] ^ v1[1] ^ v1[2] ^ v1[3];
+ accumulator ^= v2[0] ^ v2[1] ^ v2[2] ^ v2[3];
+ accumulator ^= v3[0] ^ v3[1] ^ v3[2] ^ v3[3];
+ accumulator ^= v4[0] ^ v4[1] ^ v4[2] ^ v4[3];
+ return accumulator;
+}
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 4 "reassoc1" { target { powerpc*-*-* i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88497-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-6.c
new file mode 100644
index 0000000..0146518
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-6.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target avx512f } */
+/* { dg-options "-O2 -mavx512f -ffast-math -fdump-tree-reassoc1" } */
+
+/* To test reassoc can undistribute vector bit_field_ref on multiple
+ vector machine modes.
+
+ v1, v2 of type vector 4 x float
+ v3, v4 of type vector 8 x float
+ v5, v6 of type vector 16 x float
+
+ reassoc transforms
+
+ accumulator += v1[0] + v1[1] + v1[2] + v1[3] +
+ v2[0] + v2[1] + v2[2] + v2[3] +
+ v3[0] + v3[1] + v3[2] + v3[3] +
+ v3[4] + v3[5] + v3[6] + v3[7] +
+ v4[0] + v4[1] + v4[2] + v4[3] +
+ v4[4] + v4[5] + v4[6] + v4[7] +
+ v5[0] + v5[1] + v5[2] + v5[3] +
+ v5[4] + v5[5] + v5[6] + v5[7] +
+ v5[8] + v5[9] + v5[10] + v5[11] +
+ v5[12] + v5[13] + v5[14] + v5[15] +
+ v6[0] + v6[1] + v6[2] + v6[3] +
+ v6[4] + v6[5] + v6[6] + v6[7] +
+ v6[8] + v6[9] + v6[10] + v6[11] +
+ v6[12] + v6[13] + v6[14] + v6[15] ;
+
+ into:
+
+ T12 = v1 + v2;
+ T34 = v3 + v4;
+ T56 = v5 + v6;
+ accumulator += T12[0] + T12[1] + T12[2] + T12[3] +
+ accumulator += T34[0] + T34[1] + T34[2] + T34[3] +
+ accumulator += T34[4] + T34[5] + T34[6] + T34[7] +
+ accumulator += T56[0] + T56[1] + T56[2] + T56[3] +
+ accumulator += T56[4] + T56[5] + T56[6] + T56[7] +
+ accumulator += T56[8] + T56[9] + T56[10] + T56[11] +
+ accumulator += T56[12] + T56[13] + T56[14] + T56[15] ; */
+
+typedef float v4sf __attribute__((vector_size(16)));
+typedef float v8sf __attribute__((vector_size(32)));
+typedef float v16sf __attribute__((vector_size(64)));
+
+float
+test (float accumulator, v4sf v1, v4sf v2, v8sf v3, v8sf v4, v16sf v5, v16sf v6)
+{
+ accumulator += v1[0] + v1[1] + v1[2] + v1[3];
+ accumulator += v2[0] + v2[1] + v2[2] + v2[3];
+ accumulator += v3[0] + v3[1] + v3[2] + v3[3];
+ accumulator += v3[4] + v3[5] + v3[6] + v3[7];
+ accumulator += v4[0] + v4[1] + v4[2] + v4[3];
+ accumulator += v4[4] + v4[5] + v4[6] + v4[7];
+ accumulator += v5[0] + v5[1] + v5[2] + v5[3];
+ accumulator += v5[4] + v5[5] + v5[6] + v5[7];
+ accumulator += v5[8] + v5[9] + v5[10] + v5[11];
+ accumulator += v5[12] + v5[13] + v5[14] + v5[15];
+ accumulator += v6[0] + v6[1] + v6[2] + v6[3];
+ accumulator += v6[4] + v6[5] + v6[6] + v6[7];
+ accumulator += v6[8] + v6[9] + v6[10] + v6[11];
+ accumulator += v6[12] + v6[13] + v6[14] + v6[15];
+ return accumulator;
+}
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 28 "reassoc1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88497-7.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-7.c
new file mode 100644
index 0000000..0445878
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88497-7.c
@@ -0,0 +1,77 @@
+/* { dg-do run } */
+/* { dg-require-effective-target avx512f_runtime } */
+/* { dg-options "-O2 -mavx512f -ffast-math -fdump-tree-reassoc1" } */
+
+/* To test reassoc can undistribute vector bit_field_ref on multiple
+ vector machine modes, bypass those modes with only one candidate.
+
+ v1, v2 of type vector 4 x float
+ v3 of type vector 8 x float
+ v5, v6 of type vector 16 x float
+
+ reassoc transforms
+
+ accumulator += v1[0] + v1[1] + v1[2] + v1[3] +
+ v2[0] + v2[1] + v2[2] + v2[3] +
+ v3[0] + v3[1] + v3[2] + v3[3] +
+ v3[4] + v3[5] + v3[6] + v3[7] +
+ v5[0] + v5[1] + v5[2] + v5[3] +
+ v5[4] + v5[5] + v5[6] + v5[7] +
+ v5[8] + v5[9] + v5[10] + v5[11] +
+ v5[12] + v5[13] + v5[14] + v5[15] +
+ v6[0] + v6[1] + v6[2] + v6[3] +
+ v6[4] + v6[5] + v6[6] + v6[7] +
+ v6[8] + v6[9] + v6[10] + v6[11] +
+ v6[12] + v6[13] + v6[14] + v6[15] ;
+
+ into:
+
+ T12 = v1 + v2;
+ T56 = v5 + v6;
+ accumulator += T12[0] + T12[1] + T12[2] + T12[3] +
+ accumulator += v3[0] + v3[1] + v3[2] + v3[3] +
+ accumulator += v3[4] + v3[5] + v3[6] + v3[7] +
+ accumulator += T56[0] + T56[1] + T56[2] + T56[3] +
+ accumulator += T56[4] + T56[5] + T56[6] + T56[7] +
+ accumulator += T56[8] + T56[9] + T56[10] + T56[11] +
+ accumulator += T56[12] + T56[13] + T56[14] + T56[15] ; */
+
+typedef float v4sf __attribute__((vector_size(16)));
+typedef float v8sf __attribute__((vector_size(32)));
+typedef float v16sf __attribute__((vector_size(64)));
+
+__attribute__ ((noinline))
+float test(float accumulator, v4sf v1, v4sf v2, v8sf v3, v16sf v5, v16sf v6) {
+ accumulator += v1[0] + v1[1] + v1[2] + v1[3];
+ accumulator += v2[0] + v2[1] + v2[2] + v2[3];
+ accumulator += v3[0] + v3[1] + v3[2] + v3[3];
+ accumulator += v3[4] + v3[5] + v3[6] + v3[7];
+ accumulator += v5[0] + v5[1] + v5[2] + v5[3];
+ accumulator += v5[4] + v5[5] + v5[6] + v5[7];
+ accumulator += v5[8] + v5[9] + v5[10] + v5[11];
+ accumulator += v5[12] + v5[13] + v5[14] + v5[15];
+ accumulator += v6[0] + v6[1] + v6[2] + v6[3];
+ accumulator += v6[4] + v6[5] + v6[6] + v6[7];
+ accumulator += v6[8] + v6[9] + v6[10] + v6[11];
+ accumulator += v6[12] + v6[13] + v6[14] + v6[15];
+ return accumulator;
+}
+
+extern void abort (void);
+
+int
+main ()
+{
+ v4sf v1 = {1.0, 2.0, 3.0, 4.0 };
+ v4sf v2 = {5.0, 6.0, 7.0, 8.0 };
+ v8sf v3 = {9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
+ v16sf v5 = {17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0};
+ v16sf v6 = {33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0};
+ float acc = 24.0;
+ double res = test (acc, v1, v2, v3, v5, v6);
+ if (res != 1200.0)
+ abort();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 28 "reassoc1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88775-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88775-2.c
index 292ce6e..ed5df82 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr88775-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88775-2.c
@@ -41,3 +41,5 @@ f5 (void)
int c[64] = {}, d[64] = {};
return (__UINTPTR_TYPE__) &c[64] != (__UINTPTR_TYPE__) &d[0];
}
+
+/* { dg-prune-output "-Wreturn-local-addr" } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
new file mode 100644
index 0000000..8ee1850
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+unsigned test(unsigned k, unsigned b) {
+ unsigned a[2];
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
new file mode 100644
index 0000000..9b96875
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int c;
+unsigned test(unsigned k, unsigned b) {
+ unsigned a[2];
+ a[k] = c;
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c
new file mode 100644
index 0000000..0fac9f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-3.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+unsigned a[2];
+unsigned test(unsigned k, unsigned b) {
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c
new file mode 100644
index 0000000..54b8c11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-4.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int *p;
+unsigned test(unsigned k, unsigned b) {
+ unsigned a[2];
+ p = a;
+ if (b < a[k]) {
+ a[k] = b;
+ }
+ return a[0]+a[1];
+}
+
+/* { dg-final { scan-tree-dump-not "Conditional store replacement" "cselim" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
new file mode 100644
index 0000000..b2d0411
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int test(int b, int k) {
+ struct {
+ int data[2];
+ } a;
+
+ if (b < a.data[k]) {
+ a.data[k] = b;
+ }
+
+ return a.data[0] + a.data[1];
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
new file mode 100644
index 0000000..8d3c4f7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-6.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cselim-details" } */
+
+int test(int b, int k) {
+ typedef struct {
+ int x;
+ } SS;
+ struct {
+ SS data[2];
+ } a;
+
+ if (b < a.data[k].x) {
+ a.data[k].x = b;
+ }
+
+ return a.data[0].x + a.data[1].x;
+}
+
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c
new file mode 100644
index 0000000..2ee75d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91091-1.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fno-strict-aliasing" } */
+
+struct s { int x; } __attribute__((packed));
+struct t { int x; };
+
+void __attribute__((noinline,noipa))
+swap(struct s* p, struct t* q)
+{
+ p->x = q->x;
+ q->x = p->x;
+}
+
+int main()
+{
+ struct t a[2];
+ a[0].x = 0x12345678;
+ a[1].x = 0x98765432;
+ swap ((struct s *)((char *)a + 1), a);
+ if (a[0].x != 0x12345678)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c
new file mode 100644
index 0000000..b578de7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+struct s { int x; };
+struct t { int x; };
+
+void swap(struct s* p, struct t* q)
+{
+ p->x = q->x;
+ q->x = p->x;
+}
+
+/* The second statement is redundant. */
+/* { dg-final { scan-tree-dump-times "x = " 1 "fre1" } } */
+/* { dg-final { scan-tree-dump-times " = \[^;\]*x;" 1 "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c
new file mode 100644
index 0000000..56251fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-37.c
@@ -0,0 +1,60 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */
+
+
+#ifndef SCOPE
+#define SCOPE
+#endif
+
+extern void frob (char *);
+
+void g (char *s)
+{
+ SCOPE char a[8];
+ __builtin_strncpy (a, s, sizeof a);
+ __builtin_memset (a, 0, sizeof a);
+ frob (a);
+}
+
+void h (char *s)
+{
+ SCOPE char a[8];
+ __builtin_memset (a, 0, sizeof a);
+ __builtin_strncpy (a, s, sizeof a);
+ frob (a);
+}
+
+void i (char *s)
+{
+ SCOPE char a[8];
+ __builtin_strncpy (a, s, sizeof a);
+ __builtin_memset (a, 0, sizeof a - 5);
+ frob (a);
+}
+
+void j (char *s)
+{
+ SCOPE char a[8];
+ __builtin_memset (a, 0, sizeof a);
+ __builtin_strncpy (a, s, sizeof a - 5);
+ frob (a);
+}
+
+void l (char *s)
+{
+ SCOPE char a[8];
+ __builtin_strncpy (a, s, sizeof a);
+ __builtin_memset (a + 2, 0, sizeof a - 2);
+ frob (a);
+}
+
+void m (char *s)
+{
+ SCOPE char a[8];
+ __builtin_memset (a, 0, sizeof a);
+ __builtin_strncpy (a + 2, s, sizeof a - 2);
+ frob (a);
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" } } */
+/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c
new file mode 100644
index 0000000..7ae33bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-38.c
@@ -0,0 +1,12 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */
+
+
+/* This changes the scope of the destination object and exposes
+ missed optimizations in DSE. */
+#define SCOPE extern
+#include "ssa-dse-37.c"
+
+/* { dg-final { scan-tree-dump-times "Deleted dead call" 2 "dse1" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Trimming statement " 4 "dse1" { xfail *-*-* } } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-70.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-70.c
new file mode 100644
index 0000000..612d753
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-70.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O -fdump-tree-fre1" } */
+
+__GIMPLE (ssa, startwith("fre")) char foo(char *p)
+{
+ char _1;
+
+__BB(2):
+ __MEM <char[4]> (p) = _Literal (char[4]) {};
+ _1 = __MEM <char> (p + 1);
+ return _1;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-71.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-71.c
new file mode 100644
index 0000000..edc8899
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-71.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O -fdump-tree-fre1-details" } */
+
+__GIMPLE (ssa, startwith("fre")) char foo(char *p)
+{
+ char _1;
+
+__BB(2):
+ __MEM <int> (p) = 0;
+ _1 = __MEM <char> (p + 1);
+ return _1;
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-72.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-72.c
new file mode 100644
index 0000000..b95709f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-72.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fgimple -O -fdump-tree-fre1" } */
+
+__GIMPLE (ssa,startwith("fre")) char foo(char *p, int i)
+{
+ char _1;
+
+__BB(2):
+ __MEM <int> (p) = i_2(D);
+ _1 = __MEM <char> (p + 1);
+ return _1;
+}
+
+/* { dg-final { scan-tree-dump "BIT_FIELD_REF" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-73.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-73.c
new file mode 100644
index 0000000..f138203
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-73.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+typedef int v2si __attribute__((vector_size(__SIZEOF_INT__ * 2)));
+int foo (int *a)
+{
+ a[0] = 1;
+ a[1] = 2;
+ v2si x = *(v2si *)a;
+ *(v2si *)&a[2] = x;
+ return a[3];
+}
+
+/* { dg-final { scan-tree-dump "return 2;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-74.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-74.c
new file mode 100644
index 0000000..4439d83
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-74.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(__SIZEOF_INT__ * 4)));
+int foo (int *a)
+{
+ a[2] = 2;
+ a[0] = 0;
+ a[1] = 1;
+ a[3] = 4;
+ v4si x = *(v4si *)a;
+ *(v4si *)&a[4] = x;
+ return a[4] + a[7];
+}
+
+/* { dg-final { scan-tree-dump "return 4;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-75.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-75.c
new file mode 100644
index 0000000..54bfe73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-75.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-options "-O -fgimple -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(__SIZEOF_INT__ * 4)));
+#if __SIZEOF_INT__ == 4
+__GIMPLE (ssa) int foo (int *a)
+{
+ v4si _2;
+ int _3;
+ int _4;
+ int _5;
+ int _6;
+ int _7;
+ int _8;
+ int _9;
+
+__BB(2):
+ __MEM <unsigned char[3 * __SIZEOF_INT__]> ((char *)a_1(D) + 4) = _Literal (unsigned char[3 * __SIZEOF_INT__]) {};
+ __MEM <int> (a_1(D) + 8) = 2;
+ __MEM <int> (a_1(D)) = 1;
+ _2 = __MEM <v4si> (a_1(D));
+ _3 = __BIT_FIELD_REF <int> (_2, 32, 0);
+ _4 = __BIT_FIELD_REF <int> (_2, 32, 32);
+ _5 = __BIT_FIELD_REF <int> (_2, 32, 64);
+ _6 = __BIT_FIELD_REF <int> (_2, 32, 96);
+ _7 = _3 + _4;
+ _8 = _7 + _5;
+ _9 = _8 + _6;
+ return _9;
+}
+#endif
+
+/* { dg-final { scan-tree-dump "return 3;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-76.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-76.c
new file mode 100644
index 0000000..7a1eede
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-76.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-fre1" } */
+
+typedef int v4si __attribute__((vector_size(__SIZEOF_INT__ * 4)));
+int foo (int *a)
+{
+ __builtin_memset (a, 0, 2 * __SIZEOF_INT__);
+ a[2] = 2;
+ a[0] = 1;
+ a[3] = 3;
+ v4si x = *(v4si *)a;
+ *(v4si *)&a[4] = x;
+ return a[4] + a[5] + a[7];
+}
+
+/* { dg-final { scan-tree-dump "return 4;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c
new file mode 100644
index 0000000..115f277
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+int foo (int *p, int *q)
+{
+ int x;
+ *p = 1;
+ x = *p;
+ *q = x;
+ return *p;
+}
+
+/* { dg-final { scan-tree-dump "return 1;" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c
new file mode 100644
index 0000000..4ad232e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-78.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fstrict-aliasing" } */
+
+union U {
+ struct A { int : 2; int x : 8; } a;
+ struct B { int : 6; int x : 8; } b;
+};
+
+int __attribute__((noipa))
+foo (union U *p, union U *q)
+{
+ p->a.x = 1;
+ q->b.x = 1;
+ return p->a.x;
+}
+
+int
+main()
+{
+ union U x;
+ if (foo (&x, &x) != x.a.x)
+ __builtin_abort ();
+ return 0;
+}
+
+/* We support arbitrary punning through unions when it happens through
+ the union type and thus p == q is valid here. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-79.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-79.c
new file mode 100644
index 0000000..83aef9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-79.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "-O -fgimple -fdump-tree-fre1" } */
+
+struct S { char a[4]; };
+const struct S cs = { 1, 2, 3, 4 };
+
+int __GIMPLE(ssa,startwith("fre"))
+main ()
+{
+ struct S s;
+ short _1;
+
+ __BB(2):
+ s = cs;
+ s.a[1] = _Literal (char) 3;
+ _1 = __MEM <short, 1> (&s + 1);
+ if (_1 != _Literal (short) 0x303)
+ goto __BB3;
+ else
+ goto __BB4;
+
+ __BB(3):
+ __builtin_abort ();
+
+ __BB(4):
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-7.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-7.c
new file mode 100644
index 0000000..b8ad684
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-7.c
@@ -0,0 +1,39 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
+
+typedef __INT8_TYPE__ v16qi __attribute__((vector_size(16),may_alias,aligned(1)));
+typedef __INT32_TYPE__ v4si __attribute__((vector_size(16),may_alias,aligned(1)));
+
+const __INT32_TYPE__ x[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+const __INT8_TYPE__ y[32]
+ = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
+const __INT32_TYPE__ z[8] = { [3] = 3, [1] = 1 };
+
+int
+main()
+{
+ v4si v1 = *(v4si *)(x + 1);
+ for (unsigned i = 0; i < 4; ++i)
+ if (v1[i] != (v4si) { 2, 3, 4, 5 }[i])
+ __builtin_abort ();
+ v4si v2 = *(v4si *)z;
+ for (unsigned i = 0; i < 4; ++i)
+ if (v2[i] != (v4si) { 0, 1, 0, 3 }[i])
+ __builtin_abort ();
+ v4si v3 = *(v4si *)(y + 1);
+ for (unsigned i = 0; i < 4; ++i)
+ if (v3[i] !=
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ (v4si) { 0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10 }[i]
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ (v4si) { 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d }[i]
+#else
+ v3[i]
+#endif
+ )
+ __builtin_abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr91114.c b/gcc/testsuite/gcc.dg/vect/pr91114.c
new file mode 100644
index 0000000..3343d1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr91114.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fopenmp-simd" } */
+
+void
+ne (double *zu)
+{
+ int h3;
+
+#pragma omp simd simdlen (4)
+ for (h3 = 0; h3 < 4; ++h3)
+ zu[h3] = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-sad.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-sad.c
index 15b286a..faa1c16 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-sad.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-sad.c
@@ -2,7 +2,6 @@
#include "tree-vect.h"
-typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-10.c b/gcc/testsuite/gcc.dg/vect/vect-simd-10.c
index d442d6b..e49566a 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-simd-10.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-10.c
@@ -7,6 +7,12 @@
#include "tree-vect.h"
#endif
+#ifdef __FAST_MATH__
+#define FLT_MIN_VALUE (-__FLT_MAX__)
+#else
+#define FLT_MIN_VALUE (-__builtin_inff ())
+#endif
+
float r = 1.0f, a[1024], b[1024];
__attribute__((noipa)) void
@@ -24,7 +30,7 @@ foo (float *a, float *b)
__attribute__((noipa)) float
bar (void)
{
- float s = -__builtin_inff ();
+ float s = FLT_MIN_VALUE;
#pragma omp simd reduction (inscan, max:s)
for (int i = 0; i < 1024; i++)
{
@@ -84,7 +90,7 @@ main ()
}
if (bar () != 592.0f)
abort ();
- s = -__builtin_inff ();
+ s = FLT_MIN_VALUE;
for (int i = 0; i < 1024; ++i)
{
if (s < a[i])
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-14.c b/gcc/testsuite/gcc.dg/vect/vect-simd-14.c
index 43663bb..9e73792 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-simd-14.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-14.c
@@ -7,6 +7,12 @@
#include "tree-vect.h"
#endif
+#ifdef __FAST_MATH__
+#define FLT_MIN_VALUE (-__FLT_MAX__)
+#else
+#define FLT_MIN_VALUE (-__builtin_inff ())
+#endif
+
float r = 1.0f, a[1024], b[1024];
__attribute__((noipa)) void
@@ -24,7 +30,7 @@ foo (float *a, float *b)
__attribute__((noipa)) float
bar (void)
{
- float s = -__builtin_inff ();
+ float s = FLT_MIN_VALUE;
#pragma omp simd reduction (inscan, max:s)
for (int i = 0; i < 1024; i++)
{
@@ -82,7 +88,7 @@ main ()
}
if (bar () != 592.0f)
abort ();
- s = -__builtin_inff ();
+ s = FLT_MIN_VALUE;
for (int i = 0; i < 1024; ++i)
{
if (b[i] != s)
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-16.c b/gcc/testsuite/gcc.dg/vect/vect-simd-16.c
new file mode 100644
index 0000000..ee4459a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-16.c
@@ -0,0 +1,61 @@
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[1-3] loops" 3 "vect" { target i?86-*-* x86_64-*-* } } } */
+
+#include "tree-vect.h"
+
+__attribute__((noipa)) int
+foo (int *a)
+{
+ int i;
+ #pragma omp simd lastprivate (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ return i;
+}
+
+__attribute__((noipa)) void
+bar (int *a)
+{
+ int i;
+ #pragma omp simd private (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i + 1;
+}
+
+__attribute__((noipa)) int
+baz (int *a)
+{
+ int i;
+ #pragma omp simd linear (i)
+ for (i = 0; i < 64; i++)
+ a[i] = i + 2;
+ return i;
+}
+
+int
+main ()
+{
+ int i;
+ int a[64];
+ check_vect ();
+ if (foo (a) != 64)
+ abort ();
+ for (i = 0; i < 64; ++i)
+ if (a[i] != i)
+ abort ();
+ else
+ a[i] = -8;
+ bar (a);
+ for (i = 0; i < 64; ++i)
+ if (a[i] != i + 1)
+ abort ();
+ else
+ a[i] = -8;
+ if (baz (a) != 64)
+ abort ();
+ for (i = 0; i < 64; ++i)
+ if (a[i] != i + 2)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/winline-7.c b/gcc/testsuite/gcc.dg/winline-7.c
index 34deca4..239d748 100644
--- a/gcc/testsuite/gcc.dg/winline-7.c
+++ b/gcc/testsuite/gcc.dg/winline-7.c
@@ -13,3 +13,5 @@ inline void *t (void)
{
return q (); /* { dg-message "called from here" } */
}
+
+/* { dg-prune-output "-Wreturn-local-addr" } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crypto-fuse-1.c b/gcc/testsuite/gcc.target/aarch64/aes-fuse-1.c
index d8adc89..d7b4f89 100644
--- a/gcc/testsuite/gcc.target/aarch64/crypto-fuse-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/aes-fuse-1.c
@@ -1,45 +1,66 @@
/* { dg-do compile } */
/* { dg-options "-O3 -mcpu=cortex-a72+crypto -dp" } */
+/* { dg-additional-options "-march=armv8-a+crypto" { target { aarch64*-*-* } } }*/
#include <arm_neon.h>
#define AESE(r, v, key) (r = vaeseq_u8 ((v), (key)));
#define AESMC(r, i) (r = vaesmcq_u8 (i))
+const uint8x16_t zero = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
uint8x16_t dummy;
uint8x16_t a;
uint8x16_t b;
uint8x16_t c;
uint8x16_t d;
-uint8x16_t e;
+uint8x16_t x;
+uint8x16_t y;
+uint8x16_t k;
+
+void foo (void)
-void
-foo (void)
{
- AESE (a, a, e);
+ AESE (a, a, k);
dummy = vaddq_u8 (dummy, dummy);
dummy = vaddq_u8 (dummy, dummy);
- AESE (b, b, e);
+ AESE (b, b, k);
dummy = vaddq_u8 (dummy, dummy);
dummy = vaddq_u8 (dummy, dummy);
- AESE (c, c, e);
+ AESE (c, c, k);
dummy = vaddq_u8 (dummy, dummy);
dummy = vaddq_u8 (dummy, dummy);
- AESE (d, d, e);
+ AESE (d, d, k);
dummy = vaddq_u8 (dummy, dummy);
dummy = vaddq_u8 (dummy, dummy);
- AESMC (a, a);
+ x = x ^ k;
+ AESE (x, x, zero);
dummy = vaddq_u8 (dummy, dummy);
dummy = vaddq_u8 (dummy, dummy);
- AESMC (b, b);
+ y = y ^ k;
+ AESE (y, y, zero);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ AESMC (d, d);
dummy = vaddq_u8 (dummy, dummy);
dummy = vaddq_u8 (dummy, dummy);
AESMC (c, c);
dummy = vaddq_u8 (dummy, dummy);
dummy = vaddq_u8 (dummy, dummy);
- AESMC (d, d);
-}
+ AESMC (b, b);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESMC (a, a);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
-/* { dg-final { scan-assembler-times "crypto_aese_fused" 4 } } */
+ AESMC (y, y);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESMC (x, x);
+}
+/* { dg-final { scan-assembler-times "crypto_aese_fused" 6 } } */
+/* { dg-final { scan-assembler-not "veor" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/aes-fuse-2.c b/gcc/testsuite/gcc.target/aarch64/aes-fuse-2.c
new file mode 100644
index 0000000..dfe01b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/aes-fuse-2.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mcpu=cortex-a72+crypto -dp" } */
+/* { dg-additional-options "-march=armv8-a+crypto" { target { aarch64*-*-* } } }*/
+
+#include <arm_neon.h>
+
+#define AESD(r, v, key) (r = vaesdq_u8 ((v), (key)));
+#define AESIMC(r, i) (r = vaesimcq_u8 (i))
+
+const uint8x16_t zero = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+uint8x16_t dummy;
+uint8x16_t a;
+uint8x16_t b;
+uint8x16_t c;
+uint8x16_t d;
+uint8x16_t x;
+uint8x16_t y;
+uint8x16_t k;
+
+void foo (void)
+{
+ AESD (a, a, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESD (b, b, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESD (c, c, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESD (d, d, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ x = x ^ k;
+ AESD (x, x, zero);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ y = y ^ k;
+ AESD (y, y, zero);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ AESIMC (d, d);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (c, c);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (b, b);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (a, a);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ AESIMC (y, y);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (x, x);
+}
+
+/* { dg-final { scan-assembler-times "crypto_aesd_fused" 6 } } */
+/* { dg-final { scan-assembler-not "veor" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/crypto-fuse-2.c b/gcc/testsuite/gcc.target/aarch64/crypto-fuse-2.c
deleted file mode 100644
index b12df2d..0000000
--- a/gcc/testsuite/gcc.target/aarch64/crypto-fuse-2.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O3 -mcpu=cortex-a72+crypto -dp" } */
-
-#include <arm_neon.h>
-
-#define AESE(r, v, key) (r = vaesdq_u8 ((v), (key)));
-#define AESMC(r, i) (r = vaesimcq_u8 (i))
-
-uint8x16_t dummy;
-uint8x16_t a;
-uint8x16_t b;
-uint8x16_t c;
-uint8x16_t d;
-uint8x16_t e;
-
-void
-foo (void)
-{
- AESE (a, a, e);
- dummy = vaddq_u8 (dummy, dummy);
- dummy = vaddq_u8 (dummy, dummy);
- AESE (b, b, e);
- dummy = vaddq_u8 (dummy, dummy);
- dummy = vaddq_u8 (dummy, dummy);
- AESE (c, c, e);
- dummy = vaddq_u8 (dummy, dummy);
- dummy = vaddq_u8 (dummy, dummy);
- AESE (d, d, e);
- dummy = vaddq_u8 (dummy, dummy);
- dummy = vaddq_u8 (dummy, dummy);
-
- AESMC (a, a);
- dummy = vaddq_u8 (dummy, dummy);
- dummy = vaddq_u8 (dummy, dummy);
- AESMC (b, b);
- dummy = vaddq_u8 (dummy, dummy);
- dummy = vaddq_u8 (dummy, dummy);
- AESMC (c, c);
- dummy = vaddq_u8 (dummy, dummy);
- dummy = vaddq_u8 (dummy, dummy);
- AESMC (d, d);
-}
-
-/* { dg-final { scan-assembler-times "crypto_aesd_fused" 4 } } */
-
diff --git a/gcc/testsuite/gcc.target/aarch64/pr91102.c b/gcc/testsuite/gcc.target/aarch64/pr91102.c
new file mode 100644
index 0000000..70b9904
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr91102.c
@@ -0,0 +1,26 @@
+/* PR target/91102 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (long d, long l)
+{
+ register long e asm ("x1") = d;
+ register long f asm("x2") = l;
+ asm ("" : : "r" (e), "r" (f));
+ return 3;
+}
+
+struct T { int i; int j; };
+union S { long h; struct T t; };
+
+void
+bar (union S b)
+{
+ while (1)
+ {
+ union S c = b;
+ c.t.j++;
+ b.h = foo (b.h, c.h);
+ }
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/ssra.c b/gcc/testsuite/gcc.target/aarch64/simd/ssra.c
new file mode 100644
index 0000000..e9c2e04
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/ssra.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-O3" } */
+/* { dg-skip-if "" { *-*-* } {"*sve*"} {""} } */
+
+#include <stdint.h>
+
+#define SSRA(func, vtype, n) \
+ void func () \
+ { \
+ int i; \
+ for (i = 0; i < n; i++) \
+ { \
+ s1##vtype[i] += s2##vtype[i] >> 2; \
+ } \
+ }
+
+#define TEST_VDQ_I_MODES(FUNC) \
+ FUNC (test_v8qi_v16qi, _char, 16) \
+ FUNC (test_v4hi_v8h1, _short, 8) \
+ FUNC (test_v2si_v4si, _int, 4) \
+ FUNC (test_v2di, _ll, 2) \
+
+int8_t s1_char[16], s2_char[16];
+int16_t s1_short[8], s2_short[8];
+int32_t s1_int[4], s2_int[4];
+int64_t s1_ll[2], s2_ll[2];
+
+TEST_VDQ_I_MODES(SSRA)
+
+/* { dg-final { scan-assembler "ssra" } } */
+/* { dg-final { scan-assembler-not "sshr" } } */
+
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.16b, v[0-9]+\.16b, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.8h, v[0-9]+\.8h, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.4s, v[0-9]+\.4s, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {ssra\tv[0-9]+\.2d, v[0-9]+\.2d, [0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/usra.c b/gcc/testsuite/gcc.target/aarch64/simd/usra.c
new file mode 100644
index 0000000..4e7446d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/usra.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-O3" } */
+/* { dg-skip-if "" { *-*-* } {"*sve*"} {""} } */
+
+#include <stdint.h>
+
+#define USRA(func, vtype, n) \
+ void func () \
+ { \
+ int i; \
+ for (i = 0; i < n; i++) \
+ { \
+ u1##vtype[i] += u2##vtype[i] >> 2; \
+ } \
+ }
+
+#define TEST_VDQ_I_MODES(FUNC) \
+ FUNC (test_v8qi_v16qi, _char, 16) \
+ FUNC (test_v4hi_v8h1, _short, 8) \
+ FUNC (test_v2si_v4si, _int, 4) \
+ FUNC (test_v2di, _ll, 2) \
+
+uint8_t u1_char[16], u2_char[16];
+uint16_t u1_short[8], u2_short[8];
+uint32_t u1_int[4], u2_int[4];
+uint64_t u1_ll[2], u2_ll[2];
+
+TEST_VDQ_I_MODES(USRA)
+
+/* { dg-final { scan-assembler "usra" } } */
+/* { dg-final { scan-assembler-not "ushr" } } */
+
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.16b, v[0-9]+\.16b, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.8h, v[0-9]+\.8h, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.4s, v[0-9]+\.4s, [0-9]+} 1 } } */
+/* { dg-final { scan-assembler-times {usra\tv[0-9]+\.2d, v[0-9]+\.2d, [0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/arc/tls-2.c b/gcc/testsuite/gcc.target/arc/tls-2.c
new file mode 100644
index 0000000..3cec309
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/tls-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls } */
+/* { dg-skip-if "" { arc*-*-elf* } } */
+/* { dg-options "-O2" } */
+
+typedef int type_a;
+__thread int b;
+int c;
+
+extern int bar (char *, int, int *, int, int *, char, type_a, int *, int *);
+int foo (int *f, char buffer, type_a buflen, int *g)
+{
+ bar("", c, (int *)foo, 1, (int *)f, buffer, buflen, (int *)g, &b);
+}
diff --git a/gcc/testsuite/gcc.target/arc/tls-3.c b/gcc/testsuite/gcc.target/arc/tls-3.c
new file mode 100644
index 0000000..e78b5a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/tls-3.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target tls } */
+/* { dg-skip-if "" { arc*-*-elf* } } */
+/* { dg-options "-Os -fPIC" } */
+
+
+typedef struct
+{
+ int(a);
+ char b[];
+} type_c;
+
+
+extern int bar (char *, int, char *);
+static _Thread_local type_c d;
+int foo(void)
+{
+ bar(d.b, 0, d.b);
+}
diff --git a/gcc/testsuite/gcc.target/arm/aes-fuse-1.c b/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
new file mode 100644
index 0000000..27b08ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aes-fuse-1.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_crypto_ok } */
+/* { dg-add-options arm_crypto } */
+/* { dg-additional-options "-mcpu=cortex-a72 -O3 -dp" } */
+
+#include <arm_neon.h>
+
+#define AESE(r, v, key) (r = vaeseq_u8 ((v), (key)));
+#define AESMC(r, i) (r = vaesmcq_u8 (i))
+
+const uint8x16_t zero = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+uint8x16_t dummy;
+uint8x16_t a;
+uint8x16_t b;
+uint8x16_t c;
+uint8x16_t d;
+uint8x16_t x;
+uint8x16_t y;
+uint8x16_t k;
+
+void foo (void)
+{
+ AESE (a, a, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESE (b, b, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESE (c, c, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESE (d, d, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ x = x ^ k;
+ AESE (x, x, zero);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ y = y ^ k;
+ AESE (y, y, zero);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ AESMC (d, d);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESMC (c, c);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESMC (b, b);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESMC (a, a);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ AESMC (y, y);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESMC (x, x);
+}
+
+/* { dg-final { scan-assembler-times "crypto_aese_fused" 6 } } */
+/* { dg-final { scan-assembler-not "veor" } } */
diff --git a/gcc/testsuite/gcc.target/arm/aes-fuse-2.c b/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
new file mode 100644
index 0000000..1266a28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aes-fuse-2.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_crypto_ok } */
+/* { dg-add-options arm_crypto } */
+/* { dg-additional-options "-mcpu=cortex-a72 -O3 -dp" } */
+
+#include <arm_neon.h>
+
+#define AESD(r, v, key) (r = vaesdq_u8 ((v), (key)));
+#define AESIMC(r, i) (r = vaesimcq_u8 (i))
+
+const uint8x16_t zero = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+uint8x16_t dummy;
+uint8x16_t a;
+uint8x16_t b;
+uint8x16_t c;
+uint8x16_t d;
+uint8x16_t x;
+uint8x16_t y;
+uint8x16_t k;
+
+void foo (void)
+{
+ AESD (a, a, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESD (b, b, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESD (c, c, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESD (d, d, k);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ x = x ^ k;
+ AESD (x, x, zero);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ y = y ^ k;
+ AESD (y, y, zero);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ AESIMC (d, d);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (c, c);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (b, b);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (a, a);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+
+ AESIMC (y, y);
+ dummy = vaddq_u8 (dummy, dummy);
+ dummy = vaddq_u8 (dummy, dummy);
+ AESIMC (x, x);
+}
+
+/* { dg-final { scan-assembler-times "crypto_aesd_fused" 6 } } */
+/* { dg-final { scan-assembler-not "veor" } } */
diff --git a/gcc/testsuite/gcc.target/arm/aes_xor_combine.c b/gcc/testsuite/gcc.target/arm/aes_xor_combine.c
new file mode 100644
index 0000000..17ae1c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aes_xor_combine.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_crypto_ok } */
+/* { dg-add-options arm_crypto } */
+/* { dg-additional-options "-O3" } */
+
+#include <arm_neon.h>
+
+#define AESE(r, v, key) (r = vaeseq_u8 ((v), (key)));
+#define AESD(r, v, key) (r = vaesdq_u8 ((v), (key)));
+
+const uint8x16_t zero = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+uint8x16_t foo_key_0 (uint8x16_t dummy, uint8x16_t foo, uint8x16_t bar)
+{
+ dummy = dummy ^ foo;
+ AESE(dummy, dummy, zero);
+ dummy = dummy ^ bar;
+ AESE(dummy, dummy, zero);
+
+ dummy = dummy ^ foo;
+ AESD(dummy, dummy, zero);
+ dummy = dummy ^ bar;
+ AESD(dummy, dummy, zero);
+
+ return dummy;
+}
+
+uint8x16_t foo_data_0 (uint8x16_t dummy, uint8x16_t foo, uint8x16_t bar)
+{
+ dummy = dummy ^ foo;
+ AESE(dummy, zero, dummy);
+ dummy = dummy ^ bar;
+ AESE(dummy, zero, dummy);
+
+ dummy = dummy ^ foo;
+ AESD(dummy, zero, dummy);
+ dummy = dummy ^ bar;
+ AESD(dummy, zero, dummy);
+
+ return dummy;
+}
+
+/* { dg-final { scan-assembler-not "veor" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
index fccc51d..0fc191e 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-1.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x20400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
index e6aee3c..f8327c8 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-2.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x20400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
index 285a2b9..d0550db 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/bitfield-3.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x20400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/cmse/struct-1.c b/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
index 2d366a9..874da3c 100644
--- a/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
+++ b/gcc/testsuite/gcc.target/arm/cmse/struct-1.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x20400000" } */
+/* { dg-options "--save-temps -mcmse -Wl,--section-start,.gnu.sgstubs=0x00400000" } */
typedef struct
{
diff --git a/gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c b/gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c
index 4dc9dee..41f97a7 100644
--- a/gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/crypto-vsha1cq_u32.c
@@ -1,11 +1,12 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_crypto_ok } */
/* { dg-add-options arm_crypto } */
+/* { dg-additional-options "-O3" } */
#include "arm_neon.h"
-int
-foo (void)
+uint32_t foo (void)
+
{
uint32_t hash = 0xdeadbeef;
uint32x4_t a = {0, 1, 2, 3};
@@ -15,4 +16,20 @@ foo (void)
return res[0];
}
-/* { dg-final { scan-assembler "sha1c.32\tq\[0-9\]+, q\[0-9\]+" } } */
+#define GET_LANE(lane) \
+ uint32x4_t foo_lane##lane (uint32x4_t val,uint32x4_t a, uint32x4_t b)\
+ { \
+ return vsha1cq_u32 (a, vgetq_lane_u32 (val, lane), b); \
+ }
+
+#define TEST_SHA1C_VEC_SELECT(FUNC) \
+ FUNC (0) \
+ FUNC (1) \
+ FUNC (2) \
+ FUNC (3) \
+
+TEST_SHA1C_VEC_SELECT (GET_LANE)
+
+/* { dg-final { scan-assembler-times {sha1c.32\tq[0-9]+, q[0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {vdup.32\tq[0-9]+, r[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vmov.32\tr[0-9]+, d[0-9]+\[[0-9]+\]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c b/gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c
index dee2774..b284667 100644
--- a/gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c
+++ b/gcc/testsuite/gcc.target/arm/crypto-vsha1h_u32.c
@@ -1,14 +1,31 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_crypto_ok } */
/* { dg-add-options arm_crypto } */
+/* { dg-additional-options "-O3" } */
#include "arm_neon.h"
-int
-foo (void)
+uint32_t foo (void)
+
{
uint32_t val = 0xdeadbeef;
return vsha1h_u32 (val);
}
-/* { dg-final { scan-assembler "sha1h.32\tq\[0-9\]+, q\[0-9\]+" } } */
+#define GET_LANE(lane) \
+ uint32_t foo_lane##lane (uint32x4_t val) \
+ { \
+ return vsha1h_u32 (vgetq_lane_u32 (val, lane)); \
+ }
+
+#define TEST_SHA1H_VEC_SELECT(FUNC) \
+ FUNC (0) \
+ FUNC (1) \
+ FUNC (2) \
+ FUNC (3) \
+
+TEST_SHA1H_VEC_SELECT (GET_LANE)
+
+/* { dg-final { scan-assembler-times {sha1h.32\tq[0-9]+, q[0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {vdup.32\tq[0-9]+, r[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vmov.32\tr[0-9]+, d[0-9]+\[[0-9]+\]+} 8 } } */
diff --git a/gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c b/gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c
index 672b93a..676e64c 100644
--- a/gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/crypto-vsha1mq_u32.c
@@ -1,11 +1,12 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_crypto_ok } */
/* { dg-add-options arm_crypto } */
+/* { dg-additional-options "-O3" } */
#include "arm_neon.h"
-int
-foo (void)
+uint32_t foo (void)
+
{
uint32_t hash = 0xdeadbeef;
uint32x4_t a = {0, 1, 2, 3};
@@ -15,4 +16,20 @@ foo (void)
return res[0];
}
-/* { dg-final { scan-assembler "sha1m.32\tq\[0-9\]+, q\[0-9\]+" } } */
+#define GET_LANE(lane) \
+ uint32x4_t foo_lane##lane (uint32x4_t val,uint32x4_t a, uint32x4_t b)\
+ { \
+ return vsha1mq_u32 (a, vgetq_lane_u32 (val, lane), b); \
+ }
+
+#define TEST_SHA1M_VEC_SELECT(FUNC) \
+ FUNC (0) \
+ FUNC (1) \
+ FUNC (2) \
+ FUNC (3) \
+
+TEST_SHA1M_VEC_SELECT (GET_LANE)
+
+/* { dg-final { scan-assembler-times {sha1m.32\tq[0-9]+, q[0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {vdup.32\tq[0-9]+, r[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vmov.32\tr[0-9]+, d[0-9]+\[[0-9]+\]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c b/gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c
index ff508e0..ed10fe2 100644
--- a/gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c
+++ b/gcc/testsuite/gcc.target/arm/crypto-vsha1pq_u32.c
@@ -1,11 +1,12 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_crypto_ok } */
/* { dg-add-options arm_crypto } */
+/* { dg-additional-options "-O3" } */
#include "arm_neon.h"
-int
-foo (void)
+uint32_t foo (void)
+
{
uint32_t hash = 0xdeadbeef;
uint32x4_t a = {0, 1, 2, 3};
@@ -15,4 +16,20 @@ foo (void)
return res[0];
}
-/* { dg-final { scan-assembler "sha1p.32\tq\[0-9\]+, q\[0-9\]+" } } */
+#define GET_LANE(lane) \
+ uint32x4_t foo_lane##lane (uint32x4_t val,uint32x4_t a, uint32x4_t b)\
+ { \
+ return vsha1pq_u32 (a, vgetq_lane_u32 (val, lane), b); \
+ }
+
+#define TEST_SHA1P_VEC_SELECT(FUNC) \
+ FUNC (0) \
+ FUNC (1) \
+ FUNC (2) \
+ FUNC (3) \
+
+TEST_SHA1P_VEC_SELECT (GET_LANE)
+
+/* { dg-final { scan-assembler-times {sha1p.32\tq[0-9]+, q[0-9]+} 5 } } */
+/* { dg-final { scan-assembler-times {vdup.32\tq[0-9]+, r[0-9]+} 3 } } */
+/* { dg-final { scan-assembler-times {vmov.32\tr[0-9]+, d[0-9]+\[[0-9]+\]+} 4 } } */
diff --git a/gcc/testsuite/gcc.target/arm/pr89190.c b/gcc/testsuite/gcc.target/arm/pr89190.c
new file mode 100644
index 0000000..e622d70
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr89190.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8m_base_ok } */
+/* { dg-options "-O2" } */
+/* { dg-add-options arm_arch_v8m_base } */
+
+long long a;
+int b, c;
+int d(int e, int f) { return e << f; }
+void g() {
+ long long h;
+ char i = d(b >= 7, 2);
+ c = i == 0 ?: 1 / i;
+ h = c && a ?: c + a;
+ b = h;
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c
new file mode 100644
index 0000000..602d922
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c
@@ -0,0 +1,6 @@
+/* PR tree-optimization/91157 */
+/* { dg-do run { target { avx512bw && lp64 } } } */
+/* { dg-options "-O2 -mavx512bw -fexceptions -fnon-call-exceptions -fsignaling-nans" } */
+
+#define AVX512BW
+#include "avx512f-pr91157.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr91157.c b/gcc/testsuite/gcc.target/i386/avx512f-pr91157.c
new file mode 100644
index 0000000..c7d0d8b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-pr91157.c
@@ -0,0 +1,29 @@
+/* PR tree-optimization/91157 */
+/* { dg-do run { target { avx512f && lp64 } } } */
+/* { dg-options "-O2 -mavx512f -fexceptions -fnon-call-exceptions -fsignaling-nans" } */
+
+#include "avx512f-helper.h"
+
+typedef long double V __attribute__ ((vector_size (4 * sizeof (long double))));
+typedef __int128 W __attribute__ ((vector_size (4 * sizeof (__int128))));
+
+__attribute__((noipa)) W
+foo (V x)
+{
+ return x == 0;
+}
+
+static void
+test_512 (void)
+{
+ V a = { 5.0L, 0.0L, -0.0L, -17.0L };
+ V b = { -0.0L, 16.0L, 0.0L, 18.0L };
+ V c = { 6.0L, 7.0L, 8.0L, 0.0L };
+ W ar = foo (a);
+ W br = foo (b);
+ W cr = foo (c);
+ if (ar[0] != 0 || ar[1] != -1 || ar[2] != -1 || ar[3] != 0
+ || br[0] != -1 || br[1] != 0 || br[2] != -1 || br[3] != 0
+ || cr[0] != 0 || cr[1] != 0 || cr[2] != 0 || cr[3] != -1)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr90980-1.c b/gcc/testsuite/gcc.target/i386/pr90980-1.c
new file mode 100644
index 0000000..72a30dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90980-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=skylake-avx512 -O2" } */
+/* { dg-final { scan-assembler-times "(?:vmovups|vmovdqu)\[ \\t\]+\[^\{\n\]*%xmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 2 } } */
+
+#include <immintrin.h>
+
+int *a;
+long long *b;
+volatile __m128i xx;
+volatile __m128i xx1;
+
+void extern
+avx512vl_test (void)
+{
+ _mm_storeu_epi32 (a, xx);
+ _mm_storeu_epi64 (b, xx1);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr90980-2.c b/gcc/testsuite/gcc.target/i386/pr90980-2.c
new file mode 100644
index 0000000..b1980e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90980-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-march=skylake-avx512 -O2" } */
+/* { dg-final { scan-assembler-times "vmovdqu\[0-9\]*\[ \\t\]+\[^\{\n\]*%ymm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 2 } } */
+
+#include <immintrin.h>
+
+int *a;
+long long *b;
+volatile __m256i yy;
+volatile __m256i yy1;
+
+void extern
+avx512vl_test (void)
+{
+ _mm256_storeu_epi32 (a, yy);
+ _mm256_storeu_epi64 (b, yy1);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr90980-3.c b/gcc/testsuite/gcc.target/i386/pr90980-3.c
new file mode 100644
index 0000000..d839ee0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90980-3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=skylake-avx512 -O2" } */
+/* { dg-final { scan-assembler-times "vmovdqu64\[ \\t\]+\[^\{\n\]*\\)\[^\n\]*%zmm\[0-9\]+(?:\n|\[ \\t\]+#)" 2 } } */
+/* { dg-final { scan-assembler-times "vmovdqu64\[ \\t\]+\[^\{\n\]*%zmm\[0-9\]+\[^\n\]*\\)(?:\n|\[ \\t\]+#)" 2 } } */
+
+#include <immintrin.h>
+
+int *a;
+long long *b;
+volatile __m512i zz;
+volatile __m512i zz1;
+
+void extern
+avx512f_test (void)
+{
+ zz = _mm512_loadu_epi32 (a);
+ _mm512_storeu_epi32 (a, zz);
+ zz1 = _mm512_loadu_epi64 (b);
+ _mm512_storeu_epi64 (b, zz1);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr91131.c b/gcc/testsuite/gcc.target/i386/pr91131.c
new file mode 100644
index 0000000..85008ff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91131.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+struct Reg_T {
+ unsigned int a : 3;
+ unsigned int b : 1;
+ unsigned int c : 4;
+};
+
+volatile struct Reg_T Reg_A;
+
+int
+main ()
+{
+ Reg_A = (struct Reg_T){ .a = 0, .b = 0, .c = 0 };
+ return 0;
+}
+
+/* { dg-final { scan-assembler-times "mov\[^\r\n\]*Reg_A" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr91188-1a.c b/gcc/testsuite/gcc.target/i386/pr91188-1a.c
new file mode 100644
index 0000000..8673c2a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91188-1a.c
@@ -0,0 +1,63 @@
+/* PR target/91188 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+/* { dg-final { scan-assembler-not "movb" } } */
+
+struct S
+{
+ unsigned char val;
+ unsigned char pad1;
+ unsigned short pad2;
+};
+
+struct S
+test_and (struct S a, unsigned char b)
+{
+ a.val &= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andb" } } */
+
+struct S
+test_or (struct S a, unsigned char b)
+{
+ a.val |= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orb" } } */
+
+struct S
+test_xor (struct S a, unsigned char b)
+{
+ a.val ^= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorb" } } */
+
+struct S
+test_add (struct S a, unsigned char b)
+{
+ a.val += b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addb" } } */
+
+struct S
+test_sub (struct S a, unsigned char b)
+{
+ a.val -= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]subb" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr91188-1b.c b/gcc/testsuite/gcc.target/i386/pr91188-1b.c
new file mode 100644
index 0000000..9294911
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91188-1b.c
@@ -0,0 +1,65 @@
+/* PR target/91188 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+/* { dg-final { scan-assembler-not "movb" } } */
+
+struct S
+{
+ unsigned char val;
+ unsigned char pad1;
+ unsigned short pad2;
+};
+
+unsigned char b;
+
+struct S
+test_and (struct S a)
+{
+ a.val &= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andb" } } */
+
+struct S
+test_or (struct S a)
+{
+ a.val |= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orb" } } */
+
+struct S
+test_xor (struct S a)
+{
+ a.val ^= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorb" } } */
+
+struct S
+test_add (struct S a)
+{
+ a.val += b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addb" } } */
+
+struct S
+test_sub (struct S a)
+{
+ a.val -= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]subb" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr91188-1c.c b/gcc/testsuite/gcc.target/i386/pr91188-1c.c
new file mode 100644
index 0000000..0b32420
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91188-1c.c
@@ -0,0 +1,113 @@
+/* PR target/91188 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movzbl" } } */
+/* { dg-final { scan-assembler-not "movb" } } */
+
+struct S
+{
+ unsigned char val;
+ unsigned char pad1;
+ unsigned short pad2;
+};
+
+struct S
+test_and (struct S a)
+{
+ a.val &= 0x42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andb" } } */
+
+struct S
+test_or (struct S a)
+{
+ a.val |= 0x42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orb" } } */
+
+struct S
+test_xor (struct S a)
+{
+ a.val ^= 0x42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorb" } } */
+
+struct S
+test_sal (struct S a)
+{
+ a.val <<= 3;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]salb" } } */
+
+struct S
+test_shr (struct S a)
+{
+ a.val >>= 3;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]shrb" } } */
+
+struct S
+test_sar (struct S a)
+{
+ a.val = (signed char) a.val >> 3;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]sarb" } } */
+
+struct S
+test_rol (struct S a)
+{
+ a.val = (a.val << 3 | a.val >> 5) ;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]rolb" } } */
+
+struct S
+test_ror (struct S a)
+{
+ a.val = (a.val >> 3 | a.val << 5) ;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]rorb" } } */
+
+struct S
+test_add (struct S a)
+{
+ a.val += 42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addb" } } */
+
+struct S
+test_sub (struct S a)
+{
+ a.val -= 42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]subb" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr91188-2a.c b/gcc/testsuite/gcc.target/i386/pr91188-2a.c
new file mode 100644
index 0000000..6529114
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91188-2a.c
@@ -0,0 +1,62 @@
+/* PR target/91188 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movzwl" } } */
+/* { dg-final { scan-assembler-not "movw" } } */
+
+struct S
+{
+ unsigned short val;
+ unsigned short pad;
+};
+
+struct S
+test_and (struct S a, unsigned short b)
+{
+ a.val &= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andw" } } */
+
+struct S
+test_or (struct S a, unsigned short b)
+{
+ a.val |= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orw" } } */
+
+struct S
+test_xor (struct S a, unsigned short b)
+{
+ a.val ^= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorw" } } */
+
+struct S
+test_add (struct S a, unsigned short b)
+{
+ a.val += b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addw" } } */
+
+struct S
+test_sub (struct S a, unsigned short b)
+{
+ a.val -= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]subw" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr91188-2b.c b/gcc/testsuite/gcc.target/i386/pr91188-2b.c
new file mode 100644
index 0000000..cdaeae0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91188-2b.c
@@ -0,0 +1,64 @@
+/* PR target/91188 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movzwl" } } */
+/* { dg-final { scan-assembler-not "movw" } } */
+
+struct S
+{
+ unsigned short val;
+ unsigned short pad;
+};
+
+unsigned short b;
+
+struct S
+test_and (struct S a)
+{
+ a.val &= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andw" } } */
+
+struct S
+test_or (struct S a)
+{
+ a.val |= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orw" } } */
+
+struct S
+test_xor (struct S a)
+{
+ a.val ^= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorw" } } */
+
+struct S
+test_add (struct S a)
+{
+ a.val += b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addw" } } */
+
+struct S
+test_sub (struct S a)
+{
+ a.val -= b;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]subw" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr91188-2c.c b/gcc/testsuite/gcc.target/i386/pr91188-2c.c
new file mode 100644
index 0000000..c84e9c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91188-2c.c
@@ -0,0 +1,112 @@
+/* PR target/91188 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -masm=att" } */
+/* { dg-additional-options "-mregparm=3" { target ia32 } } */
+/* { dg-final { scan-assembler-not "movzwl" } } */
+/* { dg-final { scan-assembler-not "movw" } } */
+
+struct S
+{
+ unsigned short val;
+ unsigned short pad;
+};
+
+struct S
+test_and (struct S a)
+{
+ a.val &= 0x42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]andw" } } */
+
+struct S
+test_or (struct S a)
+{
+ a.val |= 0x42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]orw" } } */
+
+struct S
+test_xor (struct S a)
+{
+ a.val ^= 0x42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]xorw" } } */
+
+struct S
+test_sal (struct S a)
+{
+ a.val <<= 3;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]salw" } } */
+
+struct S
+test_shr (struct S a)
+{
+ a.val >>= 3;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]shrw" } } */
+
+struct S
+test_sar (struct S a)
+{
+ a.val = (signed short) a.val >> 3;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]sarw" } } */
+
+struct S
+test_rol (struct S a)
+{
+ a.val = (a.val << 3 | a.val >> 13) ;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]rolw" } } */
+
+struct S
+test_ror (struct S a)
+{
+ a.val = (a.val >> 3 | a.val << 13) ;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]rorw" } } */
+
+struct S
+test_add (struct S a)
+{
+ a.val += 42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]addw" } } */
+
+struct S
+test_sub (struct S a)
+{
+ a.val -= 42;
+
+ return a;
+}
+
+/* { dg-final { scan-assembler "\[ \t\]subw" } } */
diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c
new file mode 100644
index 0000000..24c1826
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips" } */
+/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */
+
+extern void foo (void*);
+
+extern void bar (void*);
+
+void
+test (void* p)
+{
+ if (!p)
+ foo(p);
+ else
+ bar(p);
+}
+
+/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,foo" } } */
+/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,bar" } } */
diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c
new file mode 100644
index 0000000..9fd75c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips" } */
+/* { dg-additional-options "-fno-inline -fipa-ra -mcompact-branches=never" } */
+/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */
+
+static int foo (void* p) { __asm__ (""::"r"(p):"$t0"); return 0; }
+
+static int bar (void* p) { return 1; }
+
+int
+test (void* p)
+{
+ int res = !p ? foo(p) : bar(p);
+
+ register int tmp __asm__("$t0") = -1;
+ __asm__ (""::"r"(tmp));
+
+ return res;
+}
+
+/* { dg-final { scan-assembler "\\\.reloc\t1f,R_MIPS_JALR,foo" } } */
+/* { dg-final { scan-assembler "\\\.reloc\t1f,R_MIPS_JALR,bar" } } */
+/* { dg-final { scan-assembler-not "\\.set\tnomacro\n\tjalr\t\\\$25" } } */
diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c
new file mode 100644
index 0000000..580c6ec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips" } */
+/* { dg-additional-options "-fno-inline -fipa-ra -mcompact-branches=never" } */
+/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */
+
+static int foo (void* p) { return 0; }
+
+static int bar (void* p) { return 1; }
+
+int
+test (void* p)
+{
+ int res = !p ? foo(p) : bar(p);
+
+ register int tmp __asm__("$t0") = -1;
+ __asm__ (""::"r"(tmp));
+
+ return res;
+}
+
+/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,foo" } } */
+/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,bar" } } */
+/* { dg-final { scan-assembler "\\.set\tnomacro\n\tjalr\t\\\$25" } } */
diff --git a/gcc/testsuite/gcc.target/mips/msa-fmadd-n64.c b/gcc/testsuite/gcc.target/mips/msa-fmadd-n64.c
new file mode 100644
index 0000000..199b366
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/msa-fmadd-n64.c
@@ -0,0 +1,101 @@
+/* { dg-do compile } */
+/* { dg-options "-mabi=64 -mfp64 -mhard-float -mmsa -EL -flax-vector-conversions" } */
+/* { dg-skip-if "uses global registers" { *-*-* } { "-O0" } { "" } } */
+
+typedef int v4i32 __attribute__ ((vector_size(16)));
+typedef float v4f32 __attribute__ ((vector_size(16)));
+typedef double v2f64 __attribute__ ((vector_size(16)));
+
+/* Test that MSA FMADD-like intrinsics do not use first operand for multiplication. */
+
+register v4i32 a __asm__("$f24");
+register v4i32 b __asm__("$f25");
+register v4f32 c __asm__("$f26");
+register v4f32 d __asm__("$f27");
+register v2f64 e __asm__("$f28");
+register v2f64 f __asm__("$f29");
+
+void
+maddv_b_msa (void)
+{
+ a = __builtin_msa_maddv_b (a, b, b);
+}
+/* { dg-final { scan-assembler "maddv\\\.b\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+maddv_h_msa (void)
+{
+ a = __builtin_msa_maddv_h (a, b, b);
+}
+/* { dg-final { scan-assembler "maddv\\\.h\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+maddv_w_msa (void)
+{
+ a = __builtin_msa_maddv_w (a, b, b);
+}
+/* { dg-final { scan-assembler "maddv\\\.w\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+maddv_d_msa (void)
+{
+ a = __builtin_msa_maddv_d (a, b, b);
+}
+/* { dg-final { scan-assembler "maddv\\\.d\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+msubv_b_msa (void)
+{
+ a = __builtin_msa_msubv_b (a, b, b);
+}
+/* { dg-final { scan-assembler "msubv\\\.b\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+msubv_h_msa (void)
+{
+ a = __builtin_msa_msubv_h (a, b, b);
+}
+/* { dg-final { scan-assembler "msubv\\\.h\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+msubv_w_msa (void)
+{
+ a = __builtin_msa_msubv_w (a, b, b);
+}
+/* { dg-final { scan-assembler "msubv\\\.w\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+msubv_d_msa (void)
+{
+ a = __builtin_msa_msubv_d (a, b, b);
+}
+/* { dg-final { scan-assembler "msubv\\\.d\t\\\$w24,\\\$w25,\\\$w25" } } */
+
+void
+fmadd_w_msa (void)
+{
+ c = __builtin_msa_fmadd_w (c, d, d);
+}
+/* { dg-final { scan-assembler "fmadd\\\.w\t\\\$w26,\\\$w27,\\\$w27" } } */
+
+void
+fmadd_d_msa (void)
+{
+ e = __builtin_msa_fmadd_d (e, f, f);
+}
+/* { dg-final { scan-assembler "fmadd\\\.d\t\\\$w28,\\\$w29,\\\$w29" } } */
+
+void
+fmsub_w_msa (void)
+{
+ c = __builtin_msa_fmsub_w (c, d, d);
+}
+/* { dg-final { scan-assembler "fmsub\\\.w\t\\\$w26,\\\$w27,\\\$w27" } } */
+
+void
+fmsub_d_msa (void)
+{
+ e = __builtin_msa_fmsub_d (e, f, f);
+}
+/* { dg-final { scan-assembler "fmsub\\\.d\t\\\$w28,\\\$w29,\\\$w29" } } */
+
diff --git a/gcc/testsuite/gcc.target/mips/msa-fmadd.c b/gcc/testsuite/gcc.target/mips/msa-fmadd-o32.c
index 9265c04..8433369 100644
--- a/gcc/testsuite/gcc.target/mips/msa-fmadd.c
+++ b/gcc/testsuite/gcc.target/mips/msa-fmadd-o32.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-mfp64 -mhard-float -mmsa -EL -flax-vector-conversions" } */
+/* { dg-options "-mabi=32 -mfp64 -mhard-float -mmsa -EL -flax-vector-conversions" } */
/* { dg-skip-if "uses global registers" { *-*-* } { "-O0" } { "" } } */
typedef int v4i32 __attribute__ ((vector_size(16)));
diff --git a/gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430.c b/gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430.c
new file mode 100644
index 0000000..a2bf843
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430x*" "-mlarge" } { "" } } */
+/* { dg-options "-mcpu=msp430" } */
+/* { dg-final { scan-assembler "PUSH\tR11" } } */
+/* { dg-final { scan-assembler-not "PUSH\tR10" } } */
+
+void __attribute__((noinline)) callee (void);
+
+void __attribute__((interrupt))
+isr (void)
+{
+ callee();
+}
diff --git a/gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430x.c b/gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430x.c
new file mode 100644
index 0000000..2d65186
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/isr-push-pop-isr-430x.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" } { "" } } */
+/* { dg-final { scan-assembler "PUSHM.*#5" } } */
+/* { dg-final { scan-assembler-not "PUSHM.*#12" } } */
+
+void __attribute__((noinline)) callee (void);
+
+void __attribute__((interrupt))
+isr (void)
+{
+ callee();
+}
diff --git a/gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430.c b/gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430.c
new file mode 100644
index 0000000..cbb4597
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430x*" "-mlarge" } { "" } } */
+/* { dg-options "-mcpu=msp430" } */
+/* { dg-final { scan-assembler "PUSH\tR5" } } */
+/* { dg-final { scan-assembler "PUSH\tR12" } } */
+/* { dg-final { scan-assembler-not "PUSH\tR4" } } */
+/* { dg-final { scan-assembler-not "PUSH\tR11" } } */
+
+/* To check that the compiler doesn't blindly save all regs, we omit R4 and R11
+ from the trashing. */
+#define TRASH_REGS_LITE \
+ __asm__ ("mov #0xFFFF, r5" : : : "R5"); \
+ __asm__ ("mov #0xFFFF, r6" : : : "R6"); \
+ __asm__ ("mov #0xFFFF, r7" : : : "R7"); \
+ __asm__ ("mov #0xFFFF, r8" : : : "R8"); \
+ __asm__ ("mov #0xFFFF, r9" : : : "R9"); \
+ __asm__ ("mov #0xFFFF, r10" : : : "R10"); \
+ __asm__ ("mov #0xFFFF, r12" : : : "R12"); \
+ __asm__ ("mov #0xFFFF, r13" : : : "R13"); \
+ __asm__ ("mov #0xFFFF, r14" : : : "R14"); \
+ __asm__ ("mov #0xFFFF, r15" : : : "R15");
+
+void __attribute__((interrupt))
+isr_leaf (void)
+{
+ TRASH_REGS_LITE
+}
diff --git a/gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430x.c b/gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430x.c
new file mode 100644
index 0000000..872a40e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/isr-push-pop-leaf-isr-430x.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" } { "" } } */
+/* { dg-final { scan-assembler "PUSHM.*#4.*R15" } } */
+/* { dg-final { scan-assembler "PUSHM.*#6.*R10" } } */
+
+/* To check that the compiler doesn't blindly save all regs, we omit R4 and R11
+ from the trashing. */
+#define TRASH_REGS_LITE \
+ __asm__ ("mov #0xFFFF, r5" : : : "R5"); \
+ __asm__ ("mov #0xFFFF, r6" : : : "R6"); \
+ __asm__ ("mov #0xFFFF, r7" : : : "R7"); \
+ __asm__ ("mov #0xFFFF, r8" : : : "R8"); \
+ __asm__ ("mov #0xFFFF, r9" : : : "R9"); \
+ __asm__ ("mov #0xFFFF, r10" : : : "R10"); \
+ __asm__ ("mov #0xFFFF, r12" : : : "R12"); \
+ __asm__ ("mov #0xFFFF, r13" : : : "R13"); \
+ __asm__ ("mov #0xFFFF, r14" : : : "R14"); \
+ __asm__ ("mov #0xFFFF, r15" : : : "R15");
+
+void __attribute__((interrupt))
+isr_leaf (void)
+{
+ TRASH_REGS_LITE
+}
diff --git a/gcc/testsuite/gcc.target/msp430/isr-push-pop-main.c b/gcc/testsuite/gcc.target/msp430/isr-push-pop-main.c
new file mode 100644
index 0000000..5c7b594
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/isr-push-pop-main.c
@@ -0,0 +1,120 @@
+/* { dg-do run } */
+
+#ifdef __MSP430X__
+#include "isr-push-pop-isr-430x.c"
+#include "isr-push-pop-leaf-isr-430x.c"
+#else
+#include "isr-push-pop-isr-430.c"
+#include "isr-push-pop-leaf-isr-430.c"
+#endif
+
+/* Test that ISRs which call other functions do not save extraneous registers.
+ They only need to save the caller-saved regs R11->R15.
+ We use a lot of asm statements to hide what is going on from the compiler to
+ more accurately simulate an interrupt. */
+
+/* Store the register number in each general register R4->R15, so they can be
+ later checked their value has been kept. */
+#define SETUP_REGS \
+ __asm__ ("mov #4, r4"); \
+ __asm__ ("mov #5, r5"); \
+ __asm__ ("mov #6, r6"); \
+ __asm__ ("mov #7, r7"); \
+ __asm__ ("mov #8, r8"); \
+ __asm__ ("mov #9, r9"); \
+ __asm__ ("mov #10, r10"); \
+ __asm__ ("mov #11, r11"); \
+ __asm__ ("mov #12, r12"); \
+ __asm__ ("mov #13, r13"); \
+ __asm__ ("mov #14, r14"); \
+ __asm__ ("mov #15, r15");
+
+/* Write an arbitrary value to all general regs. */
+#define TRASH_REGS \
+ __asm__ ("mov #0xFFFF, r4" : : : "R4"); \
+ __asm__ ("mov #0xFFFF, r5" : : : "R5"); \
+ __asm__ ("mov #0xFFFF, r6" : : : "R6"); \
+ __asm__ ("mov #0xFFFF, r7" : : : "R7"); \
+ __asm__ ("mov #0xFFFF, r8" : : : "R8"); \
+ __asm__ ("mov #0xFFFF, r9" : : : "R9"); \
+ __asm__ ("mov #0xFFFF, r10" : : : "R10"); \
+ __asm__ ("mov #0xFFFF, r11" : : : "R11"); \
+ __asm__ ("mov #0xFFFF, r12" : : : "R12"); \
+ __asm__ ("mov #0xFFFF, r13" : : : "R13"); \
+ __asm__ ("mov #0xFFFF, r14" : : : "R14"); \
+ __asm__ ("mov #0xFFFF, r15" : : : "R15");
+
+/* Check the value in all general registers is the same as that set in
+ SETUP_REGS. */
+#define CHECK_REGS \
+ __asm__ ("cmp #4, r4 { jne ABORT"); \
+ __asm__ ("cmp #5, r5 { jne ABORT"); \
+ __asm__ ("cmp #6, r6 { jne ABORT"); \
+ __asm__ ("cmp #7, r7 { jne ABORT"); \
+ __asm__ ("cmp #8, r8 { jne ABORT"); \
+ __asm__ ("cmp #9, r9 { jne ABORT"); \
+ __asm__ ("cmp #10, r10 { jne ABORT"); \
+ __asm__ ("cmp #11, r11 { jne ABORT"); \
+ __asm__ ("cmp #12, r12 { jne ABORT"); \
+ __asm__ ("cmp #13, r13 { jne ABORT"); \
+ __asm__ ("cmp #14, r14 { jne ABORT"); \
+ __asm__ ("cmp #15, r15 { jne ABORT");
+
+void __attribute__((noinline))
+callee (void)
+{
+ /* Here were modify all the regs, but tell the compiler that we are since
+ this is just a way to simulate a function that happens to modify all the
+ registers. */
+ TRASH_REGS
+}
+int
+#ifdef __MSP430X_LARGE__
+__attribute__((lower))
+#endif
+main (void)
+{
+ SETUP_REGS
+
+ /* A surprise branch to the ISR that the compiler cannot prepare for.
+ We must first simulate the interrupt acceptance procedure that the
+ hardware would normally take care of.
+ So push the desired PC return address, and then the SR (R2).
+ MSP430X expects the high bits 19:16 of the PC return address to be stored
+ in bits 12:15 of the SR stack slot. This is hard to handle in hand-rolled
+ assembly code, so we always place main() in lower memory so the return
+ address is 16-bits. */
+ __asm__ ("push #CHECK1");
+ __asm__ ("push r2");
+ __asm__ ("br #isr");
+
+ __asm__ ("CHECK1:");
+ /* If any of the regs R4->R15 don't match their original value, this will
+ jump to ABORT. */
+ CHECK_REGS
+
+ /* Now test that an interrupt function that is a leaf also works
+ correctly. */
+ __asm__ ("push #CHECK2");
+ __asm__ ("push r2");
+ __asm__ ("br #isr_leaf");
+
+ __asm__ ("CHECK2:");
+ CHECK_REGS
+
+ /* The values in R4->R15 were successfully checked, now jump to FINISH to run
+ the prologue generated by the compiler. */
+ __asm__ ("jmp FINISH");
+
+ /* CHECK_REGS will branch here if a register holds the wrong value. */
+ __asm__ ("ABORT:");
+#ifdef __MSP430X_LARGE__
+ __asm__ ("calla #abort");
+#else
+ __asm__ ("call #abort");
+#endif
+
+ __asm__ ("FINISH:");
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.target/or1k/shftimm-1.c b/gcc/testsuite/gcc.target/or1k/shftimm-1.c
index be8d9e8..3a8dc06 100644
--- a/gcc/testsuite/gcc.target/or1k/shftimm-1.c
+++ b/gcc/testsuite/gcc.target/or1k/shftimm-1.c
@@ -1,8 +1,8 @@
/* { dg-do compile } */
-/* { dg-options "-mror -mshftimm -O2" } */
+/* { dg-options "-mshftimm -O2" } */
-unsigned int rotate6 (unsigned int a) {
- return ( a >> 6 ) | ( a << ( 32 - 6 ) );
+unsigned int shift6 (unsigned int a) {
+ return a << 6;
}
-/* { dg-final { scan-assembler "l.rori" } } */
+/* { dg-final { scan-assembler "l.slli" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c
index 6d713d2..604dbbc 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-eq-2.c
@@ -11,5 +11,5 @@ compare_exponents_eq (double *exponent1_p, double *exponent2_p)
double exponent1 = *exponent1_p;
double exponent2 = *exponent2_p;
- return __builtin_vec_scalar_cmp_exp_eq (exponent1, exponent2); /* { dg-error "builtin function '__builtin_vsx_scalar_cmp_exp_dp_eq' requires" } */
+ return __builtin_vec_scalar_cmp_exp_eq (exponent1, exponent2); /* { dg-error "'__builtin_vsx_scalar_cmp_exp_dp_eq' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c
index f3d8f04..2f01b87 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-gt-2.c
@@ -11,5 +11,5 @@ compare_exponents_gt (double *exponent1_p, double *exponent2_p)
double exponent1 = *exponent1_p;
double exponent2 = *exponent2_p;
- return __builtin_vec_scalar_cmp_exp_gt (exponent1, exponent2); /* { dg-error "builtin function '__builtin_vsx_scalar_cmp_exp_dp_gt' requires" } */
+ return __builtin_vec_scalar_cmp_exp_gt (exponent1, exponent2); /* { dg-error "'__builtin_vsx_scalar_cmp_exp_dp_gt' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c
index 0dd210a..75969c2 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-lt-2.c
@@ -11,5 +11,5 @@ compare_exponents_lt (double *exponent1_p, double *exponent2_p)
double exponent1 = *exponent1_p;
double exponent2 = *exponent2_p;
- return __builtin_vec_scalar_cmp_exp_lt (exponent1, exponent2); /* { dg-error "builtin function '__builtin_vsx_scalar_cmp_exp_dp_lt' requires" } */
+ return __builtin_vec_scalar_cmp_exp_lt (exponent1, exponent2); /* { dg-error "'__builtin_vsx_scalar_cmp_exp_dp_lt' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c
index 6987991..f59b4a3 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-cmp-exp-unordered-2.c
@@ -11,5 +11,5 @@ compare_exponents_unordered (double *exponent1_p, double *exponent2_p)
double exponent1 = *exponent1_p;
double exponent2 = *exponent2_p;
- return __builtin_vec_scalar_cmp_exp_unordered (exponent1, exponent2); /* { dg-error "builtin function '__builtin_vsx_scalar_cmp_exp_dp_unordered' requires" } */
+ return __builtin_vec_scalar_cmp_exp_unordered (exponent1, exponent2); /* { dg-error "'__builtin_vsx_scalar_cmp_exp_dp_unordered' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c
index d77d84c..9737762 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-1.c
@@ -11,7 +11,7 @@ get_exponent (double *p)
{
double source = *p;
- return __builtin_vec_scalar_extract_exp (source); /* { dg-error "builtin function '__builtin_vsx_scalar_extract_exp' requires" } */
+ return __builtin_vec_scalar_extract_exp (source); /* { dg-error "'__builtin_vsx_scalar_extract_exp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c
index 3f4d97b..9221806 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-2.c
@@ -14,7 +14,7 @@ get_exponent (double *p)
{
double source = *p;
- return scalar_extract_exp (source); /* { dg-error "builtin function '__builtin_vec_scalar_extract_exp' not supported in this compiler configuration" } */
+ return scalar_extract_exp (source); /* { dg-error "'__builtin_vec_scalar_extract_exp' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c
index b3d4910..850ff62 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-4.c
@@ -11,7 +11,7 @@ get_exponent (__ieee128 *p)
{
__ieee128 source = *p;
- return __builtin_vec_scalar_extract_exp (source); /* { dg-error "builtin function '__builtin_vsx_scalar_extract_expq' requires" } */
+ return __builtin_vec_scalar_extract_exp (source); /* { dg-error "'__builtin_vsx_scalar_extract_expq' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c
index b87e6d46..f12eed3 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-1.c
@@ -11,5 +11,5 @@ get_significand (double *p)
{
double source = *p;
- return __builtin_vec_scalar_extract_sig (source); /* { dg-error "builtin function '__builtin_vsx_scalar_extract_sig' requires" } */
+ return __builtin_vec_scalar_extract_sig (source); /* { dg-error "'__builtin_vsx_scalar_extract_sig' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c
index 4a9819c..e24d4bd 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-2.c
@@ -12,5 +12,5 @@ get_significand (double *p)
{
double source = *p;
- return __builtin_vec_scalar_extract_sig (source); /* { dg-error "builtin function '__builtin_vec_scalar_extract_sig' not supported in this compiler configuration" } */
+ return __builtin_vec_scalar_extract_sig (source); /* { dg-error "'__builtin_vec_scalar_extract_sig' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c
index cf8f14c..32a53c6 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-4.c
@@ -11,5 +11,5 @@ get_significand (__ieee128 *p)
{
__ieee128 source = *p;
- return __builtin_vec_scalar_extract_sig (source); /* { dg-error "builtin function '__builtin_vsx_scalar_extract_sigq' requires" } */
+ return __builtin_vec_scalar_extract_sig (source); /* { dg-error "'__builtin_vsx_scalar_extract_sigq' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c
index a913899..8260b10 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-1.c
@@ -13,5 +13,5 @@ insert_exponent (unsigned long long int *significand_p,
unsigned long long int significand = *significand_p;
unsigned long long int exponent = *exponent_p;
- return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "builtin function '__builtin_vsx_scalar_insert_exp' requires" } */
+ return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "'__builtin_vsx_scalar_insert_exp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c
index 196a6f6..769d3b0 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-10.c
@@ -13,5 +13,5 @@ insert_exponent (__ieee128 *significand_p,
__ieee128 significand = *significand_p;
unsigned long long int exponent = *exponent_p;
- return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "builtin function '__builtin_vsx_scalar_insert_exp_qp' requires" } */
+ return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "'__builtin_vsx_scalar_insert_exp_qp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c
index 9cab364..feb9431 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-2.c
@@ -16,5 +16,5 @@ insert_exponent (unsigned long long int *significand_p,
unsigned long long int significand = *significand_p;
unsigned long long int exponent = *exponent_p;
- return scalar_insert_exp (significand, exponent); /* { dg-error "builtin function '__builtin_vec_scalar_insert_exp' not supported in this compiler configuration" } */
+ return scalar_insert_exp (significand, exponent); /* { dg-error "'__builtin_vec_scalar_insert_exp' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-4.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-4.c
index a248703..1699c67 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-4.c
@@ -13,5 +13,5 @@ insert_exponent (double *significand_p,
double significand = *significand_p;
unsigned long long int exponent = *exponent_p;
- return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "builtin function '__builtin_vsx_scalar_insert_exp_dp' requires" } */
+ return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "'__builtin_vsx_scalar_insert_exp_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-5.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-5.c
index a6605b9..0e5683d 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-5.c
@@ -16,5 +16,5 @@ insert_exponent (double *significand_p,
double significand = *significand_p;
unsigned long long int exponent = *exponent_p;
- return scalar_insert_exp (significand, exponent); /* { dg-error "builtin function '__builtin_vec_scalar_insert_exp' not supported in this compiler configuration" } */
+ return scalar_insert_exp (significand, exponent); /* { dg-error "'__builtin_vec_scalar_insert_exp' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c
index 3f6a3ff..2e03e15 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-7.c
@@ -13,5 +13,5 @@ insert_exponent (unsigned __int128 *significand_p,
unsigned __int128 significand = *significand_p;
unsigned long long int exponent = *exponent_p;
- return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "builtin function '__builtin_vsx_scalar_insert_exp_q' requires" } */
+ return __builtin_vec_scalar_insert_exp (significand, exponent); /* { dg-error "'__builtin_vsx_scalar_insert_exp_q' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.c
index 2bb4f5e..bd68f77 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-8.c
@@ -16,5 +16,5 @@ insert_exponent (unsigned __int128 *significand_p, /* { dg-error "'__int128' is
unsigned __int128 significand = *significand_p; /* { dg-error "'__int128' is not supported on this target" } */
unsigned long long int exponent = *exponent_p;
- return scalar_insert_exp (significand, exponent); /* { dg-error "builtin function '__builtin_vec_scalar_insert_exp' not supported in this compiler configuration" } */
+ return scalar_insert_exp (significand, exponent); /* { dg-error "'__builtin_vec_scalar_insert_exp' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c
index 1ed3fd2..7c6fca2 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-11.c
@@ -10,5 +10,5 @@ test_data_class (__ieee128 *p)
{
__ieee128 source = *p;
- return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "builtin function '__builtin_vsx_scalar_test_data_class_qp' requires" } */
+ return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "'__builtin_vsx_scalar_test_data_class_qp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c
index 9fae5ff..7fb6601 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-6.c
@@ -10,5 +10,5 @@ test_data_class (double *p)
{
double source = *p;
- return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "builtin function '__builtin_vsx_scalar_test_data_class_dp' requires" } */
+ return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "'__builtin_vsx_scalar_test_data_class_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c
index f3e8a20..02e9ec5 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-data-class-7.c
@@ -10,5 +10,5 @@ test_data_class (float *p)
{
float source = *p;
- return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "builtin function '__builtin_vsx_scalar_test_data_class_sp' requires" } */
+ return __builtin_vec_scalar_test_data_class (source, 3); /* { dg-error "'__builtin_vsx_scalar_test_data_class_sp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c
index 6bdf1d6..7d2b4de 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-2.c
@@ -10,5 +10,5 @@ test_neg (float *p)
{
float source = *p;
- return __builtin_vec_scalar_test_neg_sp (source); /* { dg-error "builtin function '__builtin_vsx_scalar_test_neg_sp' requires" } */
+ return __builtin_vec_scalar_test_neg_sp (source); /* { dg-error "'__builtin_vsx_scalar_test_neg_sp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c
index 681b3d7..b503dfa 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-3.c
@@ -10,5 +10,5 @@ test_neg (double *p)
{
double source = *p;
- return __builtin_vec_scalar_test_neg_dp (source); /* { dg-error "builtin function '__builtin_vsx_scalar_test_neg_dp' requires" } */
+ return __builtin_vec_scalar_test_neg_dp (source); /* { dg-error "'__builtin_vsx_scalar_test_neg_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c
index b234ab9..bab8604 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-test-neg-5.c
@@ -10,5 +10,5 @@ test_neg (__ieee128 *p)
{
__ieee128 source = *p;
- return __builtin_vec_scalar_test_neg_qp (source); /* { dg-error "builtin function '__builtin_vsx_scalar_test_neg_qp' requires" } */
+ return __builtin_vec_scalar_test_neg_qp (source); /* { dg-error "'__builtin_vsx_scalar_test_neg_qp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c
index e27e053..86d0260 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-2.c
@@ -9,5 +9,5 @@ get_exponents (__vector double *p)
{
__vector double source = *p;
- return __builtin_vec_extract_exp (source); /* { dg-error "builtin function '__builtin_vsx_extract_exp_dp' requires" } */
+ return __builtin_vec_extract_exp (source); /* { dg-error "'__builtin_vsx_extract_exp_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c
index c2d48f8..e909a26 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-exp-3.c
@@ -9,5 +9,5 @@ get_exponents (__vector float *p)
{
__vector float source = *p;
- return __builtin_vec_extract_exp (source); /* { dg-error "builtin function '__builtin_vsx_extract_exp_sp' requires" } */
+ return __builtin_vec_extract_exp (source); /* { dg-error "'__builtin_vsx_extract_exp_sp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c
index 0ef4b3c..eab6673 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-2.c
@@ -9,5 +9,5 @@ get_significands (__vector double *p)
{
__vector double source = *p;
- return __builtin_vec_extract_sig (source); /* { dg-error "builtin function '__builtin_vsx_extract_sig_dp' requires" } */
+ return __builtin_vec_extract_sig (source); /* { dg-error "'__builtin_vsx_extract_sig_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c
index 4727fc3..ab1967b 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-extract-sig-3.c
@@ -9,5 +9,5 @@ get_significands (__vector float *p)
{
__vector float source = *p;
- return __builtin_vec_extract_sig (source); /* { dg-error "builtin function '__builtin_vsx_extract_sig_sp' requires" } */
+ return __builtin_vec_extract_sig (source); /* { dg-error "'__builtin_vsx_extract_sig_sp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c
index 4f33fd2..6aa6b40 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-2.c
@@ -11,5 +11,5 @@ make_floats (__vector unsigned int *significands_p,
__vector unsigned int significands = *significands_p;
__vector unsigned int exponents = *exponents_p;
- return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "builtin function '__builtin_vsx_insert_exp_sp' requires" } */
+ return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "'__builtin_vsx_insert_exp_sp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c
index 097f0da..ab4c2f1 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-3.c
@@ -11,5 +11,5 @@ make_doubles (__vector unsigned long long int *significands_p,
__vector unsigned long long int significands = *significands_p;
__vector unsigned long long int exponents = *exponents_p;
- return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "builtin function '__builtin_vsx_insert_exp_dp' requires" } */
+ return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "'__builtin_vsx_insert_exp_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-6.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-6.c
index 01595cd..70ed82b 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-6.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-6.c
@@ -11,5 +11,5 @@ make_floats (__vector float *significands_p,
__vector float significands = *significands_p;
__vector unsigned int exponents = *exponents_p;
- return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "builtin function '__builtin_vsx_insert_exp_sp' requires" } */
+ return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "'__builtin_vsx_insert_exp_sp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-7.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-7.c
index 3401630..eb5dda4 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-insert-exp-7.c
@@ -11,5 +11,5 @@ make_doubles (__vector double *significands_p,
__vector double significands = *significands_p;
__vector unsigned long long int exponents = *exponents_p;
- return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "builtin function '__builtin_vsx_insert_exp_dp' requires" } */
+ return __builtin_vec_insert_exp (significands, exponents); /* { dg-error "'__builtin_vsx_insert_exp_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c
index 1ade5fb..f53efdc 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-2.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector double *p)
{
__vector double source = *p;
- return __builtin_vec_test_data_class (source, 0x37); /* { dg-error "builtin function '__builtin_vsx_test_data_class_dp' requires" } */
+ return __builtin_vec_test_data_class (source, 0x37); /* { dg-error "'__builtin_vsx_test_data_class_dp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c
index a4f804e..5ec7019 100644
--- a/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/bfp/vec-test-data-class-3.c
@@ -9,5 +9,5 @@ get_data_class_flags (__vector float *p)
{
__vector float source = *p;
- return __builtin_vec_test_data_class (source, 0x37); /* { dg-error "builtin function '__builtin_vsx_test_data_class_sp' requires" } */
+ return __builtin_vec_test_data_class (source, 0x37); /* { dg-error "'__builtin_vsx_test_data_class_sp' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/byte-in-either-range-1.c b/gcc/testsuite/gcc.target/powerpc/byte-in-either-range-1.c
index 6e11285..e67fb66 100644
--- a/gcc/testsuite/gcc.target/powerpc/byte-in-either-range-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/byte-in-either-range-1.c
@@ -17,5 +17,5 @@ test_byte_in_either_range (unsigned char b,
range_encoding = ((first_hi_bound << 24) | (first_lo_bound << 16)
| (second_hi_bound << 8) | second_lo_bound);
- return __builtin_byte_in_either_range (b, range_encoding); /* { dg-error "builtin function '__builtin_scalar_byte_in_either_range' requires" } */
+ return __builtin_byte_in_either_range (b, range_encoding); /* { dg-error "'__builtin_scalar_byte_in_either_range' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/byte-in-range-1.c b/gcc/testsuite/gcc.target/powerpc/byte-in-range-1.c
index bd4a9d3..4f4ad8f 100644
--- a/gcc/testsuite/gcc.target/powerpc/byte-in-range-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/byte-in-range-1.c
@@ -10,6 +10,6 @@ test_byte_in_range (unsigned char b,
unsigned char low_range, unsigned char high_range)
{
unsigned int range_encoding = (high_range << 8) | low_range;
- return __builtin_byte_in_range (b, range_encoding); /* { dg-error "builtin function '__builtin_scalar_byte_in_range' requires" } */
+ return __builtin_byte_in_range (b, range_encoding); /* { dg-error "'__builtin_scalar_byte_in_range' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/byte-in-set-1.c b/gcc/testsuite/gcc.target/powerpc/byte-in-set-1.c
index 3d3247a..a369dc1 100644
--- a/gcc/testsuite/gcc.target/powerpc/byte-in-set-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/byte-in-set-1.c
@@ -9,5 +9,5 @@
int
test_byte_in_set (unsigned char b, unsigned long long set_members)
{
- return __builtin_byte_in_set (b, set_members); /* { dg-error "builtin function '__builtin_scalar_byte_in_set' requires" } */
+ return __builtin_byte_in_set (b, set_members); /* { dg-error "'__builtin_scalar_byte_in_set' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/byte-in-set-2.c b/gcc/testsuite/gcc.target/powerpc/byte-in-set-2.c
index a858841..9a80c27 100644
--- a/gcc/testsuite/gcc.target/powerpc/byte-in-set-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/byte-in-set-2.c
@@ -11,5 +11,5 @@
int
test_byte_in_set (unsigned char b, unsigned long long set_members)
{
- return __builtin_byte_in_set (b, set_members); /* { dg-error "builtin function '__builtin_byte_in_set' not supported in this compiler configuration" } */
+ return __builtin_byte_in_set (b, set_members); /* { dg-error "'__builtin_byte_in_set' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/cmpb-3.c b/gcc/testsuite/gcc.target/powerpc/cmpb-3.c
index 70de475..de111a8 100644
--- a/gcc/testsuite/gcc.target/powerpc/cmpb-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/cmpb-3.c
@@ -8,7 +8,7 @@ void abort ();
long long int
do_compare (long long int a, long long int b)
{
- return __builtin_cmpb (a, b); /* { dg-error "builtin function '__builtin_cmpb' not supported in this compiler configuration" } */
+ return __builtin_cmpb (a, b); /* { dg-error "'__builtin_cmpb' is not supported in this compiler configuration" } */
}
void expect (long long int pattern, long long int value)
diff --git a/gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c b/gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c
index a3389ff..4066b12 100644
--- a/gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/crypto-builtin-2.c
@@ -5,21 +5,21 @@
void use_builtins_d (__vector unsigned long long *p, __vector unsigned long long *q, __vector unsigned long long *r, __vector unsigned long long *s)
{
- p[0] = __builtin_crypto_vcipher (q[0], r[0]); /* { dg-error "builtin function '__builtin_crypto_vcipher' is not supported with the current options" } */
- p[1] = __builtin_crypto_vcipherlast (q[1], r[1]); /* { dg-error "builtin function '__builtin_crypto_vcipherlast' is not supported with the current options" } */
- p[2] = __builtin_crypto_vncipher (q[2], r[2]); /* { dg-error "builtin function '__builtin_crypto_vncipher' is not supported with the current options" } */
- p[3] = __builtin_crypto_vncipherlast (q[3], r[3]); /* { dg-error "builtin function '__builtin_crypto_vncipherlast' is not supported with the current options" } */
+ p[0] = __builtin_crypto_vcipher (q[0], r[0]); /* { dg-error "'__builtin_crypto_vcipher' is not supported with the current options" } */
+ p[1] = __builtin_crypto_vcipherlast (q[1], r[1]); /* { dg-error "'__builtin_crypto_vcipherlast' is not supported with the current options" } */
+ p[2] = __builtin_crypto_vncipher (q[2], r[2]); /* { dg-error "'__builtin_crypto_vncipher' is not supported with the current options" } */
+ p[3] = __builtin_crypto_vncipherlast (q[3], r[3]); /* { dg-error "'__builtin_crypto_vncipherlast' is not supported with the current options" } */
p[4] = __builtin_crypto_vpermxor (q[4], r[4], s[4]);
p[5] = __builtin_crypto_vpmsumd (q[5], r[5]);
- p[6] = __builtin_crypto_vshasigmad (q[6], 1, 15); /* { dg-error "builtin function '__builtin_crypto_vshasigmad' is not supported with the current options" } */
- p[7] = __builtin_crypto_vsbox (q[7]); /* { dg-error "builtin function '__builtin_crypto_vsbox' is not supported with the current options" } */
+ p[6] = __builtin_crypto_vshasigmad (q[6], 1, 15); /* { dg-error "'__builtin_crypto_vshasigmad' is not supported with the current options" } */
+ p[7] = __builtin_crypto_vsbox (q[7]); /* { dg-error "'__builtin_crypto_vsbox' is not supported with the current options" } */
}
void use_builtins_w (__vector unsigned int *p, __vector unsigned int *q, __vector unsigned int *r, __vector unsigned int *s)
{
p[0] = __builtin_crypto_vpermxor (q[0], r[0], s[0]);
p[1] = __builtin_crypto_vpmsumw (q[1], r[1]);
- p[2] = __builtin_crypto_vshasigmaw (q[2], 1, 15); /* { dg-error "builtin function '__builtin_crypto_vshasigmaw' is not supported with the current options" } */
+ p[2] = __builtin_crypto_vshasigmaw (q[2], 1, 15); /* { dg-error "'__builtin_crypto_vshasigmaw' is not supported with the current options" } */
}
void use_builtins_h (__vector unsigned short *p, __vector unsigned short *q, __vector unsigned short *r, __vector unsigned short *s)
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c
index 62e2f7f..e660b74 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-1.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_lt (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_lt_dd' requires" } */
+ return __builtin_dfp_dtstsfi_lt (5, source); /* { dg-error "'__builtin_dtstsfi_lt_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c
index bdbf85c..92145f0 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-11.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_lt_dd (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_lt_dd' requires" } */
+ return __builtin_dfp_dtstsfi_lt_dd (5, source); /* { dg-error "'__builtin_dtstsfi_lt_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c
index a2f4c4f..62dc52d 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-16.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_lt_td (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_lt_td' requires" } */
+ return __builtin_dfp_dtstsfi_lt_td (5, source); /* { dg-error "'__builtin_dtstsfi_lt_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c
index a881b71..a8e435b 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-21.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_gt (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_gt_dd' requires" } */
+ return __builtin_dfp_dtstsfi_gt (5, source); /* { dg-error "'__builtin_dtstsfi_gt_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c
index d69a094..40790f4 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-26.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_gt (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_gt_td' requires" } */
+ return __builtin_dfp_dtstsfi_gt (5, source); /* { dg-error "'__builtin_dtstsfi_gt_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c
index d921b8f..a7f3908 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-31.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_gt_dd (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_gt_dd' requires" } */
+ return __builtin_dfp_dtstsfi_gt_dd (5, source); /* { dg-error "'__builtin_dtstsfi_gt_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c
index 046c78b..1b48867 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-36.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_gt_td (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_gt_td' requires" } */
+ return __builtin_dfp_dtstsfi_gt_td (5, source); /* { dg-error "'__builtin_dtstsfi_gt_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c
index 7460c0c..640e6c8 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-41.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_eq (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_eq_dd' requires" } */
+ return __builtin_dfp_dtstsfi_eq (5, source); /* { dg-error "'__builtin_dtstsfi_eq_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c
index 2072f11..6557a63 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-46.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_eq (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_eq_td' requires" } */
+ return __builtin_dfp_dtstsfi_eq (5, source); /* { dg-error "'__builtin_dtstsfi_eq_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c
index cf0b4ad..801c8c7 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-51.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_eq_dd (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_eq_dd' requires" } */
+ return __builtin_dfp_dtstsfi_eq_dd (5, source); /* { dg-error "'__builtin_dtstsfi_eq_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c
index cac7c4d..589adeb 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-56.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_eq_td (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_eq_td' requires" } */
+ return __builtin_dfp_dtstsfi_eq_td (5, source); /* { dg-error "'__builtin_dtstsfi_eq_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c
index dfa8039..873ad9f 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-6.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_lt (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_lt_td' requires" } */
+ return __builtin_dfp_dtstsfi_lt (5, source); /* { dg-error "'__builtin_dtstsfi_lt_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c
index ad7aced..3b2867c 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-61.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_ov (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_ov_dd' requires" } */
+ return __builtin_dfp_dtstsfi_ov (5, source); /* { dg-error "'__builtin_dtstsfi_ov_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c
index ee9b56a..2b6d30a 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-66.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_ov (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_ov_td' requires" } */
+ return __builtin_dfp_dtstsfi_ov (5, source); /* { dg-error "'__builtin_dtstsfi_ov_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c
index bcdac7a..8fe0b6a 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-71.c
@@ -9,6 +9,6 @@ int doTestBCDSignificance (_Decimal64 *p)
{
_Decimal64 source = *p;
- return __builtin_dfp_dtstsfi_ov_dd (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_ov_dd' requires" } */
+ return __builtin_dfp_dtstsfi_ov_dd (5, source); /* { dg-error "'__builtin_dtstsfi_ov_dd' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c
index a618067..dccc388 100644
--- a/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c
+++ b/gcc/testsuite/gcc.target/powerpc/dfp/dtstsfi-76.c
@@ -9,7 +9,7 @@ int doTestBCDSignificance (_Decimal128 *p)
{
_Decimal128 source = *p;
- return __builtin_dfp_dtstsfi_ov_td (5, source); /* { dg-error "builtin function '__builtin_dtstsfi_ov_td' requires" } */
+ return __builtin_dfp_dtstsfi_ov_td (5, source); /* { dg-error "'__builtin_dtstsfi_ov_td' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr88233.c b/gcc/testsuite/gcc.target/powerpc/pr88233.c
new file mode 100644
index 0000000..fa47b57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr88233.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcpu=power8" } */
+
+typedef struct { double a[2]; } A;
+A
+foo (const A *a)
+{
+ return *a;
+}
+
+/* { dg-final { scan-assembler-not {\mmtvsr} } } */
+/* { dg-final { scan-assembler-times {\mlxvd2x\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mstxvd2x\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/sse4_1-check.h b/gcc/testsuite/gcc.target/powerpc/sse4_1-check.h
new file mode 100644
index 0000000..5f855b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/sse4_1-check.h
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "m128-check.h"
+
+//#define DEBUG 1
+
+#define TEST sse4_1_test
+
+static void sse4_1_test (void);
+
+static void
+__attribute__ ((noinline))
+do_test (void)
+{
+ sse4_1_test ();
+}
+
+int
+main ()
+{
+ do_test ();
+#ifdef DEBUG
+ printf ("PASSED\n");
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendvb.c b/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendvb.c
new file mode 100644
index 0000000..6aa77fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendvb.c
@@ -0,0 +1,71 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mpower8-vector -Wno-psabi" } */
+/* { dg-require-effective-target p8vector_hw } */
+
+#define NO_WARN_X86_INTRINSICS 1
+#ifndef CHECK_H
+#define CHECK_H "sse4_1-check.h"
+#endif
+
+#ifndef TEST
+#define TEST sse4_1_test
+#endif
+
+#include CHECK_H
+
+#include <smmintrin.h>
+#include <string.h>
+
+#define NUM 20
+
+static void
+init_pblendvb (unsigned char *src1, unsigned char *src2,
+ unsigned char *mask)
+{
+ int i, sign = 1;
+
+ for (i = 0; i < NUM * 16; i++)
+ {
+ src1[i] = i* i * sign;
+ src2[i] = (i + 20) * sign;
+ mask[i] = (i % 3) + ((i * (14 + sign))
+ ^ (src1[i] | src2[i] | (i*3)));
+ sign = -sign;
+ }
+}
+
+static int
+check_pblendvb (__m128i *dst, unsigned char *src1,
+ unsigned char *src2, unsigned char *mask)
+{
+ unsigned char tmp[16];
+ int j;
+
+ memcpy (&tmp[0], src1, sizeof (tmp));
+ for (j = 0; j < 16; j++)
+ if (mask [j] & 0x80)
+ tmp[j] = src2[j];
+
+ return memcmp (dst, &tmp[0], sizeof (tmp));
+}
+
+static void
+TEST (void)
+{
+ union
+ {
+ __m128i x[NUM];
+ unsigned char c[NUM * 16];
+ } dst, src1, src2, mask;
+ int i;
+
+ init_pblendvb (src1.c, src2.c, mask.c);
+
+ for (i = 0; i < NUM; i++)
+ {
+ dst.x[i] = _mm_blendv_epi8 (src1.x[i], src2.x[i], mask.x[i]);
+ if (check_pblendvb (&dst.x[i], &src1.c[i * 16], &src2.c[i * 16],
+ &mask.c[i * 16]))
+ abort ();
+ }
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw-2.c b/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw-2.c
new file mode 100644
index 0000000..d3f96e8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw-2.c
@@ -0,0 +1,80 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mpower8-vector -Wno-psabi" } */
+/* { dg-require-effective-target p8vector_hw } */
+
+#define NO_WARN_X86_INTRINSICS 1
+#include "sse4_1-check.h"
+
+#include <smmintrin.h>
+#include <string.h>
+
+#define NUM 20
+
+#undef MASK
+#define MASK 0xfe
+
+static void
+init_pblendw (short *src1, short *src2)
+{
+ int i, sign = 1;
+
+ for (i = 0; i < NUM * 8; i++)
+ {
+ src1[i] = i * i * sign;
+ src2[i] = (i + 20) * sign;
+ sign = -sign;
+ }
+}
+
+static int
+check_pblendw (__m128i *dst, short *src1, short *src2)
+{
+ short tmp[8];
+ int j;
+
+ memcpy (&tmp[0], src1, sizeof (tmp));
+ for (j = 0; j < 8; j++)
+ if ((MASK & (1 << j)))
+ tmp[j] = src2[j];
+
+ return memcmp (dst, &tmp[0], sizeof (tmp));
+}
+
+static void
+sse4_1_test (void)
+{
+ __m128i x, y;
+ union
+ {
+ __m128i x[NUM];
+ short s[NUM * 8];
+ } dst, src1, src2;
+ union
+ {
+ __m128i x;
+ short s[8];
+ } src3;
+ int i;
+
+ init_pblendw (src1.s, src2.s);
+
+ /* Check pblendw imm8, m128, xmm */
+ for (i = 0; i < NUM; i++)
+ {
+ dst.x[i] = _mm_blend_epi16 (src1.x[i], src2.x[i], MASK);
+ if (check_pblendw (&dst.x[i], &src1.s[i * 8], &src2.s[i * 8]))
+ abort ();
+ }
+
+ /* Check pblendw imm8, xmm, xmm */
+ src3.x = _mm_setzero_si128 ();
+
+ x = _mm_blend_epi16 (dst.x[2], src3.x, MASK);
+ y = _mm_blend_epi16 (src3.x, dst.x[2], MASK);
+
+ if (check_pblendw (&x, &dst.s[16], &src3.s[0]))
+ abort ();
+
+ if (check_pblendw (&y, &src3.s[0], &dst.s[16]))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw.c b/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw.c
new file mode 100644
index 0000000..1c48c76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/sse4_1-pblendw.c
@@ -0,0 +1,89 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mpower8-vector -Wno-psabi" } */
+/* { dg-require-effective-target p8vector_hw } */
+
+#define NO_WARN_X86_INTRINSICS 1
+#ifndef CHECK_H
+#define CHECK_H "sse4_1-check.h"
+#endif
+
+#ifndef TEST
+#define TEST sse4_1_test
+#endif
+
+#include CHECK_H
+
+#include <smmintrin.h>
+#include <string.h>
+
+#define NUM 20
+
+#ifndef MASK
+#define MASK 0x0f
+#endif
+
+static void
+init_pblendw (short *src1, short *src2)
+{
+ int i, sign = 1;
+
+ for (i = 0; i < NUM * 8; i++)
+ {
+ src1[i] = i * i * sign;
+ src2[i] = (i + 20) * sign;
+ sign = -sign;
+ }
+}
+
+static int
+check_pblendw (__m128i *dst, short *src1, short *src2)
+{
+ short tmp[8];
+ int j;
+
+ memcpy (&tmp[0], src1, sizeof (tmp));
+ for (j = 0; j < 8; j++)
+ if ((MASK & (1 << j)))
+ tmp[j] = src2[j];
+
+ return memcmp (dst, &tmp[0], sizeof (tmp));
+}
+
+static void
+TEST (void)
+{
+ __m128i x, y;
+ union
+ {
+ __m128i x[NUM];
+ short s[NUM * 8];
+ } dst, src1, src2;
+ union
+ {
+ __m128i x;
+ short s[8];
+ } src3;
+ int i;
+
+ init_pblendw (src1.s, src2.s);
+
+ /* Check pblendw imm8, m128, xmm */
+ for (i = 0; i < NUM; i++)
+ {
+ dst.x[i] = _mm_blend_epi16 (src1.x[i], src2.x[i], MASK);
+ if (check_pblendw (&dst.x[i], &src1.s[i * 8], &src2.s[i * 8]))
+ abort ();
+ }
+
+ /* Check pblendw imm8, xmm, xmm */
+ src3.x = _mm_setzero_si128 ();
+
+ x = _mm_blend_epi16 (dst.x[2], src3.x, MASK);
+ y = _mm_blend_epi16 (src3.x, dst.x[2], MASK);
+
+ if (check_pblendw (&x, &dst.s[16], &src3.s[0]))
+ abort ();
+
+ if (check_pblendw (&y, &src3.s[0], &dst.s[16]))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c b/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c
index 3c52287..5c7acf1 100644
--- a/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c
+++ b/gcc/testsuite/gcc.target/powerpc/stabs-attrib-vect-darwin.c
@@ -1,5 +1,6 @@
/* Test Attribute Vector associated with vector type stabs. */
/* { dg-do compile { target powerpc*-*-darwin* } } */
+/* { dg-require-effective-target stabs } */
/* { dg-options "-gstabs+ -fno-eliminate-unused-debug-types -faltivec" } */
int main ()
diff --git a/gcc/testsuite/gcc.target/powerpc/volatile-mem.c b/gcc/testsuite/gcc.target/powerpc/volatile-mem.c
new file mode 100644
index 0000000..c8a7444
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/volatile-mem.c
@@ -0,0 +1,16 @@
+/* { dg-options "-O2 -std=c11" } */
+/* { dg-require-effective-target lp64 } */
+
+/* This tests if the instructions used for C atomic are optimised properly
+ as atomic by the target code, too. */
+
+#include <stdatomic.h>
+
+int load(_Atomic int *ptr)
+{
+ return atomic_load_explicit(ptr, memory_order_relaxed);
+}
+
+/* There should be only two machine instructions, an lwa and a blr: */
+/* { dg-final { scan-assembler-times {(?n)^\s+[a-z]} 2 } } */
+/* { dg-final { scan-assembler-times {\mlwa\M} 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c
index 980893f..0f9badd 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-all-nez-7.c
@@ -11,5 +11,5 @@ test_all_not_equal_and_not_zero (vector unsigned short *arg1_p,
vector unsigned short arg_1 = *arg1_p;
vector unsigned short arg_2 = *arg2_p;
- return __builtin_vec_vcmpnez_p (__CR6_LT, arg_1, arg_2); /* { dg-error "builtin function '__builtin_vec_vcmpnez_p' not supported in this compiler configuration" } */
+ return __builtin_vec_vcmpnez_p (__CR6_LT, arg_1, arg_2); /* { dg-error "'__builtin_vec_vcmpnez_p' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c
index 9fdbd5f..c69dfa6 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-any-eqz-7.c
@@ -10,5 +10,5 @@ test_any_equal (vector unsigned int *arg1_p, vector unsigned int *arg2_p)
vector unsigned int arg_1 = *arg1_p;
vector unsigned int arg_2 = *arg2_p;
- return __builtin_vec_vcmpnez_p (__CR6_LT_REV, arg_1, arg_2); /* { dg-error "builtin function '__builtin_vec_vcmpnez_p' not supported in this compiler configuration" } */
+ return __builtin_vec_vcmpnez_p (__CR6_LT_REV, arg_1, arg_2); /* { dg-error "'__builtin_vec_vcmpnez_p' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cmpnez-7.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cmpnez-7.c
index bc906f7..811b32f 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cmpnez-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cmpnez-7.c
@@ -10,5 +10,5 @@ fetch_data (vector unsigned int *arg1_p, vector unsigned int *arg2_p)
vector unsigned int arg_1 = *arg1_p;
vector unsigned int arg_2 = *arg2_p;
- return __builtin_vec_vcmpnez (arg_1, arg_2); /* { dg-error "builtin function '__builtin_altivec_vcmpnezw' requires the '-mcpu=power9' option" } */
+ return __builtin_vec_vcmpnez (arg_1, arg_2); /* { dg-error "'__builtin_altivec_vcmpnezw' requires the '-mcpu=power9' option" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c
index 3364354..6ee066d 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cntlz-lsbb-2.c
@@ -9,5 +9,5 @@ count_leading_zero_byte_bits (vector unsigned char *arg1_p)
{
vector unsigned char arg_1 = *arg1_p;
- return __builtin_vec_vclzlsbb (arg_1); /* { dg-error "builtin function '__builtin_altivec_vclzlsbb_v16qi' requires the '-mcpu=power9' option" } */
+ return __builtin_vec_vclzlsbb (arg_1); /* { dg-error "'__builtin_altivec_vclzlsbb_v16qi' requires the '-mcpu=power9' option" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c
index dfad174..ecd0add 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-cnttz-lsbb-2.c
@@ -9,5 +9,5 @@ count_trailing_zero_byte_bits (vector unsigned char *arg1_p)
{
vector unsigned char arg_1 = *arg1_p;
- return __builtin_vec_vctzlsbb (arg_1); /* { dg-error "builtin function '__builtin_altivec_vctzlsbb_v16qi' requires the '-mcpu=power9' option" } */
+ return __builtin_vec_vctzlsbb (arg_1); /* { dg-error "'__builtin_altivec_vctzlsbb_v16qi' requires the '-mcpu=power9' option" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-12.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-12.c
index 96a04d2..92b0d0dd 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-12.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-12.c
@@ -11,5 +11,5 @@
__vector float
fetch_data (float *address, size_t length)
{
- return __builtin_vec_lxvl (address, length); /* { dg-error "builtin function '__builtin_vsx_lxvl' requires" } */
+ return __builtin_vec_lxvl (address, length); /* { dg-error "'__builtin_vsx_lxvl' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-13.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-13.c
index 04f213a9..9de6424 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-13.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xl-len-13.c
@@ -13,5 +13,5 @@
__vector float
fetch_data (float *address, size_t length)
{
- return __builtin_vec_lxvl (address, length); /* { dg-error "builtin function '__builtin_vec_lxvl' not supported in this compiler configuration" } */
+ return __builtin_vec_lxvl (address, length); /* { dg-error "'__builtin_vec_lxvl' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xlx-7.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xlx-7.c
index 25cd01c..c6f7b5c 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xlx-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xlx-7.c
@@ -10,5 +10,5 @@ fetch_data (unsigned int offset, vector signed int *datap)
{
vector signed int data = *datap;
- return __builtin_vec_vextulx (offset, data); /* { dg-error "builtin function '__builtin_altivec_vextuwlx' requires" } */
+ return __builtin_vec_vextulx (offset, data); /* { dg-error "'__builtin_altivec_vextuwlx' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xrx-7.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xrx-7.c
index 3a27213..fd6b5be 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xrx-7.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xrx-7.c
@@ -10,5 +10,5 @@ fetch_data (unsigned short offset, vector signed short *datap)
{
vector signed short data = *datap;
- return __builtin_vec_vexturx (offset, data); /* { dg-error "builtin function '__builtin_altivec_vextuhrx' requires" } */
+ return __builtin_vec_vexturx (offset, data); /* { dg-error "'__builtin_altivec_vextuhrx' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c
index 992d7b5..3a51132 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-12.c
@@ -13,5 +13,5 @@ store_data (vector double *datap, double *address, size_t length)
{
vector double data = *datap;
- __builtin_vec_stxvl (data, address, length); /* { dg-error "builtin function '__builtin_vec_stxvl' not supported in this compiler configuration" } */
+ __builtin_vec_stxvl (data, address, length); /* { dg-error "'__builtin_vec_stxvl' is not supported in this compiler configuration" } */
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-13.c b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-13.c
index 37b20b0..2a6a7da 100644
--- a/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-13.c
+++ b/gcc/testsuite/gcc.target/powerpc/vsu/vec-xst-len-13.c
@@ -14,5 +14,5 @@ store_data (vector double *datap, double *address, size_t length)
{
vector double data = *datap;
- __builtin_vec_stxvl (data, address, length); /* { dg-error "builtin function '__builtin_altivec_stxvl' requires" } */
+ __builtin_vec_stxvl (data, address, length); /* { dg-error "'__builtin_altivec_stxvl' requires" } */
}
diff --git a/gcc/testsuite/gcc.target/riscv/shift-shift-2.c b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c
index 3f07e77..10a5bb7 100644
--- a/gcc/testsuite/gcc.target/riscv/shift-shift-2.c
+++ b/gcc/testsuite/gcc.target/riscv/shift-shift-2.c
@@ -25,5 +25,17 @@ sub4 (unsigned long i)
{
return (i << 52) >> 52;
}
-/* { dg-final { scan-assembler-times "slli" 4 } } */
-/* { dg-final { scan-assembler-times "srli" 4 } } */
+
+unsigned int
+sub5 (unsigned int i)
+{
+ unsigned int j;
+ j = i >> 24;
+ j = j * (1 << 24);
+ j = i - j;
+ return j;
+}
+/* { dg-final { scan-assembler-times "slli" 5 } } */
+/* { dg-final { scan-assembler-times "srli" 5 } } */
+/* { dg-final { scan-assembler-times "slliw" 1 } } */
+/* { dg-final { scan-assembler-times "srliw" 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/combine-rotate-modulo.c b/gcc/testsuite/gcc.target/s390/combine-rotate-modulo.c
new file mode 100644
index 0000000..6cbbb552
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/combine-rotate-modulo.c
@@ -0,0 +1,36 @@
+/* Check that we do not emit & 63 via risbg for rotating. */
+
+/* { dg-options "-O1 -m64" } */
+
+/* { dg-final { scan-assembler-not "risbg" } } */
+/* { dg-final { scan-assembler-not "nilf" } } */
+
+long shiftl (long in, unsigned long sh)
+{
+ sh %= 64;
+ return (in << sh);
+}
+
+unsigned long shiftll (unsigned long in, unsigned long sh)
+{
+ sh %= 64;
+ return (in << sh);
+}
+
+long shiftr (long in, unsigned long sh)
+{
+ sh %= 64;
+ return (in >> sh);
+}
+
+unsigned long shiftrl (unsigned long in, unsigned long sh)
+{
+ sh %= 64;
+ return (in >> sh);
+}
+
+unsigned long rotlmod (unsigned long in, unsigned long sh)
+{
+ sh %= 64;
+ return (in << sh) | (in >> (64 - sh));
+}
diff --git a/gcc/testsuite/gcc.target/s390/combine-shift-rotate-add-mod.c b/gcc/testsuite/gcc.target/s390/combine-shift-rotate-add-mod.c
new file mode 100644
index 0000000..dc63bfa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/combine-shift-rotate-add-mod.c
@@ -0,0 +1,29 @@
+/* Check shift via address-style displacement. There should not be any
+ and operations that the instructions perform implicitly anyway.*/
+
+/* { dg-options "-O1 -m64" } */
+
+/* { dg-final { scan-assembler-not "risbg\t%r.+,.*63" } } */
+/* { dg-final { scan-assembler "rllg\t%r.+,3.%r.+" } } */
+/* { dg-final { scan-assembler "sllg\t%r.+,2.%r.+" } } */
+
+unsigned long rotlmodp (unsigned long in, unsigned long sh)
+{
+ sh = (sh + 3) % 64;
+ return (in << sh) | (in >> (64 - sh));
+}
+
+unsigned long shiftmodp (unsigned long in, unsigned long sh)
+{
+ sh = (sh + 2) % 64;
+ return (in << sh);
+}
+
+/* We expect a displacement of 1 here since combine simplifies
+ modulo 255 when substituting into a QImode subreg. */
+/* { dg-final { scan-assembler "sllg\t%r.+,1.%r.+" } } */
+unsigned long shiftp (unsigned long in, unsigned long sh)
+{
+ sh = sh + 4097;
+ return (in << sh);
+}
diff --git a/gcc/testsuite/gcc.target/s390/rotate-truncation-mask.c b/gcc/testsuite/gcc.target/s390/rotate-truncation-mask.c
new file mode 100644
index 0000000..1cdd209
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/rotate-truncation-mask.c
@@ -0,0 +1,11 @@
+/* Check that we do not use (64 - sh) for rotating. */
+
+/* { dg-options "-O1 -m64" } */
+
+/* { dg-final { scan-assembler "lcr\t%r.+,%r.+" } } */
+/* { dg-final { scan-assembler-not "lhi\t%r.+,64" } } */
+/* { dg-final { scan-assembler-not "sr\t%r.+,%r.+" } } */
+unsigned long rotr (unsigned long in, unsigned long sh)
+{
+ return (in >> sh) | (in << (64 - sh));
+}
diff --git a/gcc/testsuite/gcc.target/s390/vector/combine-shift-vec.c b/gcc/testsuite/gcc.target/s390/vector/combine-shift-vec.c
new file mode 100644
index 0000000..1ac9496
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/combine-shift-vec.c
@@ -0,0 +1,107 @@
+/* Check vector shift patterns. */
+
+/* { dg-options "-march=z13 -O1 -m64" } */
+
+/* { dg-final { scan-assembler "veslb\t%v.+,%v.+,2.%r2" } } */
+/* { dg-final { scan-assembler "veslh\t%v.+,%v.+,3.%r2" } } */
+/* { dg-final { scan-assembler "veslf\t%v.+,%v.+,4.%r2" } } */
+/* { dg-final { scan-assembler "veslg\t%v.+,%v.+,5.%r2" } } */
+/* { dg-final { scan-assembler "vesrab\t%v.+,%v.+,2.%r2" } } */
+/* { dg-final { scan-assembler "vesrah\t%v.+,%v.+,3.%r2" } } */
+/* { dg-final { scan-assembler "vesraf\t%v.+,%v.+,4.%r2" } } */
+/* { dg-final { scan-assembler "vesrag\t%v.+,%v.+,5.%r2" } } */
+/* { dg-final { scan-assembler "vesrlb\t%v.+,%v.+,2.%r2" } } */
+/* { dg-final { scan-assembler "vesrlh\t%v.+,%v.+,3.%r2" } } */
+/* { dg-final { scan-assembler "vesrlf\t%v.+,%v.+,4.%r2" } } */
+/* { dg-final { scan-assembler "vesrlg\t%v.+,%v.+,5.%r2" } } */
+/* { dg-final { scan-assembler-not "ahi" } } */
+/* { dg-final { scan-assembler-not "nilf" } } */
+/* { dg-final { scan-assembler-not "risbg" } } */
+
+typedef __attribute__((vector_size(16))) signed char v16qi;
+
+v16qi vshiftlqi (v16qi in, unsigned int sh)
+{
+ sh = (sh + 2) % 8;
+ return (in << sh);
+}
+
+typedef __attribute__((vector_size(16))) signed short v8hi;
+
+v8hi vshiftlhi (v8hi in, unsigned int sh)
+{
+ sh = (sh + 3) % 16;
+ return (in << sh);
+}
+
+typedef __attribute__((vector_size(16))) signed int v4si;
+
+v4si vshiftlsi (v4si in, unsigned int sh)
+{
+ sh = (sh + 4) % 32;
+ return (in << sh);
+}
+
+typedef __attribute__((vector_size(16))) signed long v2di;
+
+v2di vshiftldi (v2di in, unsigned int sh)
+{
+ sh = (sh + 5) % 64;
+ return (in << sh);
+}
+
+typedef __attribute__((vector_size(16))) unsigned char uv16qi;
+
+uv16qi vshiftrqiu (uv16qi in, unsigned int sh)
+{
+ sh = (sh + 2) % 8;
+ return (in >> sh);
+}
+
+typedef __attribute__((vector_size(16))) unsigned short uv8hi;
+
+uv8hi vshiftrhiu (uv8hi in, unsigned int sh)
+{
+ sh = (sh + 3) % 16;
+ return (in >> sh);
+}
+
+typedef __attribute__((vector_size(16))) unsigned int uv4si;
+
+uv4si vshiftrsiu (uv4si in, unsigned int sh)
+{
+ sh = (sh + 4) % 32;
+ return (in >> sh);
+}
+
+typedef __attribute__((vector_size(16))) unsigned long uv2di;
+
+uv2di vshiftrdiu (uv2di in, unsigned int sh)
+{
+ sh = (sh + 5) % 64;
+ return (in >> sh);
+}
+
+v16qi vshiftrqi (v16qi in, unsigned int sh)
+{
+ sh = (sh + 2) % 8;
+ return (in >> sh);
+}
+
+v8hi vshiftrhi (v8hi in, unsigned int sh)
+{
+ sh = (sh + 3) % 16;
+ return (in >> sh);
+}
+
+v4si vshiftrsi (v4si in, unsigned int sh)
+{
+ sh = (sh + 4) % 32;
+ return (in >> sh);
+}
+
+v2di vshiftrdi (v2di in, unsigned int sh)
+{
+ sh = (sh + 5) % 64;
+ return (in >> sh);
+}
diff --git a/gcc/testsuite/gfortran.dg/check_bits_1.f90 b/gcc/testsuite/gfortran.dg/check_bits_1.f90
new file mode 100644
index 0000000..1ed3e81
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/check_bits_1.f90
@@ -0,0 +1,49 @@
+! { dg-do run }
+! { dg-options "-fcheck=bits -fdump-tree-original" }
+! { dg-shouldfail "Fortran runtime error: SIZE argument (0) out of range 1:32 in intrinsic ISHFTC" }
+! { dg-output "At line 44 .*" }
+!
+! Verify that the runtime checks for the bit manipulation intrinsic functions
+! do not generate false-positives
+program check
+ implicit none
+ integer :: i, k, pos, len, shift, size, nb
+ nb = bit_size (i)
+ i = 0
+ do pos = 0, nb-1
+ k = ibset (i, pos)
+ i = ibclr (k, pos)
+ if (btest (i, pos)) stop 1
+ end do
+ do pos = 0, nb
+ do len = 0, nb-pos
+ i = ibits (i, pos, len)
+ end do
+ end do
+ do shift = 0, nb
+ k = ishft (i, shift)
+ i = ishft (k, -shift)
+ end do
+ do shift = 0, nb
+ k = shiftl (i, shift) ! Fortran 2008
+ i = shiftr (k, shift)
+ i = shifta (i, shift)
+ k = lshift (i, shift) ! GNU extensions
+ i = rshift (k, shift)
+ end do
+ do shift = 0, nb
+ k = ishftc (i, shift)
+ i = ishftc (k, -shift)
+ do size = max (1,shift), nb
+ k = ishftc (i, shift, size)
+ i = ishftc (k, -shift, size)
+ end do
+ end do
+ size = 0
+ ! The following line should fail with a runtime error:
+ k = ishftc (i, 0, size)
+ ! Should never get here with -fcheck=bits
+ stop 2
+end program check
+
+! { dg-final { scan-tree-dump-times "_gfortran_runtime_error_at" 21 "original" } }
diff --git a/gcc/testsuite/gfortran.dg/initialization_14.f90 b/gcc/testsuite/gfortran.dg/initialization_14.f90
index 4d5b685..aa14377 100644
--- a/gcc/testsuite/gfortran.dg/initialization_14.f90
+++ b/gcc/testsuite/gfortran.dg/initialization_14.f90
@@ -3,18 +3,18 @@
! Dummy arguments are disallowed in initialization expressions in
! elemental functions except as arguments to the intrinsic functions
! BIT_SIZE, KIND, LEN, or to the numeric inquiry functions listed
-! in 13.11.8
+! in 13.11.8 F95, likewise not allowed in F2003, now allowed in F2008.
MODULE TT
INTEGER M
CONTAINS
ELEMENTAL REAL FUNCTION two(N)
INTEGER, INTENT(IN) :: N
- INTEGER, DIMENSION(N) :: scr ! { dg-error "Dummy argument 'n' not allowed in expression" }
+ INTEGER, DIMENSION(N) :: scr ! Now valid under F2008
END FUNCTION
ELEMENTAL REAL FUNCTION twopointfive(N)
INTEGER, INTENT(IN) :: N
- INTEGER, DIMENSION(MAX(N,2)) :: scr ! { dg-error "Dummy argument 'n' not allowed in expression" }
+ INTEGER, DIMENSION(MAX(N,2)) :: scr ! Now valid under F2008
end FUNCTION twopointfive
REAL FUNCTION three(N)
diff --git a/gcc/testsuite/gfortran.dg/initialization_30.f90 b/gcc/testsuite/gfortran.dg/initialization_30.f90
new file mode 100644
index 0000000..ff8436b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/initialization_30.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-std=f95" }
+! PR 20851
+! Dummy arguments are disallowed in initialization expressions in
+! elemental functions except as arguments to the intrinsic functions
+! BIT_SIZE, KIND, LEN, or to the numeric inquiry functions listed
+! in 13.11.8
+MODULE TT
+INTEGER M
+CONTAINS
+ ELEMENTAL REAL FUNCTION two(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(N) :: scr ! { dg-error "Dummy argument 'n' not allowed in expression" }
+ END FUNCTION
+
+ ELEMENTAL REAL FUNCTION twopointfive(N)
+ INTEGER, INTENT(IN) :: N
+ INTEGER, DIMENSION(MAX(N,2)) :: scr ! { dg-error "Dummy argument 'n' not allowed in expression" }
+ end FUNCTION twopointfive
+END MODULE
+END
diff --git a/gcc/testsuite/gfortran.dg/pointer_array_11.f90 b/gcc/testsuite/gfortran.dg/pointer_array_11.f90
new file mode 100644
index 0000000..11885ae
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_array_11.f90
@@ -0,0 +1,90 @@
+! { dg-do run }
+!
+! Test the fix for PR91077 - both the original test and that in comment #4 of the PR.
+!
+! Contribute by Ygal Klein <ygalklein@gmail.com>
+!
+program test
+ implicit none
+ call original
+ call comment_4
+contains
+ subroutine original
+ integer, parameter :: length = 9
+ real(8), dimension(2) :: a, b
+ integer :: i
+ type point
+ real(8) :: x
+ end type point
+
+ type stored
+ type(point), dimension(:), allocatable :: np
+ end type stored
+ type(stored), dimension(:), pointer :: std =>null()
+ allocate(std(1))
+ allocate(std(1)%np(length))
+ std(1)%np(1)%x = 0.3d0
+ std(1)%np(2)%x = 0.3555d0
+ std(1)%np(3)%x = 0.26782d0
+ std(1)%np(4)%x = 0d0
+ std(1)%np(5)%x = 1.555d0
+ std(1)%np(6)%x = 7.3d0
+ std(1)%np(7)%x = 7.8d0
+ std(1)%np(8)%x = 6.3d0
+ std(1)%np(9)%x = 5.5d0
+! do i = 1, 2
+! write(*, "('std(1)%np(',i1,')%x = ',1e22.14)") i, std(1)%np(i)%x
+! end do
+! do i = 1, 2
+! write(*, "('std(1)%np(1:',i1,') = ',9e22.14)") i, std(1)%np(1:i)%x
+! end do
+ a = std(1)%np(1:2)%x
+ b = [std(1)%np(1)%x, std(1)%np(2)%x]
+! print *,a
+! print *,b
+ if (allocated (std(1)%np)) deallocate (std(1)%np)
+ if (associated (std)) deallocate (std)
+ if (norm2(a - b) .gt. 1d-3) stop 1
+ end subroutine
+
+ subroutine comment_4
+ integer, parameter :: length = 2
+ real(8), dimension(length) :: a, b
+ integer :: i
+
+ type point
+ real(8) :: x
+ end type point
+
+ type points
+ type(point), dimension(:), pointer :: np=>null()
+ end type points
+
+ type stored
+ integer :: l
+ type(points), pointer :: nfpoint=>null()
+ end type stored
+
+ type(stored), dimension(:), pointer :: std=>null()
+
+
+ allocate(std(1))
+ allocate(std(1)%nfpoint)
+ allocate(std(1)%nfpoint%np(length))
+ std(1)%nfpoint%np(1)%x = 0.3d0
+ std(1)%nfpoint%np(2)%x = 0.3555d0
+
+! do i = 1, length
+! write(*, "('std(1)%nfpoint%np(',i1,')%x = ',1e22.14)") i, std(1)%nfpoint%np(i)%x
+! end do
+! do i = 1, length
+! write(*, "('std(1)%nfpoint%np(1:',i1,')%x = ',2e22.14)") i, std(1)%nfpoint%np(1:i)%x
+! end do
+ a = std(1)%nfpoint%np(1:2)%x
+ b = [std(1)%nfpoint%np(1)%x, std(1)%nfpoint%np(2)%x]
+ if (associated (std(1)%nfpoint%np)) deallocate (std(1)%nfpoint%np)
+ if (associated (std(1)%nfpoint)) deallocate (std(1)%nfpoint)
+ if (associated (std)) deallocate (std)
+ if (norm2(a - b) .gt. 1d-3) stop 2
+ end subroutine
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pr88833.f90 b/gcc/testsuite/gfortran.dg/pr88833.f90
new file mode 100644
index 0000000..224e6ce
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr88833.f90
@@ -0,0 +1,9 @@
+! { dg-do assemble { target aarch64_asm_sve_ok } }
+! { dg-options "-O3 -march=armv8.2-a+sve --save-temps" }
+
+subroutine foo(x)
+ real :: x(100)
+ x = x + 10
+end subroutine foo
+
+! { dg-final { scan-assembler {\twhilelo\tp[0-9]+\.s, wzr, (w[0-9]+).*\twhilelo\tp[0-9]+\.s, w[0-9]+, \1} } }
diff --git a/gcc/testsuite/gnat.dg/access6.adb b/gcc/testsuite/gnat.dg/access6.adb
new file mode 100644
index 0000000..3956061
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/access6.adb
@@ -0,0 +1,28 @@
+-- { dg-do run }
+-- { dg-options "-gnat12" }
+
+procedure Access6 is
+ type Int_Ref is access all Integer;
+ Ptr : Int_Ref;
+
+ procedure update_ptr (X : access integer) is
+ begin
+ -- Failed accessibility test: supposed to raise a Program_Error
+ Ptr := Int_Ref (X);
+ end;
+
+ procedure bar is
+ ref : access integer := new integer;
+ begin
+ update_ptr (ref);
+ end;
+begin
+ bar;
+
+ -- As the call to bar must raise a Program_Error, the following is not supposed to be executed:
+ raise Constraint_Error;
+
+exception
+ when Program_Error =>
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/access7.adb b/gcc/testsuite/gnat.dg/access7.adb
new file mode 100644
index 0000000..e481312
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/access7.adb
@@ -0,0 +1,79 @@
+-- { dg-do run }
+
+with Interfaces; use Interfaces;
+
+procedure Access7 is
+ type t_p_string is access constant String;
+ subtype t_hash is Unsigned_32;
+
+ -- Return a hash value for a given string
+ function hash(s: String) return t_hash is
+ h: t_hash := 0;
+ g: t_hash;
+ begin
+ for i in s'Range loop
+ h := Shift_Left(h, 4) + t_hash'(Character'Pos(s(i)));
+ g := h and 16#F000_0000#;
+ if (h and g) /= 0 then
+ h := h xor ((Shift_Right(g, 24) and 16#FF#) or g);
+ end if;
+ end loop;
+ return h;
+ end hash;
+
+ type hash_entry is record
+ v: t_p_string;
+ hash: t_hash;
+ next: access hash_entry;
+ end record;
+
+ type hashtable is array(t_hash range <>) of access hash_entry;
+
+ protected pool is
+ procedure allocate (sp: out t_p_string; s: String; h: t_hash);
+ private
+ tab: hashtable(0..199999-1) := (others => null);
+ end pool;
+
+ protected body pool is
+ procedure allocate(sp: out t_p_string; s: String; h: t_hash) is
+ p: access hash_entry;
+ slot: t_hash;
+ begin
+ slot := h mod tab'Length;
+ p := tab(slot);
+ while p /= null loop
+ -- quickly check hash, then length, only then slow comparison
+ if p.hash = h and then p.v.all'Length = s'Length
+ and then p.v.all = s
+ then
+ sp := p.v; -- shared string
+ return;
+ end if;
+ p := p.next;
+ end loop;
+ -- add to table
+ p := new hash_entry'(v => new String'(s),
+ hash => h,
+ next => tab(slot));
+ tab(slot) := p; -- { dg-warning "accessibility check fails|Program_Error will be raised at run time" }
+ sp := p.v; -- shared string
+ end allocate;
+ end pool;
+
+ -- Return the pooled string equal to a given String
+ function new_p_string(s: String) return t_p_string is
+ sp: t_p_string;
+ begin
+ pool.allocate(sp, s, hash(s));
+ return sp;
+ end new_p_string;
+
+ foo_string : t_p_string;
+begin
+ foo_string := new_p_string("foo");
+ raise Constraint_Error;
+exception
+ when Program_Error =>
+ null;
+end Access7;
diff --git a/gcc/testsuite/gnat.dg/addr13.adb b/gcc/testsuite/gnat.dg/addr13.adb
new file mode 100644
index 0000000..91e44ae
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/addr13.adb
@@ -0,0 +1,9 @@
+-- { dg-do compile }
+
+package body Addr13 is
+ procedure Overlay is
+ Over : Integer with Address => Gen_Obj'Address;
+ begin
+ Over := 123;
+ end Overlay;
+end Addr13;
diff --git a/gcc/testsuite/gnat.dg/addr13.ads b/gcc/testsuite/gnat.dg/addr13.ads
new file mode 100644
index 0000000..f1f1646
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/addr13.ads
@@ -0,0 +1,5 @@
+generic
+ Gen_Obj : in out Integer;
+package Addr13 is
+ procedure Overlay;
+end Addr13;
diff --git a/gcc/testsuite/gnat.dg/aggr25.adb b/gcc/testsuite/gnat.dg/aggr25.adb
new file mode 100644
index 0000000..d1bb32a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr25.adb
@@ -0,0 +1,7 @@
+-- { dg-do compile }
+
+package body Aggr25 is
+
+ procedure Foo is null;
+
+end Aggr25;
diff --git a/gcc/testsuite/gnat.dg/aggr25.ads b/gcc/testsuite/gnat.dg/aggr25.ads
new file mode 100644
index 0000000..5637cfe
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr25.ads
@@ -0,0 +1,23 @@
+package Aggr25 is
+
+ type T_A is (A, B , C ,D);
+
+ subtype Has_B_D is T_A with Static_Predicate => Has_B_D in B | D;
+
+ type Obj_T (Kind : T_A) is
+ record
+ case Kind is
+ --OK-- when A | C => null; --OK--
+ when Has_B_D => Value : Boolean;
+ --BAD-- when A | C => null;
+ when others => null;
+ end case;
+ end record;
+
+ type T is access Obj_T;
+
+ Unavailable : constant T := new Obj_T'(Kind => A);
+
+ procedure Foo;
+
+end Aggr25;
diff --git a/gcc/testsuite/gnat.dg/allocator.adb b/gcc/testsuite/gnat.dg/allocator.adb
new file mode 100644
index 0000000..c3840aa
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/allocator.adb
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+
+procedure Allocator is
+ type Object_Type is not null access all Integer;
+ type Object_Array is array (Positive range <>) of Object_Type;
+ type Object_Array_Ptr is access Object_Array;
+ type Data_Ptr is access Object_Array_Ptr;
+ Copy : Data_Ptr := new Object_Array_Ptr;
+begin
+ Copy.all := new Object_Array (1..2);
+end;
diff --git a/gcc/testsuite/gnat.dg/aspect2.adb b/gcc/testsuite/gnat.dg/aspect2.adb
new file mode 100644
index 0000000..acf3329
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aspect2.adb
@@ -0,0 +1,5 @@
+-- { dg-do compile }
+
+package body Aspect2 is
+ procedure Foo is null;
+end Aspect2;
diff --git a/gcc/testsuite/gnat.dg/aspect2.ads b/gcc/testsuite/gnat.dg/aspect2.ads
new file mode 100644
index 0000000..73d3fe0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aspect2.ads
@@ -0,0 +1,30 @@
+with Ada.Containers.Functional_Vectors;
+with Ada.Containers; use Ada.Containers;
+
+generic
+ type Element_Type (<>) is private;
+ type Element_Model (<>) is private;
+ with function Model (X : Element_Type) return Element_Model is <>;
+ with function Copy (X : Element_Type) return Element_Type is <>;
+package Aspect2 with SPARK_Mode is
+ pragma Unevaluated_Use_Of_Old (Allow);
+
+ type Vector is private;
+
+ function Length (V : Vector) return Natural;
+
+ procedure Foo;
+
+private
+ type Element_Access is access Element_Type;
+ type Element_Array is array (Positive range <>) of Element_Access with
+ Dynamic_Predicate => Element_Array'First = 1;
+ type Element_Array_Access is access Element_Array;
+ type Vector is record
+ Top : Natural := 0;
+ Content : Element_Array_Access;
+ end record;
+
+ function Length (V : Vector) return Natural is
+ (V.Top);
+end Aspect2;
diff --git a/gcc/testsuite/gnat.dg/bip_export.adb b/gcc/testsuite/gnat.dg/bip_export.adb
new file mode 100644
index 0000000..2935a84
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/bip_export.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+
+package body Bip_Export is
+ function F return T is
+ begin
+ return Result : constant T := G do
+ null;
+ end return;
+ end F;
+
+ function G return T is
+ begin
+ return (null record);
+ end G;
+end Bip_Export;
diff --git a/gcc/testsuite/gnat.dg/bip_export.ads b/gcc/testsuite/gnat.dg/bip_export.ads
new file mode 100644
index 0000000..dbbecf5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/bip_export.ads
@@ -0,0 +1,6 @@
+package Bip_Export is
+ type T is limited null record;
+ function F return T;
+ pragma Export (C, F);
+ function G return T;
+end Bip_Export;
diff --git a/gcc/testsuite/gnat.dg/class_wide5.adb b/gcc/testsuite/gnat.dg/class_wide5.adb
new file mode 100644
index 0000000..008273f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/class_wide5.adb
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+
+procedure Class_Wide5 is
+ type B is interface;
+ type B_Child is new B with null record;
+ type B_Ptr is access B'Class;
+
+ procedure P (Obj : B_Ptr) is begin null; end;
+begin
+ P (new B_child); -- Test
+end Class_Wide5;
diff --git a/gcc/testsuite/gnat.dg/cpp_constructor.adb b/gcc/testsuite/gnat.dg/cpp_constructor.adb
new file mode 100644
index 0000000..1ecae1b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/cpp_constructor.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+
+with Interfaces.C; use Interfaces.C;
+with Cpp_Constructor_FP;
+with Cpp_Constructor_Useit;
+
+procedure Cpp_Constructor is
+ F : Cpp_Constructor_FP.Class :=
+ Cpp_Constructor_FP.Constructor (Cpp_Constructor_Useit.My_Fn'Access);
+begin
+ null;
+end Cpp_Constructor;
diff --git a/gcc/testsuite/gnat.dg/cpp_constructor2.adb b/gcc/testsuite/gnat.dg/cpp_constructor2.adb
new file mode 100644
index 0000000..3b245b0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/cpp_constructor2.adb
@@ -0,0 +1,19 @@
+-- { dg-do compile }
+
+procedure CPP_Constructor2 is
+
+ package P is
+ type X is tagged limited record
+ A, B, C, D : Integer;
+ end record;
+ pragma Import (Cpp, X);
+
+ procedure F1 (V : X);
+ pragma Import (Cpp, F1);
+
+ function F2 return X; -- { dg-error "C\\+\\+ constructor must have external name or link name" }
+ pragma Cpp_Constructor (F2);
+ end P;
+begin
+ null;
+end CPP_Constructor2;
diff --git a/gcc/testsuite/gnat.dg/cpp_constructor_fp.ads b/gcc/testsuite/gnat.dg/cpp_constructor_fp.ads
new file mode 100644
index 0000000..3ee4b3e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/cpp_constructor_fp.ads
@@ -0,0 +1,10 @@
+with Interfaces.C; use Interfaces.C;
+
+package Cpp_Constructor_FP is
+ type Class is limited record null; end record
+ with Convention => Cpp, Import;
+
+ function Constructor
+ (Fn : access function (Val : int) return int) return Class;
+ pragma Cpp_Constructor (Constructor, External_Name => "foo");
+end Cpp_Constructor_FP;
diff --git a/gcc/testsuite/gnat.dg/cpp_constructor_useit.ads b/gcc/testsuite/gnat.dg/cpp_constructor_useit.ads
new file mode 100644
index 0000000..1f30464
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/cpp_constructor_useit.ads
@@ -0,0 +1,8 @@
+with Interfaces.C; use Interfaces.C;
+
+package Cpp_Constructor_Useit is
+ function My_Fn (Val : int) return int
+ with Convention => Cpp;
+
+ function My_Fn (Val : int) return int is (Val + 1);
+end Cpp_Constructor_Useit;
diff --git a/gcc/testsuite/gnat.dg/default_initial_condition.adb b/gcc/testsuite/gnat.dg/default_initial_condition.adb
new file mode 100644
index 0000000..5ba94a6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/default_initial_condition.adb
@@ -0,0 +1,12 @@
+-- { dg-do run }
+-- { dg-options "-gnata" }
+
+with Default_Initial_Condition_Pack; use Default_Initial_Condition_Pack;
+
+procedure Default_Initial_Condition is
+ Obj : T;
+begin
+ if not DIC_Called then
+ raise Program_Error;
+ end if;
+end Default_Initial_Condition;
diff --git a/gcc/testsuite/gnat.dg/default_initial_condition_pack.adb b/gcc/testsuite/gnat.dg/default_initial_condition_pack.adb
new file mode 100644
index 0000000..abcd491
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/default_initial_condition_pack.adb
@@ -0,0 +1,7 @@
+package body Default_Initial_Condition_Pack is
+ function Is_OK (Val : T) return Boolean is
+ begin
+ DIC_Called := True;
+ return True;
+ end Is_OK;
+end Default_Initial_Condition_Pack;
diff --git a/gcc/testsuite/gnat.dg/default_initial_condition_pack.ads b/gcc/testsuite/gnat.dg/default_initial_condition_pack.ads
new file mode 100644
index 0000000..c461bf2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/default_initial_condition_pack.ads
@@ -0,0 +1,12 @@
+package Default_Initial_Condition_Pack is
+ type T;
+ type T is private
+ with Default_Initial_Condition => Is_OK (T);
+
+ function Is_OK (Val : T) return Boolean;
+
+ DIC_Called : Boolean := False;
+
+private
+ type T is null record;
+end Default_Initial_Condition_Pack;
diff --git a/gcc/testsuite/gnat.dg/dimensions2.adb b/gcc/testsuite/gnat.dg/dimensions2.adb
new file mode 100644
index 0000000..630a44f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/dimensions2.adb
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+
+with Dimensions2_phys; use Dimensions2_phys;
+
+procedure Dimensions2 is
+
+ zero_flow : constant Volumetric_Flow := 0.0 * m**3 / h;
+ type Node_Flow_Scenario_T is array (Positive range <>)
+ of Volumetric_Flow with
+ default_component_value => zero_flow;
+ subtype Max_Node_Flow_Scenario_T
+ is Node_Flow_Scenario_T (Natural (1) .. 48);
+ flow_value_array : Max_Node_Flow_Scenario_T := (1..48 => zero_flow);
+ flow_value_array1 : Max_Node_Flow_Scenario_T
+ := (Max_Node_Flow_Scenario_T'Range=> zero_flow);
+ flow_value_array2 : Max_Node_Flow_Scenario_T := (others => zero_flow);
+
+begin
+ null;
+end Dimensions2;
diff --git a/gcc/testsuite/gnat.dg/dimensions2_phys.ads b/gcc/testsuite/gnat.dg/dimensions2_phys.ads
new file mode 100644
index 0000000..675352a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/dimensions2_phys.ads
@@ -0,0 +1,80 @@
+with ada.numerics.generic_elementary_functions;
+with Dimensions2_real_numbers;
+
+package Dimensions2_Phys is
+
+ type si_type is new Dimensions2_real_numbers.Real with
+ dimension_system =>
+ ((unit_name => meter, unit_symbol => 'm', dim_symbol => 'L'),
+ (unit_name => kilogram, unit_symbol => "kg", dim_symbol => 'M'),
+ (unit_name => second, unit_symbol => 's', dim_symbol => 'T'),
+ (unit_name => ampere, unit_symbol => 'A', dim_symbol => 'I'),
+ (unit_name => kelvin, unit_symbol => 'K', dim_symbol => "Theta"),
+ (unit_name => mole, unit_symbol => "mol", dim_symbol => 'N'),
+ (unit_name => euro, unit_symbol => "EUR", dim_symbol => 'E'));
+
+ subtype distance is Si_Type with
+ dimension => (symbol => 'm', meter => 1, others => 0);
+
+ subtype mass is Si_Type with
+ dimension => (symbol => "kg", kilogram => 1, others => 0);
+
+ subtype time is Si_Type with
+ dimension => (symbol => 's', second => 1, others => 0);
+
+ subtype electric_current is Si_Type with
+ dimension => (symbol => 'A', ampere => 1, others => 0);
+
+ subtype temperature is Si_Type with
+ dimension => (symbol => 'K', kelvin => 1, others => 0);
+
+ subtype amount_of_substance is Si_Type with
+ dimension => (symbol => "mol", mole => 1, others => 0);
+
+ pragma warnings (off, "*assumed to be*");
+ subtype pressure_barg is Dimensions2_real_numbers.Real;
+ m : constant Distance := 1.0;
+ kg : constant Mass := 1.0;
+ s : constant Time := 1.0;
+ a : constant Electric_Current := 1.0;
+ k : constant Temperature := 1.0;
+ mol : constant Amount_Of_Substance := 1.0;
+ min : constant Time := 1.0;
+ h : constant Time := 60.0 * min;
+
+ subtype frequency is Si_Type with
+ dimension => (symbol => "Hz", second => -1, others => 0);
+
+ subtype massflow is Si_Type with
+ dimension => (symbol => "kg/s",
+ kilogram => 1, second => -1, others => 0);
+
+ subtype molar_heat_capacity is Si_Type with
+ dimension => (symbol => "J/(K*mol)", meter => 2, kilogram => 1,
+ second => -2, kelvin => -1, mole => -1, others => 0);
+
+ subtype molar_flow is Si_Type with
+ dimension => (symbol => "mol/s", second => -1, mole => 1, others => 0);
+
+ subtype pressure is Si_Type with
+ dimension =>
+ (symbol => "Pa", meter => -1, kilogram => 1, second => -2, others => 0);
+
+ subtype ratio is Si_Type range 0.0 .. 1.0;
+
+ subtype scalar is Si_Type;
+
+ subtype specific_heat_capacity is Si_Type with
+ dimension => (symbol => "J/(K*kg)", meter => 2, second => -2,
+ kelvin => -1, others => 0);
+
+ subtype speed is Si_Type with
+ dimension => (symbol => "m/s", meter => 1, second => -1, others => 0);
+
+ subtype volume is Si_Type with
+ dimension => (symbol => "m^3", meter => 3, others => 0);
+
+ subtype volumetric_flow is Si_Type with
+ dimension => (symbol => "m^3/s", meter => 3, second => -1, others => 0);
+
+end Dimensions2_Phys;
diff --git a/gcc/testsuite/gnat.dg/dimensions2_real_numbers.ads b/gcc/testsuite/gnat.dg/dimensions2_real_numbers.ads
new file mode 100644
index 0000000..e7cda0b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/dimensions2_real_numbers.ads
@@ -0,0 +1,3 @@
+package Dimensions2_Real_Numbers is
+ type Real is new Long_Float;
+end;
diff --git a/gcc/testsuite/gnat.dg/encode_string1.adb b/gcc/testsuite/gnat.dg/encode_string1.adb
new file mode 100644
index 0000000..f1144ba
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/encode_string1.adb
@@ -0,0 +1,48 @@
+-- { dg-do run }
+
+with Ada.Text_IO; use Ada.Text_IO;
+with Encode_String1_Pkg;
+with GNAT.Encode_String;
+with System.WCh_Con; use System.WCh_Con;
+
+procedure Encode_String1 is
+ High_WS : constant Wide_String (1000 .. 1009) := (others => '1');
+ High_WWS : constant Wide_Wide_String (1000 .. 1009) := (others => '2');
+ Low_WS : constant Wide_String (3 .. 12) := (others => '3');
+ Low_WWS : constant Wide_Wide_String (3 .. 12) := (others => '4');
+
+ procedure Test_Method (Method : WC_Encoding_Method);
+ -- Test Wide_String and Wide_Wide_String encodings using method Method to
+ -- encode them.
+
+ -----------------
+ -- Test_Method --
+ -----------------
+
+ procedure Test_Method (Method : WC_Encoding_Method) is
+ package Encoder is new GNAT.Encode_String (Method);
+
+ procedure WS_Tester is new Encode_String1_Pkg
+ (C => Wide_Character,
+ S => Wide_String,
+ Encode => Encoder.Encode_Wide_String);
+
+ procedure WWS_Tester is new Encode_String1_Pkg
+ (C => Wide_Wide_Character,
+ S => Wide_Wide_String,
+ Encode => Encoder.Encode_Wide_Wide_String);
+ begin
+ WS_Tester (High_WS);
+ WS_Tester (Low_WS);
+
+ WWS_Tester (High_WWS);
+ WWS_Tester (Low_WWS);
+ end Test_Method;
+
+-- Start of processing for Main
+
+begin
+ for Method in WC_Encoding_Method'Range loop
+ Test_Method (Method);
+ end loop;
+end;
diff --git a/gcc/testsuite/gnat.dg/encode_string1_pkg.adb b/gcc/testsuite/gnat.dg/encode_string1_pkg.adb
new file mode 100644
index 0000000..fa969a0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/encode_string1_pkg.adb
@@ -0,0 +1,15 @@
+with Ada.Exceptions; use Ada.Exceptions;
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Encode_String1_Pkg (Val : S) is
+begin
+ declare
+ Result : constant String := Encode (Val);
+ begin
+ Put_Line (Result);
+ end;
+
+exception
+ when Ex : others =>
+ Put_Line ("ERROR: Unexpected exception " & Exception_Name (Ex));
+end;
diff --git a/gcc/testsuite/gnat.dg/encode_string1_pkg.ads b/gcc/testsuite/gnat.dg/encode_string1_pkg.ads
new file mode 100644
index 0000000..ba2d675
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/encode_string1_pkg.ads
@@ -0,0 +1,6 @@
+generic
+ type C is private;
+ type S is array (Positive range <>) of C;
+ with function Encode (Val : S) return String;
+
+procedure Encode_String1_Pkg (Val : S);
diff --git a/gcc/testsuite/gnat.dg/entry1.adb b/gcc/testsuite/gnat.dg/entry1.adb
new file mode 100644
index 0000000..7577a26
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/entry1.adb
@@ -0,0 +1,75 @@
+-- { dg-do compile }
+-- { dg-options "-gnateF" }
+
+PACKAGE BODY Entry1 IS
+
+ PROTECTED TYPE key_buffer IS
+
+ PROCEDURE clear;
+
+ ENTRY incr;
+ ENTRY put (val : IN Natural);
+ ENTRY get (val : OUT Natural);
+
+ PRIVATE
+
+ -- Stores Key states (key state controller)
+ -- purpose: exclusive access
+ max_len : Natural := 10;
+
+ cnt : Natural := 0;
+
+ END key_buffer;
+
+ PROTECTED BODY key_buffer IS
+
+ PROCEDURE clear IS
+ BEGIN
+ cnt := 0;
+ END clear;
+
+ ENTRY incr WHEN cnt < max_len IS
+ BEGIN
+ cnt := cnt + 1;
+ END;
+
+ ENTRY put (val : IN Natural) WHEN cnt < max_len IS
+ BEGIN
+ cnt := val;
+ END put;
+
+ ENTRY get (val : OUT Natural) WHEN cnt > 0 IS
+ BEGIN
+ val := cnt;
+ END get;
+
+ END key_buffer;
+
+ my_buffer : key_buffer;
+
+ FUNCTION pt2 (t : IN Float) RETURN Natural IS
+ c : Natural;
+ t2 : duration := duration (t);
+ BEGIN
+ SELECT
+ my_buffer.get (c);
+ RETURN c;
+ OR
+ DELAY t2;
+ RETURN 0;
+ END SELECT;
+ END pt2;
+
+ FUNCTION pt (t : IN Float) RETURN Natural IS
+ c : Natural;
+ BEGIN
+ SELECT
+ my_buffer.get (c);
+ RETURN c;
+ OR
+ DELAY Duration (t);
+ RETURN 0;
+ END SELECT;
+ END pt;
+
+END Entry1;
diff --git a/gcc/testsuite/gnat.dg/entry1.ads b/gcc/testsuite/gnat.dg/entry1.ads
new file mode 100644
index 0000000..7dcc7b5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/entry1.ads
@@ -0,0 +1,4 @@
+PACKAGE Entry1 IS
+ FUNCTION pt (t : IN Float) RETURN Natural;
+ FUNCTION pt2 (t : IN Float) RETURN Natural;
+END Entry1;
diff --git a/gcc/testsuite/gnat.dg/enum_val1.adb b/gcc/testsuite/gnat.dg/enum_val1.adb
new file mode 100644
index 0000000..4550c11
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/enum_val1.adb
@@ -0,0 +1,22 @@
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Enum_Val1 is
+ type Enum is (Two, Four);
+ for Enum use (2, 4);
+
+ Count : Natural := 0;
+
+begin
+ for I in 10 .. 11 loop
+ begin
+ Put (Integer'Image (I) & ": ");
+ Put_Line (Enum'Image (Enum'Enum_Val (I)));
+ exception
+ when Constraint_Error =>
+ Count := Count + 1;
+ end;
+ end loop;
+ if Count /= 2 then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/equal6.adb b/gcc/testsuite/gnat.dg/equal6.adb
new file mode 100644
index 0000000..dea772f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal6.adb
@@ -0,0 +1,29 @@
+-- { dg-do run }
+with Text_IO;
+with Equal6_Types; use Equal6_Types;
+
+procedure Equal6 is
+ Packets_In : To_Evc_Optional_Packet_List_T;
+ Packets_Out : To_Evc_Optional_Packet_List_T;
+begin
+ Packets_In.list (1) :=
+ (Data_Used_Outside_Ertms_System =>
+ (Mail_Box =>
+ (Receiver => 31,
+ Data => (Length => 12, Message => (0, others => 0)))));
+
+ Packets_Out.list (1) :=
+ (Data_Used_Outside_Ertms_System =>
+ (Mail_Box =>
+ (Receiver => 31,
+ Data => (Length => 12, Message => (0, others => 1)))));
+
+ if not (Packets_In = Packets_Out) then
+ raise Program_Error;
+ end if;
+
+ if not (Equal1_Called and then Equal2_Called) then
+ raise Program_Error;
+ end if;
+
+end Equal6;
diff --git a/gcc/testsuite/gnat.dg/equal6_types.adb b/gcc/testsuite/gnat.dg/equal6_types.adb
new file mode 100644
index 0000000..7105b07
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal6_types.adb
@@ -0,0 +1,15 @@
+package body Equal6_Types is
+
+ function "=" (L, R : in Mail_Box_Data_T) return Boolean is
+ use type Bits_T;
+ begin
+ Equal1_Called := True;
+ return L.Message (1) = R.Message (1);
+ end "=";
+
+ function "=" (L, R : in To_Evc_Optional_Packet_List_T) return Boolean is
+ begin
+ Equal2_Called := True;
+ return L.List (1) = R.List (1);
+ end "=";
+end Equal6_Types;
diff --git a/gcc/testsuite/gnat.dg/equal6_types.ads b/gcc/testsuite/gnat.dg/equal6_types.ads
new file mode 100644
index 0000000..90ec52bb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal6_types.ads
@@ -0,0 +1,49 @@
+package Equal6_Types is
+ type Bit_T is range 0 .. 1;
+
+ type Bits_T is array (Positive range <>) of Bit_T;
+
+ type Nid_Xuser_T is range 0 .. 511;
+
+ Dispatch_P44_To_Ntc_C : constant Nid_Xuser_T := 102;
+
+ type Mail_Box_Data_T is record
+ Length : Natural;
+ Message : Bits_T (1 .. 200);
+ end record;
+ function "=" (L, R : in Mail_Box_Data_T) return Boolean;
+ Equal1_Called : Boolean := False;
+
+ type Mail_Box_T (Receiver : Nid_Xuser_T := Nid_Xuser_T'First) is record
+ Data : Mail_Box_Data_T;
+ case Receiver is
+ when Dispatch_P44_To_Ntc_C =>
+ Stm_Id : Positive;
+ when others =>
+ null;
+ end case;
+ end record;
+
+ type Data_Used_Outside_Ertms_System_T is record
+ Mail_Box : Mail_Box_T;
+ end record;
+
+ type To_Evc_Optional_Packet_T
+ is record
+ Data_Used_Outside_Ertms_System : Data_Used_Outside_Ertms_System_T;
+ end record;
+
+ type To_Evc_Optional_Packet_List_Length_T is range 0 .. 50;
+ type To_Evc_Optional_Packet_Map_T is
+ array
+ (To_Evc_Optional_Packet_List_Length_T range <>)
+ of To_Evc_Optional_Packet_T;
+
+ type To_Evc_Optional_Packet_List_T is record
+ List : To_Evc_Optional_Packet_Map_T
+ (1 .. To_Evc_Optional_Packet_List_Length_T'Last);
+ end record;
+ function "=" (L, R : in To_Evc_Optional_Packet_List_T) return Boolean;
+ Equal2_Called : Boolean := False;
+
+end Equal6_Types;
diff --git a/gcc/testsuite/gnat.dg/equal7.adb b/gcc/testsuite/gnat.dg/equal7.adb
new file mode 100644
index 0000000..2b27842
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal7.adb
@@ -0,0 +1,15 @@
+-- { dg-do run }
+
+with Equal7_Pkg; use Equal7_Pkg;
+with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
+procedure Equal7 is
+ X : constant Integer := 42;
+
+begin
+ if F (X) /= "" & ASCII.LF then
+ null;
+ end if;
+ if not (F (X) = "" & ASCII.LF) then
+ null;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/equal7_pkg.adb b/gcc/testsuite/gnat.dg/equal7_pkg.adb
new file mode 100644
index 0000000..171343f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal7_pkg.adb
@@ -0,0 +1,14 @@
+package body Equal7_Pkg is
+
+ function F (X : Integer) return String is
+ begin
+ return To_String (F (X));
+ end F;
+
+ function F (X : Integer) return Unbounded_String is
+ Result : Unbounded_String;
+ begin
+ Append (Result, "hello" & X'Img);
+ return Result;
+ end;
+end;
diff --git a/gcc/testsuite/gnat.dg/equal7_pkg.ads b/gcc/testsuite/gnat.dg/equal7_pkg.ads
new file mode 100644
index 0000000..8fd601c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal7_pkg.ads
@@ -0,0 +1,16 @@
+with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
+with Ada.Finalization; use Ada.Finalization;
+package Equal7_Pkg is
+
+ type Editor_Location is abstract new Controlled with null record;
+ Nil_Editor_Location : constant Editor_Location'Class;
+
+ function F (X : Integer) return Unbounded_String;
+ function F (X : Integer) return String;
+
+private
+ type Dummy_Editor_Location is new Editor_Location with null record;
+
+ Nil_Editor_Location : constant Editor_Location'Class :=
+ Dummy_Editor_Location'(Controlled with null record);
+end;
diff --git a/gcc/testsuite/gnat.dg/equal8.adb b/gcc/testsuite/gnat.dg/equal8.adb
new file mode 100644
index 0000000..9424abc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal8.adb
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+package body Equal8 is
+ procedure Foo is null;
+end Equal8;
diff --git a/gcc/testsuite/gnat.dg/equal8.ads b/gcc/testsuite/gnat.dg/equal8.ads
new file mode 100644
index 0000000..9b6694d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal8.ads
@@ -0,0 +1,36 @@
+with Ada.Containers.Formal_Hashed_Sets;
+with Ada.Strings.Hash;
+
+-- with Dynamic_Strings; use Dynamic_Strings;
+-- with Bounded_Dynamic_Strings;
+
+with Equal8_Pkg;
+
+package Equal8 is
+
+ package Dynamic_Strings is
+ -- pragma SPARK_Mode (On);
+
+ package Bounded_Dynamic_Strings is new Equal8_Pkg
+ (Component => Character,
+ List_Index => Positive,
+ List => String,
+ Default_Value => ' ');
+ type Dynamic_String is new Bounded_Dynamic_Strings.Sequence;
+
+ end Dynamic_Strings;
+ use Dynamic_Strings;
+
+ subtype Subscription_Address is Dynamic_String (Capacity => 255);
+
+ function Hashed_Subscription_Address (Element : Subscription_Address)
+ return Ada.Containers.Hash_Type is
+ (Ada.Strings.Hash (Value (Element)));
+
+ package Subscription_Addresses is new Ada.Containers.Formal_Hashed_Sets
+ (Element_Type => Subscription_Address,
+ Hash => Hashed_Subscription_Address,
+ Equivalent_Elements => "=");
+
+ procedure Foo;
+end Equal8;
diff --git a/gcc/testsuite/gnat.dg/equal8_pkg.ads b/gcc/testsuite/gnat.dg/equal8_pkg.ads
new file mode 100644
index 0000000..b454a2c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal8_pkg.ads
@@ -0,0 +1,58 @@
+generic
+ type Component is private;
+ type List_Index is range <>;
+ type List is array (List_Index range <>) of Component;
+ Default_Value : Component;
+ -- with function "=" (Left, Right : List) return Boolean is <>;
+
+package Equal8_Pkg is
+
+ pragma Pure;
+
+ Maximum_Length : constant List_Index := List_Index'Last;
+
+ subtype Natural_Index is List_Index'Base range 0 .. Maximum_Length;
+ type Sequence (Capacity : Natural_Index) is private;
+ -- from zero to Capacity.
+
+ function Value (This : Sequence) return List;
+ -- Returns the content of this sequence. The value returned is the
+ -- "logical" value in that only that slice which is currently assigned
+ -- is returned, as opposed to the entire physical representation.
+
+ overriding
+ function "=" (Left, Right : Sequence) return Boolean with
+ Inline;
+
+ function "=" (Left : Sequence; Right : List) return Boolean with
+ Inline;
+
+private
+ type Sequence (Capacity : Natural_Index) is record
+ Current_Length : Natural_Index := 0;
+ Content : List (1 .. Capacity) := (others => Default_Value);
+ end record;
+
+ -----------
+ -- Value --
+ -----------
+
+ function Value (This : Sequence) return List is
+ (This.Content (1 .. This.Current_Length));
+
+ ---------
+ -- "=" --
+ ---------
+
+ overriding
+ function "=" (Left, Right : Sequence) return Boolean is
+ (Value (Left) = Value (Right));
+
+ ---------
+ -- "=" --
+ ---------
+
+ function "=" (Left : Sequence; Right : List) return Boolean is
+ (Value (Left) = Right);
+end Equal8_Pkg;
+
diff --git a/gcc/testsuite/gnat.dg/equal9.adb b/gcc/testsuite/gnat.dg/equal9.adb
new file mode 100644
index 0000000..aa60d5b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal9.adb
@@ -0,0 +1,26 @@
+-- { dg-do run }
+
+with Ada.Text_IO; use Ada.Text_IO;
+with System; use System;
+
+procedure Equal9 is
+ Val : Address := Null_Address;
+begin
+ if Val = Null_Address then
+ Put_Line ("= OK");
+ else
+ raise Program_Error;
+ end if;
+
+ if Val /= Null_Address then
+ raise Program_Error;
+ else
+ Put_Line ("/= OK");
+ end if;
+
+ if not (Val = Null_Address) then
+ raise Program_Error;
+ else
+ Put_Line ("not = OK");
+ end if;
+end Equal9;
diff --git a/gcc/testsuite/gnat.dg/fixed_delete.adb b/gcc/testsuite/gnat.dg/fixed_delete.adb
new file mode 100644
index 0000000..c13c71c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/fixed_delete.adb
@@ -0,0 +1,17 @@
+-- { dg-do run }
+
+with Ada.Text_IO; use Ada.Text_IO;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+
+procedure Fixed_Delete is
+ Str : String := "a";
+ Str1 : String := Replace_Slice (Str, 2, 2, "");
+ Str2 : String := Delete (Str, 2, 2);
+begin
+ if Str1 /= "a" then
+ raise Program_Error;
+ end if;
+ if Str2 /= "a" then
+ raise Program_Error;
+ end if;
+end Fixed_Delete;
diff --git a/gcc/testsuite/gnat.dg/fixedpnt6.adb b/gcc/testsuite/gnat.dg/fixedpnt6.adb
new file mode 100644
index 0000000..01c1747
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/fixedpnt6.adb
@@ -0,0 +1,21 @@
+-- { dg-do run }
+-- { dg-options "-O0" }
+
+procedure Fixedpnt6 is
+
+ type T is delta 0.125 range -2.0 .. 1.875;
+
+ function Mult (A, B : T) return T is
+ begin
+ return T (A * B);
+ end;
+
+ R : T;
+
+begin
+ R := Mult (T'Last, T'Last);
+ raise Program_Error;
+exception
+ when Constraint_Error =>
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/float_value1.adb b/gcc/testsuite/gnat.dg/float_value1.adb
new file mode 100644
index 0000000..8e36767
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/float_value1.adb
@@ -0,0 +1,46 @@
+-- { dg-do run }
+
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+
+procedure Float_Value1 is
+ Str1 : String := "0." & 50000 * "4";
+ Str2 : String := "1." & 5000 * "4";
+ Str3 : String := "16#0." & 500000 * "4" & "#";
+ Str4 : String := "1" & (5000 * "0") & "E-5000";
+ Str5 : String := "1" & "." & 50000 * "0" & "1";
+ Str6 : String := 50000 * "0" & "." & 50000 * "2" & "1";
+ Str7 : String := "1" & (5000 * "0") & "1" & "E-5000";
+ Str8 : String := "16#1" & "." & 50000 * "0" & "1#";
+
+ procedure Test (Msg, Str, Expected : String) is
+ Number : Long_Long_Float;
+ begin
+ Number := Long_Long_Float'Value (Str);
+ if Number'Img /= Expected then
+ raise Program_Error;
+ end if;
+ end Test;
+
+begin
+ Test ("0.4444...[50000 times] ", Str1, " 4.44444444444444444E-01");
+ Test ("1.4...[5000 times] ", Str2, " 1.44444444444444444E+00");
+ Test ("16#0.[50000 '4']# ", Str3, " 2.66666666666666667E-01");
+ Test ("1[5000 zeros]E-5000 ", Str4, " 1.00000000000000000E+00");
+ Test ("1.[50000zeros]1 ", Str5, " 1.00000000000000000E+00");
+ Test ("[50000zeros].[50000 '2']1", Str6, " 2.22222222222222222E-01");
+ Test ("1[50000zeros]1.E-5000 ", Str7, " 1.00000000000000000E+01");
+ Test ("16#1.[50000zeros]1# ", Str8, " 1.00000000000000000E+00");
+
+ -- Check that number of trailing zero after point does not change
+ -- the value
+
+ for J in 1 .. 10000 loop
+ declare
+ Str : String := "0.1" & J * "0";
+ begin
+ if Long_Long_Float'Value (Str) /= 0.1 then
+ raise Program_Error;
+ end if;
+ end;
+ end loop;
+end Float_Value1;
diff --git a/gcc/testsuite/gnat.dg/generic_inst4.adb b/gcc/testsuite/gnat.dg/generic_inst4.adb
new file mode 100644
index 0000000..c1b2496
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst4.adb
@@ -0,0 +1,7 @@
+-- { dg-do compile }
+
+with Generic_Inst4_Inst;
+procedure Generic_Inst4 is
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst4_gen.ads b/gcc/testsuite/gnat.dg/generic_inst4_gen.ads
new file mode 100644
index 0000000..a1c039e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst4_gen.ads
@@ -0,0 +1,3 @@
+generic
+ Param : String;
+package Generic_Inst4_Gen is end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst4_inst.ads b/gcc/testsuite/gnat.dg/generic_inst4_inst.ads
new file mode 100644
index 0000000..1660d67
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst4_inst.ads
@@ -0,0 +1,5 @@
+with Generic_Inst4_Gen;
+with Generic_Inst4_Typ; use Generic_Inst4_Typ;
+package Generic_Inst4_Inst is new Generic_Inst4_Gen (
+ Param => "SHARING;" & -- ERROR
+ Generic_Inst4_Typ.New_Int'image (Generic_Inst4_Typ.T'size/8));
diff --git a/gcc/testsuite/gnat.dg/generic_inst4_typ.ads b/gcc/testsuite/gnat.dg/generic_inst4_typ.ads
new file mode 100644
index 0000000..5f80029
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst4_typ.ads
@@ -0,0 +1,7 @@
+package Generic_Inst4_Typ is
+ subtype New_Int is Natural;
+ type T is
+ record
+ X : Integer;
+ end record;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst5.adb b/gcc/testsuite/gnat.dg/generic_inst5.adb
new file mode 100644
index 0000000..25e92f0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst5.adb
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+
+procedure Generic_Inst5 is
+ generic
+ package G1 is
+ end G1;
+
+ generic
+ with package I1 is new G1;
+ package G2 is
+ end G2;
+
+ package body G1 is
+ package I2 is new G2 (I1 => G1);
+ end G1;
+
+ package I1 is new G1;
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst6.adb b/gcc/testsuite/gnat.dg/generic_inst6.adb
new file mode 100644
index 0000000..780fae9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst6.adb
@@ -0,0 +1,9 @@
+-- { dg-do run }
+with Text_IO; use Text_IO;
+with Generic_Inst6_I2;
+procedure Generic_Inst6 is
+begin
+ if Generic_Inst6_I2.Check /= 49 then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst6_g1-c.adb b/gcc/testsuite/gnat.dg/generic_inst6_g1-c.adb
new file mode 100644
index 0000000..ed671f1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst6_g1-c.adb
@@ -0,0 +1,6 @@
+with Generic_Inst6_X;
+package body Generic_Inst6_G1.C is
+ package N is new Generic_Inst6_X
+ (Generic_Inst6_G1, Generic_Inst6_G1);
+ function Check return Integer is (N.Result);
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst6_g1-c.ads b/gcc/testsuite/gnat.dg/generic_inst6_g1-c.ads
new file mode 100644
index 0000000..c00d19d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst6_g1-c.ads
@@ -0,0 +1,3 @@
+generic package Generic_Inst6_G1.C is
+ function Check return Integer;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst6_g1.ads b/gcc/testsuite/gnat.dg/generic_inst6_g1.ads
new file mode 100644
index 0000000..9beeb21
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst6_g1.ads
@@ -0,0 +1,3 @@
+generic package Generic_Inst6_G1 is
+ Val : Integer := 7;
+ end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst6_i1.ads b/gcc/testsuite/gnat.dg/generic_inst6_i1.ads
new file mode 100644
index 0000000..016dfb7
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst6_i1.ads
@@ -0,0 +1,2 @@
+with Generic_Inst6_G1;
+package Generic_Inst6_I1 is new Generic_Inst6_G1;
diff --git a/gcc/testsuite/gnat.dg/generic_inst6_i2.ads b/gcc/testsuite/gnat.dg/generic_inst6_i2.ads
new file mode 100644
index 0000000..03abe22
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst6_i2.ads
@@ -0,0 +1,2 @@
+with Generic_Inst6_I1, Generic_Inst6_G1.C;
+package Generic_Inst6_I2 is new Generic_Inst6_I1.C;
diff --git a/gcc/testsuite/gnat.dg/generic_inst6_x.ads b/gcc/testsuite/gnat.dg/generic_inst6_x.ads
new file mode 100644
index 0000000..657dc41
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst6_x.ads
@@ -0,0 +1,7 @@
+with Generic_Inst6_G1;
+generic
+ with package G2 is new Generic_Inst6_G1 (<>);
+ with package G3 is new Generic_Inst6_G1 (<>);
+package Generic_Inst6_X is
+ Result : Integer := G2.Val * G3.Val;
+end;
diff --git a/gcc/testsuite/gnat.dg/ghost5.adb b/gcc/testsuite/gnat.dg/ghost5.adb
new file mode 100644
index 0000000..8aad8d4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/ghost5.adb
@@ -0,0 +1,5 @@
+-- { dg-do compile }
+
+package body Ghost5 is
+ procedure Foo is null;
+end Ghost5;
diff --git a/gcc/testsuite/gnat.dg/ghost5.ads b/gcc/testsuite/gnat.dg/ghost5.ads
new file mode 100644
index 0000000..f58ff39
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/ghost5.ads
@@ -0,0 +1,5 @@
+with Ghost5_Parent;
+generic
+package Ghost5 is
+ procedure Foo;
+end Ghost5;
diff --git a/gcc/testsuite/gnat.dg/ghost5_parent.ads b/gcc/testsuite/gnat.dg/ghost5_parent.ads
new file mode 100644
index 0000000..cab7f31
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/ghost5_parent.ads
@@ -0,0 +1,14 @@
+package Ghost5_Parent is
+
+ type Priv is private;
+
+ package Nested with Ghost is
+ function Func1 (X : Priv) return Boolean is (True); -- Error flagged here
+ function Func2 (X : Priv) return Boolean is (False);
+ end Nested;
+
+private
+
+ type Priv is new Integer;
+
+end Ghost5_Parent;
diff --git a/gcc/testsuite/gnat.dg/ghost6.adb b/gcc/testsuite/gnat.dg/ghost6.adb
new file mode 100644
index 0000000..01a2417
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/ghost6.adb
@@ -0,0 +1,10 @@
+-- { dg-do link }
+-- { dg-options "-gnata -g" }
+
+with Ghost6_Pkg;
+
+procedure Ghost6 is
+ X : Ghost6_Pkg.T with Ghost;
+begin
+ null;
+end Ghost6;
diff --git a/gcc/testsuite/gnat.dg/ghost6_pkg.ads b/gcc/testsuite/gnat.dg/ghost6_pkg.ads
new file mode 100644
index 0000000..7fbd942
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/ghost6_pkg.ads
@@ -0,0 +1,7 @@
+with Ada.Finalization;
+
+package Ghost6_Pkg with
+ Ghost
+is
+ type T is new Ada.Finalization.Controlled with null record;
+end Ghost6_Pkg;
diff --git a/gcc/testsuite/gnat.dg/image1.adb b/gcc/testsuite/gnat.dg/image1.adb
new file mode 100644
index 0000000..ae8d680
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/image1.adb
@@ -0,0 +1,12 @@
+-- { dg-do run }
+
+with Ada.Text_IO; use Ada.Text_IO;
+with Ada.Characters.Latin_1;
+
+procedure Image1 is
+ Str : String := Ada.Characters.Latin_1.LF'Img;
+begin
+ if Str /= "LF" then
+ raise Program_Error;
+ end if;
+end Image1;
diff --git a/gcc/testsuite/gnat.dg/incomplete7.adb b/gcc/testsuite/gnat.dg/incomplete7.adb
new file mode 100644
index 0000000..34accbe
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/incomplete7.adb
@@ -0,0 +1,5 @@
+-- { dg-do compile }
+
+package body Incomplete7 is
+ procedure Foo is null;
+end Incomplete7;
diff --git a/gcc/testsuite/gnat.dg/incomplete7.ads b/gcc/testsuite/gnat.dg/incomplete7.ads
new file mode 100644
index 0000000..3c1ade7
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/incomplete7.ads
@@ -0,0 +1,31 @@
+package Incomplete7 is
+ type Color;
+ type Color is (red, green, blue);
+
+ type Action (C : Color := Color'(red));
+ type Action (C : Color := Color'(red)) is record
+ case C is
+ when red =>
+ Stop_Time : Positive;
+
+ when others =>
+ Go_For_It : Integer;
+ end case;
+ end record;
+
+ type Num;
+ type Num is new Integer;
+
+ type Rec (N : Num := Num'(1));
+ type Rec (N : Num := Num'(1)) is record
+ case N is
+ when 1 =>
+ One : Integer;
+
+ when others =>
+ null;
+ end case;
+ end record;
+
+ procedure Foo;
+end Incomplete7;
diff --git a/gcc/testsuite/gnat.dg/inline17.adb b/gcc/testsuite/gnat.dg/inline17.adb
new file mode 100644
index 0000000..bb6e5c2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline17.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatn" }
+with Inline17_Pkg1; use Inline17_Pkg1;
+with Inline17_Pkg2; use Inline17_Pkg2;
+
+procedure Inline17 is
+ use type SQL_Field;
+begin
+ Test;
+end;
diff --git a/gcc/testsuite/gnat.dg/inline17_pkg1.adb b/gcc/testsuite/gnat.dg/inline17_pkg1.adb
new file mode 100644
index 0000000..80febe8
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline17_pkg1.adb
@@ -0,0 +1,15 @@
+with Inline17_Pkg2; use Inline17_Pkg2;
+
+package body Inline17_Pkg1 is
+
+ procedure Test is
+ begin
+ null;
+ end;
+
+ function Get (Field : SQL_Field) return Integer is
+ begin
+ return +Field;
+ end;
+
+end Inline17_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/inline17_pkg1.ads b/gcc/testsuite/gnat.dg/inline17_pkg1.ads
new file mode 100644
index 0000000..78f26b1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline17_pkg1.ads
@@ -0,0 +1,7 @@
+
+package Inline17_Pkg1 is
+
+ procedure Test;
+ pragma Inline (Test);
+
+end Inline17_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/inline17_pkg2.ads b/gcc/testsuite/gnat.dg/inline17_pkg2.ads
new file mode 100644
index 0000000..bf89d55
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline17_pkg2.ads
@@ -0,0 +1,10 @@
+with Inline17_Pkg3; use Inline17_Pkg3;
+
+package Inline17_Pkg2 is
+
+ subtype SQL_Field is Inline17_Pkg3.SQL_Field;
+
+ function "+" (Field : SQL_Field'Class) return Integer renames
+ Inline17_Pkg3."+";
+
+end Inline17_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/inline17_pkg3.adb b/gcc/testsuite/gnat.dg/inline17_pkg3.adb
new file mode 100644
index 0000000..411a509
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline17_pkg3.adb
@@ -0,0 +1,14 @@
+
+package body Inline17_Pkg3 is
+
+ function "+" (Field : SQL_Field'Class) return Integer is
+ begin
+ return 0;
+ end;
+
+ function Unchecked_Get (Self : Ref) return Integer is
+ begin
+ return Self.Data;
+ end;
+
+end Inline17_Pkg3;
diff --git a/gcc/testsuite/gnat.dg/inline17_pkg3.ads b/gcc/testsuite/gnat.dg/inline17_pkg3.ads
new file mode 100644
index 0000000..6f0c5a8
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline17_pkg3.ads
@@ -0,0 +1,16 @@
+
+package Inline17_Pkg3 is
+
+ type SQL_Field is tagged null record;
+
+ function "+" (Field : SQL_Field'Class) return Integer;
+
+ type Ref is record
+ Data : Integer;
+ end record;
+
+ function Unchecked_Get (Self : Ref) return Integer with Inline_Always;
+
+ function Get (Self : Ref) return Integer is (Unchecked_Get (Self));
+
+end Inline17_Pkg3;
diff --git a/gcc/testsuite/gnat.dg/interface10.adb b/gcc/testsuite/gnat.dg/interface10.adb
new file mode 100644
index 0000000..7433454
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/interface10.adb
@@ -0,0 +1,22 @@
+-- { dg-do run }
+-- { dg-options "-gnata" }
+
+with Ada.Text_IO;
+
+procedure Interface10 is
+
+ type Iface is interface;
+
+ type My_First_Type is new Iface with null record;
+ type My_Second_Type is new Iface with null record;
+
+ procedure Do_Test (Object : in Iface'Class) is
+ begin
+ pragma Assert
+ ((Object in My_First_Type) = (Object in My_First_Type'Class));
+ end;
+
+ V : My_Second_Type;
+begin
+ Do_Test (V);
+end Interface10;
diff --git a/gcc/testsuite/gnat.dg/interface9.adb b/gcc/testsuite/gnat.dg/interface9.adb
new file mode 100644
index 0000000..ec46e20
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/interface9.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+with Interface9_Root.Child;
+procedure Interface9 is
+ package R is new Interface9_Root (Real => Float);
+ package RC is new R.Child;
+
+begin
+ null;
+end Interface9;
diff --git a/gcc/testsuite/gnat.dg/interface9_root-child.ads b/gcc/testsuite/gnat.dg/interface9_root-child.ads
new file mode 100644
index 0000000..0440ddb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/interface9_root-child.ads
@@ -0,0 +1,7 @@
+generic
+package Interface9_Root.Child is
+ type Base_Type is abstract new Base_Interface with null record;
+
+ type Derived_Type is abstract new Base_Type and Derived_Interface
+ with null record; -- Test
+end Interface9_Root.Child;
diff --git a/gcc/testsuite/gnat.dg/interface9_root.ads b/gcc/testsuite/gnat.dg/interface9_root.ads
new file mode 100644
index 0000000..2e64e5b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/interface9_root.ads
@@ -0,0 +1,10 @@
+generic
+ type Real is digits <>;
+package Interface9_Root is
+ type Base_Interface is limited interface;
+
+ procedure Primitive1 (B : in out Base_Interface) is abstract;
+ procedure Primitive2 (B : in out Base_Interface) is null;
+
+ type Derived_Interface is limited interface and Base_Interface;
+end Interface9_Root;
diff --git a/gcc/testsuite/gnat.dg/iter5.adb b/gcc/testsuite/gnat.dg/iter5.adb
new file mode 100644
index 0000000..fa21715
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/iter5.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+with Iter5_Pkg;
+
+procedure Iter5 is
+begin
+ for The_Filename of Iter5_Pkg.Iterator_For ("C:\Program_Files") loop -- { dg-error "cannot iterate over \"Item\"" }
+ null;
+ end loop;
+end Iter5;
diff --git a/gcc/testsuite/gnat.dg/iter5_pkg.ads b/gcc/testsuite/gnat.dg/iter5_pkg.ads
new file mode 100644
index 0000000..0449f3b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/iter5_pkg.ads
@@ -0,0 +1,127 @@
+with Ada.Calendar;
+with Ada.Directories;
+
+with Ada.Iterator_Interfaces;
+
+package Iter5_Pkg is
+
+ subtype Size is Ada.Directories.File_Size;
+
+ type Folder is new String;
+
+ function Folder_Separator return Character;
+
+ function "+" (Directory : String) return Folder;
+
+ function "+" (Left, Right : String) return Folder;
+
+ function "+" (Left : Folder;
+ Right : String) return Folder;
+
+ function Composure (Directory : Folder;
+ Filename : String;
+ Extension : String) return String;
+
+ function Composure (Directory : String;
+ Filename : String;
+ Extension : String) return String;
+ -- no exception
+
+ function Base_Name_Of (Name : String) return String
+ renames Ada.Directories.Base_Name;
+
+ function Extension_Of (Name : String) return String
+ renames Ada.Directories.Extension;
+
+ function Containing_Directory_Of (Name : String) return String
+ renames Ada.Directories.Containing_Directory;
+
+ function Exists (Name : String) return Boolean;
+ -- no exception
+
+ function Size_Of (Name : String) return Size renames Ada.Directories.Size;
+
+ function Directory_Exists (Name : String) return Boolean;
+ -- no exception
+
+ function Modification_Time_Of (Name : String) return Ada.Calendar.Time
+ renames Ada.Directories.Modification_Time;
+
+ function Is_Newer (The_Name : String;
+ Than_Name : String) return Boolean;
+
+ procedure Delete (Name : String);
+ -- no exception if no existance
+
+ procedure Create_Directory (Path : String);
+ -- creates the whole directory path
+
+ procedure Delete_Directory (Name : String); -- including contents
+ -- no exception if no existance
+
+ procedure Rename (Old_Name : String;
+ New_Name : String) renames Ada.Directories.Rename;
+
+ procedure Copy (Source_Name : String;
+ Target_Name : String;
+ Form : String := "")
+ renames Ada.Directories.Copy_File;
+
+ function Is_Leaf_Directory (Directory : String) return Boolean;
+
+ procedure Iterate_Over_Leaf_Directories (From_Directory : String;
+ Iterator : access procedure
+ (Leaf_Directory : String));
+
+ function Found_Directory (Simple_Name : String;
+ In_Directory : String) return String;
+
+ Not_Found : exception;
+
+ Name_Error : exception renames Ada.Directories.Name_Error;
+ Use_Error : exception renames Ada.Directories.Use_Error;
+
+ ------------------------
+ -- File Iterator Loop --
+ ------------------------
+ -- Example:
+ -- for The_Filename of Iter5_Pkg.Iterator_For ("C:\Program_Files") loop
+ -- Log.Write (The_Filename);
+ -- end loop;
+
+ type Item (Name_Length : Natural) is limited private;
+
+ function Iterator_For (Name : String) return Item;
+
+private
+ type Cursor;
+
+ function Has_More (Data : Cursor) return Boolean;
+
+ package List_Iterator_Interfaces is
+ new Ada.Iterator_Interfaces (Cursor, Has_More);
+
+ function Iterate (The_Item : Item)
+ return List_Iterator_Interfaces.Forward_Iterator'class;
+
+ type Cursor_Data is record
+ Has_More : Boolean := False;
+ Position : Ada.Directories.Search_Type;
+ end record;
+
+ type Cursor is access all Cursor_Data;
+
+ function Constant_Reference (The_Item : aliased Item;
+ Unused_Index : Cursor) return String;
+
+ type Item (Name_Length : Natural) is tagged limited record
+ Name : String(1..Name_Length);
+ Actual : Ada.Directories.Directory_Entry_Type;
+ Data : aliased Cursor_Data;
+ end record
+ with
+ Constant_Indexing => Constant_Reference,
+ Default_Iterator => Iterate,
+ Iterator_Element => String;
+
+end Iter5_Pkg;
diff --git a/gcc/testsuite/gnat.dg/iter6.adb b/gcc/testsuite/gnat.dg/iter6.adb
new file mode 100644
index 0000000..371352b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/iter6.adb
@@ -0,0 +1,40 @@
+-- { dg-do compile }
+
+with Ada.Iterator_Interfaces;
+
+procedure Iter6 is
+ package Pkg is
+ type Item (<>) is limited private;
+ private
+
+ type Cursor is null record;
+
+ function Constant_Reference (The_Item : aliased Item;
+ Unused_Index : Cursor) return String
+ is ("");
+
+ function Has_More (Data : Cursor) return Boolean is (False);
+
+ package List_Iterator_Interfaces is new Ada.Iterator_Interfaces
+ (Cursor, Has_More);
+
+ function Iterate (The_Item : Item)
+ return List_Iterator_Interfaces.Forward_Iterator'class
+ is (raise Program_Error);
+
+ type Item (Name_Length : Natural) is tagged limited record
+ null;
+ end record
+ with
+ Constant_Indexing => Constant_Reference,
+ Default_Iterator => Iterate,
+ Iterator_Element => String;
+ end Pkg; use Pkg;
+
+ type Item_Ref is access Item;
+ function F return Item_Ref is (null);
+begin
+ for I of F.all loop -- { dg-error "cannot iterate over \"Item\"" }
+ null;
+ end loop;
+end;
diff --git a/gcc/testsuite/gnat.dg/limited2.adb b/gcc/testsuite/gnat.dg/limited2.adb
new file mode 100644
index 0000000..e3b28ec
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited2.adb
@@ -0,0 +1,8 @@
+-- { dg-do compile }
+
+with Limited2_Pack_2;
+
+procedure Limited2 is
+begin
+ Limited2_Pack_2.Create (P => Limited2_Pack_2.C1);
+end Limited2;
diff --git a/gcc/testsuite/gnat.dg/limited2_pack_1.adb b/gcc/testsuite/gnat.dg/limited2_pack_1.adb
new file mode 100644
index 0000000..1f6e616
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited2_pack_1.adb
@@ -0,0 +1,5 @@
+package body Limited2_Pack_1 is
+ type B is record
+ F : Integer := 0;
+ end record;
+end Limited2_Pack_1;
diff --git a/gcc/testsuite/gnat.dg/limited2_pack_1.ads b/gcc/testsuite/gnat.dg/limited2_pack_1.ads
new file mode 100644
index 0000000..c7d0950
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited2_pack_1.ads
@@ -0,0 +1,8 @@
+package Limited2_Pack_1 is
+ type A is limited private;
+ type A_Ptr is access all A;
+
+private
+ type B;
+ type A is access all B;
+end Limited2_Pack_1;
diff --git a/gcc/testsuite/gnat.dg/limited2_pack_2.adb b/gcc/testsuite/gnat.dg/limited2_pack_2.adb
new file mode 100644
index 0000000..2a4ddd1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited2_pack_2.adb
@@ -0,0 +1,21 @@
+with Limited2_Pack_1;
+
+package body Limited2_Pack_2 is
+ Obj_1 : Limited2_Pack_1.A;
+ Obj_2 : Limited2_Pack_1.A;
+ Obj_3 : Limited2_Pack_1.A;
+
+ procedure M (R : Limited2_Pack_1.A) is
+ begin
+ null;
+ end M;
+
+ procedure Create (P : in C) is
+ begin
+ M (R => Obj_1);
+ M (R => (case P is
+ when C1 => Obj_1,
+ when C2 => Obj_2,
+ when C3 => Obj_3));
+ end Create;
+end Limited2_Pack_2;
diff --git a/gcc/testsuite/gnat.dg/limited2_pack_2.ads b/gcc/testsuite/gnat.dg/limited2_pack_2.ads
new file mode 100644
index 0000000..efc1ab6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited2_pack_2.ads
@@ -0,0 +1,5 @@
+package Limited2_Pack_2 is
+ type C is (C1, C2, C3);
+
+ procedure Create (P : in C);
+end Limited2_Pack_2;
diff --git a/gcc/testsuite/gnat.dg/limited3.adb b/gcc/testsuite/gnat.dg/limited3.adb
new file mode 100644
index 0000000..a0da49d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited3.adb
@@ -0,0 +1,11 @@
+-- { dg-do run }
+
+with Limited3_Pkg; use Limited3_Pkg;
+
+procedure Limited3 is
+ R1 : Rec := F (15);
+ R2 : Rec := F (-1);
+ R3 : Var_Rec := FS (20);
+begin
+ null;
+end Limited3;
diff --git a/gcc/testsuite/gnat.dg/limited3_pkg.adb b/gcc/testsuite/gnat.dg/limited3_pkg.adb
new file mode 100644
index 0000000..71e271d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited3_pkg.adb
@@ -0,0 +1,20 @@
+package body Limited3_Pkg is
+ function F (I : Integer) return Rec is
+ begin
+ return (D => False, I => I);
+ end;
+
+ function FS (X : Integer) return Var_Rec is
+ begin
+ return (X, (1..X => '?'), Tag => <>);
+ end FS;
+
+ function F2 (I : Integer) return Rec2 is
+ begin
+ if I > 0 then
+ return (D => False, I => I);
+ else
+ return (D => True, L => new Limited_Rec);
+ end if;
+ end;
+end Limited3_Pkg;
diff --git a/gcc/testsuite/gnat.dg/limited3_pkg.ads b/gcc/testsuite/gnat.dg/limited3_pkg.ads
new file mode 100644
index 0000000..52f211d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/limited3_pkg.ads
@@ -0,0 +1,30 @@
+package Limited3_Pkg is
+
+ type Limited_Rec is limited
+ null record;
+
+ type Var_Rec (X : Integer) is record
+ Name : String (1 .. X);
+ Tag : Limited_Rec;
+ end record;
+
+ type Rec (D : Boolean := True) is record
+ case D is
+ when True => L : Limited_Rec;
+ when False => I : Integer;
+ end case;
+ end record;
+
+ function F (I : Integer) return Rec;
+
+ function FS (X : Integer) return Var_Rec;
+
+ type Rec2 (D : Boolean := True) is record
+ case D is
+ when True => L : access Limited_Rec;
+ when False => I : Integer;
+ end case;
+ end record;
+
+ function F2 (I : Integer) return Rec2;
+end Limited3_Pkg;
diff --git a/gcc/testsuite/gnat.dg/loop_entry1.adb b/gcc/testsuite/gnat.dg/loop_entry1.adb
new file mode 100644
index 0000000..39cb8d0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_entry1.adb
@@ -0,0 +1,13 @@
+-- { dg-do compile }
+-- { dg-options "-gnatwc" }
+
+procedure Loop_Entry1 (X, Y : in out Integer) is
+begin
+ while X < Y loop
+ pragma Loop_Invariant
+ (X >= X'Loop_Entry and then Y <= Y'Loop_Entry);
+
+ X := X + 1;
+ Y := Y - 1;
+ end loop;
+end Loop_Entry1;
diff --git a/gcc/testsuite/gnat.dg/loop_invariant1.adb b/gcc/testsuite/gnat.dg/loop_invariant1.adb
new file mode 100644
index 0000000..a5c9476
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_invariant1.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+package body Loop_Invariant1 is
+
+ procedure Proc (A : Arr; N : Integer) is
+ I : Integer := A'First;
+ begin
+ while i <= A'Last and then A(A'First .. A'Last) /= A loop
+ pragma Loop_Invariant (N = N'Loop_Entry);
+ i := i + 1;
+ end loop;
+ end;
+
+end Loop_Invariant1;
diff --git a/gcc/testsuite/gnat.dg/loop_invariant1.ads b/gcc/testsuite/gnat.dg/loop_invariant1.ads
new file mode 100644
index 0000000..5c19a92
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_invariant1.ads
@@ -0,0 +1,7 @@
+package Loop_Invariant1 is
+
+ type Arr is array (Natural range <>) of Integer;
+
+ procedure Proc (A : Arr; N : Integer);
+
+end Loop_Invariant1;
diff --git a/gcc/testsuite/gnat.dg/modular5.adb b/gcc/testsuite/gnat.dg/modular5.adb
new file mode 100644
index 0000000..7fcf59c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/modular5.adb
@@ -0,0 +1,26 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+procedure Modular5 is
+ type U64 is mod 2 ** 64;
+ Maybe : Boolean := 2 ** 10 < U64'Succ (U64'last - 1);
+ For_Sure : Boolean := U64'(18446744073709551615) > 2;
+ Ditto : Boolean := 18446744073709551615 > 2;
+
+ generic
+ type TG is mod <>;
+ package PG is
+ X : TG;
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= TG'Last);
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= TG'Last - 1);
+
+ Maybe : Boolean := 2 ** 10 < TG'Succ (TG'last - 1);
+ For_Sure : Boolean := TG'(18446744073709551615) > 2;
+ end PG;
+
+ package IG is new PG (U64);
+
+begin
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= U64'Last);
+ pragma Assert (for all K in 1 .. 2 => 2 ** K <= U64'Last - 1);
+end Modular5;
diff --git a/gcc/testsuite/gnat.dg/opt80.adb b/gcc/testsuite/gnat.dg/opt80.adb
new file mode 100644
index 0000000..39c6cef
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt80.adb
@@ -0,0 +1,15 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure Opt80 is
+ Item : Integer;
+begin
+ Item := Integer'Value ("zzz");
+ Put_Line (Boolean'Image (Item'Valid));
+ raise Program_Error;
+exception
+ when Constraint_Error =>
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/pack23.adb b/gcc/testsuite/gnat.dg/pack23.adb
new file mode 100644
index 0000000..aa8099f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/pack23.adb
@@ -0,0 +1,14 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
+with Pack23_Pkg;
+
+function Pack23 return Integer is
+
+ type Arr is array (1 .. 32) of Boolean with Size => 32, Pack;
+
+ A : Arr;
+
+begin
+ return Pack23_Pkg.Func (A (1));
+end;
diff --git a/gcc/testsuite/gnat.dg/pack23_pkg.ads b/gcc/testsuite/gnat.dg/pack23_pkg.ads
new file mode 100644
index 0000000..beacbad
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/pack23_pkg.ads
@@ -0,0 +1,5 @@
+package Pack23_Pkg is
+
+ function Func (B : in out Boolean) return Integer;
+
+end Pack23_Pkg;
diff --git a/gcc/testsuite/gnat.dg/predicate10.adb b/gcc/testsuite/gnat.dg/predicate10.adb
new file mode 100644
index 0000000..019038d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate10.adb
@@ -0,0 +1,9 @@
+-- { dg-do run }
+
+with Predicate10_Pkg; use Predicate10_Pkg;
+
+procedure Predicate10 is
+ X : I_Pointer := new Integer'(0);
+begin
+ Foo (1, X);
+end;
diff --git a/gcc/testsuite/gnat.dg/predicate10_pkg.adb b/gcc/testsuite/gnat.dg/predicate10_pkg.adb
new file mode 100644
index 0000000..159530f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate10_pkg.adb
@@ -0,0 +1,10 @@
+package body Predicate10_Pkg is
+ procedure Foo (
+ Length : Natural;
+ Initial : I_Pointer
+ ) is
+ A : NI_Array := (1 .. Length => Initial);
+ begin
+ null;
+ end Foo;
+end;
diff --git a/gcc/testsuite/gnat.dg/predicate10_pkg.ads b/gcc/testsuite/gnat.dg/predicate10_pkg.ads
new file mode 100644
index 0000000..e48cfe0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate10_pkg.ads
@@ -0,0 +1,13 @@
+package Predicate10_Pkg is
+ type I_Array is array (Positive range <>) of access Integer;
+
+ subtype NI_Array is I_Array with Dynamic_Predicate =>
+ (for all I of NI_Array => I /= null);
+
+ type I_Pointer is access Integer;
+
+ procedure Foo (
+ Length : Natural;
+ Initial : I_Pointer
+ );
+end;
diff --git a/gcc/testsuite/gnat.dg/predicate11.adb b/gcc/testsuite/gnat.dg/predicate11.adb
new file mode 100644
index 0000000..dc92a91
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate11.adb
@@ -0,0 +1,19 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+procedure Predicate11 is
+ type T_BYTES is new Integer range 0 .. 2**15 - 1 with Size => 32;
+ subtype TYPE5_SCALAR is T_BYTES
+ with Dynamic_Predicate => TYPE5_SCALAR mod 4 = 0;
+ subtype Cond is Integer
+ with dynamic_predicate => (if cond < 5 then false else True);
+
+ Thing1 : Type5_Scalar := 7; -- { dg-warning "check will fail at run time" }
+ function OK (C :Type5_scalar) return Boolean is (True);
+ Thing2 : Type5_Scalar;
+ Thing3 : Cond;
+begin
+ if not OK (7) then raise Program_Error; end if; -- { dg-warning "check will fail at run time" }
+ Thing2 := 8;
+ Thing3 := 1; -- { dg-warning "check will fail at run time" }
+end;
diff --git a/gcc/testsuite/gnat.dg/predicate7.adb b/gcc/testsuite/gnat.dg/predicate7.adb
new file mode 100644
index 0000000..119c190
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate7.adb
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+package body Predicate7 is
+ procedure Foo is null;
+end;
diff --git a/gcc/testsuite/gnat.dg/predicate7.ads b/gcc/testsuite/gnat.dg/predicate7.ads
new file mode 100644
index 0000000..598e2b0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate7.ads
@@ -0,0 +1,13 @@
+with Predicate7_Pkg; use Predicate7_Pkg;
+
+package Predicate7 is
+ function Always_True (I : My_Int) return Boolean;
+
+ function Identity (I : My_Int ) return Integer with Pre => Always_True (I);
+
+ procedure Foo;
+
+private
+ function Identity (I : My_Int ) return Integer is (I);
+ function Always_True (I : My_Int) return Boolean is (True);
+end;
diff --git a/gcc/testsuite/gnat.dg/predicate7_pkg.ads b/gcc/testsuite/gnat.dg/predicate7_pkg.ads
new file mode 100644
index 0000000..b90419e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate7_pkg.ads
@@ -0,0 +1,3 @@
+package Predicate7_Pkg is
+ subtype My_Int is Integer with Dynamic_Predicate => My_Int /= 0;
+end Predicate7_Pkg;
diff --git a/gcc/testsuite/gnat.dg/predicate8.adb b/gcc/testsuite/gnat.dg/predicate8.adb
new file mode 100644
index 0000000..0019699
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate8.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+
+pragma Spark_Mode (On);
+
+with Predicate8_Pkg;
+
+procedure Predicate8 is
+ package Ring_Buffer is new Predicate8_Pkg (Element_Type => Integer);
+ use Ring_Buffer;
+
+ X : Ring_Buffer_Type (4);
+
+begin
+ Put (X, 1);
+end Predicate8;
diff --git a/gcc/testsuite/gnat.dg/predicate8_pkg.adb b/gcc/testsuite/gnat.dg/predicate8_pkg.adb
new file mode 100644
index 0000000..20626d9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate8_pkg.adb
@@ -0,0 +1,64 @@
+pragma Spark_Mode (On);
+
+package body Predicate8_Pkg is
+ function Empty
+ (Buffer : in Ring_Buffer_Type) return Boolean
+ is (Size (Buffer) = 0);
+
+ function Full
+ (Buffer : in Ring_Buffer_Type) return Boolean
+ is (Size (Buffer) = Buffer.Max_Size);
+
+ function Size
+ (Buffer : in Ring_Buffer_Type) return Natural
+ is (Buffer.Count);
+
+ function Free
+ (Buffer : in Ring_Buffer_Type) return Natural
+ is (Buffer.Max_Size - Size (Buffer));
+
+ function First
+ (Buffer : in Ring_Buffer_Type) return Element_Type
+ is (Buffer.Items (Buffer.Head));
+
+ function Last
+ (Buffer : in Ring_Buffer_Type) return Element_Type
+ is (Buffer.Items (Buffer.Tail));
+
+ procedure Get
+ (Buffer : in out Ring_Buffer_Type;
+ Element : out Element_Type)
+ is
+ begin
+ Element := Buffer.Items (Buffer.Head);
+ Buffer :=
+ Buffer'Update
+ (Head =>
+ (if Buffer.Head = Buffer.Max_Size then 1 else Buffer.Head + 1),
+ Count => Buffer.Count - 1);
+ end Get;
+
+ procedure Put
+ (Buffer : in out Ring_Buffer_Type;
+ Element : in Element_Type)
+ is
+ begin
+ if Buffer.Tail = Buffer.Max_Size then
+ Buffer.Tail := 1;
+ else
+ Buffer.Tail := Buffer.Tail + 1;
+ end if;
+
+ Buffer.Items (Buffer.Tail) := Element;
+ Buffer.Count := Buffer.Count + 1;
+ end Put;
+
+ procedure Clear
+ (Buffer : in out Ring_Buffer_Type)
+ is
+ begin
+ Buffer.Head := 1;
+ Buffer.Tail := Buffer.Max_Size;
+ Buffer.Count := 0;
+ end Clear;
+end Predicate8_Pkg;
diff --git a/gcc/testsuite/gnat.dg/predicate8_pkg.ads b/gcc/testsuite/gnat.dg/predicate8_pkg.ads
new file mode 100644
index 0000000..fd25294
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate8_pkg.ads
@@ -0,0 +1,81 @@
+pragma Spark_Mode (On);
+
+generic
+ type Element_Type is private;
+
+package Predicate8_Pkg is
+ pragma Annotate (GNATprove, Terminating, Predicate8_Pkg);
+
+ subtype Small_Natural is Natural range 0 .. Natural'Last / 2;
+ subtype Small_Positive is Natural range 1 .. Natural'Last / 2;
+
+ type Element_Array_Type is array (Small_Positive range <>) of Element_Type;
+
+ type Ring_Buffer_Type (Max_Size : Small_Positive) is private
+ with Default_Initial_Condition => Empty (Ring_Buffer_Type);
+
+ function Empty
+ (Buffer : in Ring_Buffer_Type) return Boolean;
+
+ function Full
+ (Buffer : in Ring_Buffer_Type) return Boolean;
+
+ function Size
+ (Buffer : in Ring_Buffer_Type) return Natural;
+
+ function Free
+ (Buffer : in Ring_Buffer_Type) return Natural;
+
+ function First
+ (Buffer : in Ring_Buffer_Type) return Element_Type
+ with
+ Pre => not Empty (Buffer);
+
+ function Last
+ (Buffer : in Ring_Buffer_Type) return Element_Type
+ with
+ Pre => not Empty (Buffer);
+
+ procedure Get
+ (Buffer : in out Ring_Buffer_Type;
+ Element : out Element_Type)
+ with
+ Pre => not Empty (Buffer) and
+ Size (Buffer) >= 1,
+ Post => not Full (Buffer) and then
+ Element = First (Buffer'Old) and then
+ Size (Buffer) = Size (Buffer'Old) - 1;
+
+ procedure Put
+ (Buffer : in out Ring_Buffer_Type;
+ Element : in Element_Type)
+ with
+ Pre => not Full (Buffer),
+ Post => not Empty (Buffer) and then
+ Last (Buffer) = Element and then
+ Size (Buffer) = Size (Buffer'Old) + 1;
+
+ procedure Clear
+ (Buffer : in out Ring_Buffer_Type)
+ with
+ Post => Empty (Buffer) and then
+ not Full (Buffer) and then
+ Size (Buffer) = 0;
+
+private
+ type Ring_Buffer_Type (Max_Size : Small_Positive) is record
+ Count : Small_Natural := 0;
+ Head : Small_Positive := 1;
+ Tail : Small_Positive := Max_Size;
+ Items : Element_Array_Type (1 .. Max_Size);
+ end record
+ with Dynamic_Predicate =>
+ (Max_Size <= Small_Positive'Last and
+ Count <= Max_Size and
+ Head <= Max_Size and
+ Tail <= Max_Size and
+ ((Count = 0 and Tail = Max_Size and Head = 1) or
+ (Count = Max_Size + Tail - Head + 1) or
+ (Count = Tail - Head + 1)));
+
+end Predicate8_Pkg;
diff --git a/gcc/testsuite/gnat.dg/predicate9.adb b/gcc/testsuite/gnat.dg/predicate9.adb
new file mode 100644
index 0000000..ebcfca7
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate9.adb
@@ -0,0 +1,21 @@
+-- { dg-do compile }
+procedure Predicate9 is
+ function Num (x : Integer) return Integer is (X + 1);
+ function name (X : String) return Integer is (X'Size);
+ function Post (One : Integer; Two : Integer) return Boolean;
+
+ generic
+ type T is private;
+ procedure Pro (Z : Integer) with Post =>
+ Post (Num (5), Two => Name ("yeah"));
+
+ function Post (One : Integer; Two : Integer) return Boolean
+ is (True);
+
+ procedure Pro (Z : Integer) is
+ begin
+ null;
+ end Pro;
+begin
+ null;
+end Predicate9;
diff --git a/gcc/testsuite/gnat.dg/prot8.adb b/gcc/testsuite/gnat.dg/prot8.adb
new file mode 100644
index 0000000..c390448
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/prot8.adb
@@ -0,0 +1,8 @@
+-- { dg-do compile }
+
+package body Prot8 is
+
+ protected body Prot is
+ end Prot;
+
+end Prot8;
diff --git a/gcc/testsuite/gnat.dg/prot8.ads b/gcc/testsuite/gnat.dg/prot8.ads
new file mode 100644
index 0000000..01424ce
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/prot8.ads
@@ -0,0 +1,10 @@
+package Prot8 is
+
+ protected type Prot is
+ private
+ B : Boolean;
+ N : access Prot;
+ Ptr : access Prot;
+ end Prot;
+
+end Prot8;
diff --git a/gcc/testsuite/gnat.dg/range_check3.adb b/gcc/testsuite/gnat.dg/range_check3.adb
new file mode 100644
index 0000000..d134a79
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/range_check3.adb
@@ -0,0 +1,13 @@
+-- { dg-do run }
+-- { dg-options "-gnatVa" }
+
+with Range_Check3_Pkg; use Range_Check3_Pkg;
+procedure Range_Check3 is
+ Ptr : Array_Access;
+begin
+ Ptr := Allocate;
+ raise Program_Error;
+exception
+ when Constraint_Error => null;
+end Range_Check3;
+
diff --git a/gcc/testsuite/gnat.dg/range_check3_pkg.adb b/gcc/testsuite/gnat.dg/range_check3_pkg.adb
new file mode 100644
index 0000000..50c1b1d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/range_check3_pkg.adb
@@ -0,0 +1,18 @@
+package body Range_Check3_Pkg is
+ function One return Positive is
+ begin
+ return 1;
+ end One;
+
+ function Zero return Natural is
+ begin
+ return 0;
+ end Zero;
+
+ function Allocate return Array_Access is
+ begin
+ return
+ new Array_Type
+ (Positive (One) .. Positive (Zero)); -- Failed range check
+ end Allocate;
+end Range_Check3_Pkg;
diff --git a/gcc/testsuite/gnat.dg/range_check3_pkg.ads b/gcc/testsuite/gnat.dg/range_check3_pkg.ads
new file mode 100644
index 0000000..d5864c6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/range_check3_pkg.ads
@@ -0,0 +1,9 @@
+package Range_Check3_Pkg is
+ type Array_Type is array (Positive range <>) of Integer;
+ type Array_Access is access Array_Type;
+
+ function One return Positive;
+ function Zero return Natural;
+
+ function Allocate return Array_Access;
+end Range_Check3_Pkg;
diff --git a/gcc/testsuite/gnat.dg/range_check5.adb b/gcc/testsuite/gnat.dg/range_check5.adb
new file mode 100644
index 0000000..dd62296
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/range_check5.adb
@@ -0,0 +1,21 @@
+-- { dg-do run }
+-- { dg-options "-gnateF -O0" }
+
+procedure Range_Check5 is
+
+ subtype Small_Float is Float range -100.0 .. 100.0;
+
+ function Conv (F : Long_Float) return Small_Float is
+ begin
+ return Small_Float (F);
+ end;
+
+ R : Small_Float;
+
+begin
+ R := Conv (4.0E+38);
+ raise Program_Error;
+exception
+ when Constraint_Error =>
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/rep_clause8.adb b/gcc/testsuite/gnat.dg/rep_clause8.adb
new file mode 100644
index 0000000..11d1266
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/rep_clause8.adb
@@ -0,0 +1,19 @@
+procedure Rep_Clause8 is
+ package Pack is
+ type Root is tagged record
+ Comp : Integer;
+ end record;
+ end Pack;
+ use Pack;
+
+ generic
+ type Formal_Root is new Root with private;
+ package Gen_Derived is
+ type Deriv is new Formal_Root with null record
+ with Size => 300; -- { dg-error "representation item not allowed for generic type" }
+ end Gen_Derived;
+
+ package Inst_Derived is new Gen_Derived (Root);
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/scos1.adb b/gcc/testsuite/gnat.dg/scos1.adb
new file mode 100644
index 0000000..778c071
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/scos1.adb
@@ -0,0 +1,26 @@
+-- { dg-do compile }
+-- { dg-options "-gnata -gnateS" }
+
+procedure SCOs1 with SPARK_Mode => On is
+
+ LEN_IN_BITS : constant := 20;
+
+ M_SIZE_BYTES : constant := 2 ** LEN_IN_BITS;
+ ET_BYTES : constant := (M_SIZE_BYTES - 4);
+
+ type T_BYTES is new Integer range 0 .. ET_BYTES with Size => 32;
+ subtype TYPE5_SCALAR is T_BYTES
+ with Dynamic_Predicate => TYPE5_SCALAR mod 4 = 0;
+
+ type E_16_BYTES is new Integer;
+ subtype RD_BYTES is E_16_BYTES
+ with Dynamic_Predicate => RD_BYTES mod 4 = 0;
+
+ function "-" (left : TYPE5_SCALAR; right : RD_BYTES) return TYPE5_SCALAR
+ is ( left - TYPE5_SCALAR(right) )
+ with Pre => TYPE5_SCALAR(right) <= left and then
+ left - TYPE5_SCALAR(right) <= T_BYTES'Last, Inline_Always;
+
+begin
+ null;
+end SCOs1;
diff --git a/gcc/testsuite/gnat.dg/self_ref1.adb b/gcc/testsuite/gnat.dg/self_ref1.adb
new file mode 100644
index 0000000..a65dbd9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/self_ref1.adb
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+
+procedure Self_Ref1 is
+ type Integer_Ptr is access all Integer;
+ Ptr : constant Integer_Ptr := Integer_Ptr (Ptr); -- { dg-error "object \"Ptr\" cannot be used before end of its declaration" }
+
+begin
+ if Ptr /= null then
+ null;
+ end if;
+end Self_Ref1;
diff --git a/gcc/testsuite/gnat.dg/spark3.adb b/gcc/testsuite/gnat.dg/spark3.adb
new file mode 100644
index 0000000..3c9908a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/spark3.adb
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+
+procedure SPARK3 (X : in out Integer) with SPARK_Mode is
+
+ procedure Q (X : in out Integer) with SPARK_Mode => Off is
+ begin
+ X := X + 1;
+ end Q;
+
+ procedure R (X : in out Integer);
+
+ procedure R (X : in out Integer) with SPARK_Mode => Off is
+ begin
+ Q (X);
+ end R;
+
+begin
+ R (X);
+ X := X + 1;
+end SPARK3;
diff --git a/gcc/testsuite/gnat.dg/sso16.adb b/gcc/testsuite/gnat.dg/sso16.adb
new file mode 100644
index 0000000..0480d9162
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/sso16.adb
@@ -0,0 +1,55 @@
+-- { dg-do run }
+
+with Ada.Text_IO; use Ada.Text_IO;
+
+procedure SSO16 is
+
+ pragma Default_Scalar_Storage_Order (High_Order_First);
+
+ type Enum_T is
+ (Event_0,
+ Event_1,
+ Event_2,
+ Event_3,
+ Event_4,
+ Event_5,
+ Event_11,
+ Event_12,
+ Event_13,
+ Event_14,
+ Event_15,
+ Event_21,
+ Event_22,
+ Event_23,
+ Event_24,
+ Event_25,
+ Event_31,
+ Event_32,
+ Event_33,
+ Event_34,
+ Event_35,
+ Event_41,
+ Event_42,
+ Event_43,
+ Event_44,
+ Event_45);
+
+ Var : Enum_T := Event_0;
+
+begin
+ if Var'Image /= "EVENT_0" then
+ raise Program_Error;
+ end if;
+
+ if Enum_T'Value ("Event_4")'Image /= "EVENT_4" then
+ raise Program_Error;
+ end if;
+
+ if Enum_T'Val (20)'Image /= "EVENT_35" then
+ raise Program_Error;
+ end if;
+
+ if Enum_T'Pos (Enum_T'Value ("Event_45"))'Image /= " 25" then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/synchronized2.adb b/gcc/testsuite/gnat.dg/synchronized2.adb
new file mode 100644
index 0000000..1c111ef
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/synchronized2.adb
@@ -0,0 +1,5 @@
+with Synchronized2_Pkg;
+package body Synchronized2 with SPARK_Mode, Refined_State => (State => C) is
+ C : Synchronized2_Pkg.T;
+ procedure Dummy is null;
+end;
diff --git a/gcc/testsuite/gnat.dg/synchronized2.ads b/gcc/testsuite/gnat.dg/synchronized2.ads
new file mode 100644
index 0000000..780edeb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/synchronized2.ads
@@ -0,0 +1,4 @@
+-- { dg-do compile }
+package Synchronized2 with SPARK_Mode, Abstract_State => (State with Synchronous) is
+ procedure Dummy;
+end;
diff --git a/gcc/testsuite/gnat.dg/synchronized2_pkg.ads b/gcc/testsuite/gnat.dg/synchronized2_pkg.ads
new file mode 100644
index 0000000..57cae9c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/synchronized2_pkg.ads
@@ -0,0 +1,5 @@
+package Synchronized2_Pkg with SPARK_Mode is
+ type T is limited private;
+private
+ task type T;
+end;
diff --git a/gcc/testsuite/gnat.dg/tagged2.adb b/gcc/testsuite/gnat.dg/tagged2.adb
new file mode 100644
index 0000000..2cf9fc5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tagged2.adb
@@ -0,0 +1,9 @@
+-- { dg-do compile }
+
+package body Tagged2 is
+
+ procedure Get_Parent
+ (DeviceX : Device;
+ Parent : out Device) is null;
+
+end Tagged2;
diff --git a/gcc/testsuite/gnat.dg/tagged2.ads b/gcc/testsuite/gnat.dg/tagged2.ads
new file mode 100644
index 0000000..8bbc485
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tagged2.ads
@@ -0,0 +1,9 @@
+package Tagged2 is
+ type Device;
+
+ procedure Get_Parent
+ (DeviceX : Device;
+ Parent : out Device);
+
+ type Device is tagged null record;
+end Tagged2;
diff --git a/gcc/testsuite/gnat.dg/task3.adb b/gcc/testsuite/gnat.dg/task3.adb
new file mode 100644
index 0000000..a73c2dc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/task3.adb
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+
+with Ada.Unchecked_Deallocation;
+
+package body Task3 is
+ procedure Destroy (Obj : in out Child_Wrapper) is
+ procedure Free is new Ada.Unchecked_Deallocation (Child, Child_Ptr);
+ begin
+ Free (Obj.Ptr);
+ end Destroy;
+end Task3;
diff --git a/gcc/testsuite/gnat.dg/task3.ads b/gcc/testsuite/gnat.dg/task3.ads
new file mode 100644
index 0000000..324d894
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/task3.ads
@@ -0,0 +1,12 @@
+with Task3_Pkg2; use Task3_Pkg2;
+
+package Task3 is
+ type Child is new Root with null record;
+ type Child_Ptr is access Child;
+
+ type Child_Wrapper is record
+ Ptr : Child_Ptr := null;
+ end record;
+
+ procedure Destroy (Obj : in out Child_Wrapper);
+end Task3;
diff --git a/gcc/testsuite/gnat.dg/task3_pkg1.ads b/gcc/testsuite/gnat.dg/task3_pkg1.ads
new file mode 100644
index 0000000..cc41be0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/task3_pkg1.ads
@@ -0,0 +1,11 @@
+package Task3_Pkg1 is
+ type Task_Wrapper (Discr : Integer) is tagged limited private;
+
+private
+ task type Task_Typ (Discr : Integer) is
+ end Task_Typ;
+
+ type Task_Wrapper (Discr : Integer) is tagged limited record
+ Tsk : Task_Typ (Discr);
+ end record;
+end Task3_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/task3_pkg2.ads b/gcc/testsuite/gnat.dg/task3_pkg2.ads
new file mode 100644
index 0000000..aee5c73
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/task3_pkg2.ads
@@ -0,0 +1,7 @@
+with Task3_Pkg1; use Task3_Pkg1;
+
+package Task3_Pkg2 is
+ type Root (Discr : Integer) is tagged limited record
+ Wrap : Task_Wrapper (Discr);
+ end record;
+end Task3_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/task4.adb b/gcc/testsuite/gnat.dg/task4.adb
new file mode 100644
index 0000000..9a97503
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/task4.adb
@@ -0,0 +1,19 @@
+-- { dg-do compile }
+
+with System.Multiprocessors;
+
+procedure Task4 is
+
+ task type Infinite_Loop (C : System.Multiprocessors.CPU_Range)
+ with CPU => C;
+
+ task body Infinite_Loop is
+ begin
+ loop
+ null;
+ end loop;
+ end Infinite_Loop;
+
+begin
+ null;
+end Task4;
diff --git a/gcc/testsuite/gnat.dg/unreferenced2.adb b/gcc/testsuite/gnat.dg/unreferenced2.adb
new file mode 100644
index 0000000..9576ef8
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/unreferenced2.adb
@@ -0,0 +1,34 @@
+-- { dg-do compile }
+-- { dg-options "-gnatf" }
+
+procedure Unreferenced2 is
+
+ protected Example is
+ procedure Callme;
+ end Example;
+
+ procedure Other (X : Boolean) is
+ begin
+ null;
+ end;
+
+ protected body Example is
+
+ procedure Internal (X : Boolean) is
+ pragma Unreferenced (X);
+ Y : Integer;
+ begin
+ Y := 3;
+ end Internal;
+
+ procedure Callme is
+ begin
+ Internal (X => True);
+ end Callme;
+
+ end Example;
+
+begin
+ Example.Callme;
+ Other (True);
+end Unreferenced2;
diff --git a/gcc/testsuite/gnat.dg/warn21.adb b/gcc/testsuite/gnat.dg/warn21.adb
new file mode 100644
index 0000000..123dfdc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn21.adb
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+-- { dg-options "-gnata -gnatwa" }
+
+package body Warn21 is
+ procedure Foo is null;
+end Warn21;
diff --git a/gcc/testsuite/gnat.dg/warn21.ads b/gcc/testsuite/gnat.dg/warn21.ads
new file mode 100644
index 0000000..a091467
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn21.ads
@@ -0,0 +1,18 @@
+package Warn21 is
+
+ type Set is new Integer;
+
+ function "<=" (Left : Set; Right : Set) return Boolean;
+
+ function "=" (Left : Set; Right : Set) return Boolean with
+ Post => "="'Result = (Left <= Right and Right <= Left);
+
+ procedure Foo;
+
+private
+
+ function "<=" (Left : Set; Right : Set) return Boolean is (True);
+ function "=" (Left : Set; Right : Set) return Boolean is
+ (Left <= Right and Right <= Left);
+
+end Warn21;
diff --git a/gcc/testsuite/gnat.dg/warn22.adb b/gcc/testsuite/gnat.dg/warn22.adb
new file mode 100644
index 0000000..0a1692f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn22.adb
@@ -0,0 +1,34 @@
+-- { dg-do compile }
+-- { dg-options "-gnatwa" }
+
+with Ada.Text_IO;
+
+procedure Warn22
+is
+ type X is
+ record
+ Str : String (1 .. 3);
+ end record;
+
+ type T is
+ record
+ Value : X;
+ end record;
+
+ procedure Consume_Data (Item : out T) is
+ begin
+ Item := (Value => (Str => "Bar"));
+ end Consume_Data;
+
+ Baz : T;
+begin
+
+ Baz := (Value => (Str => "Foo"));
+
+ Ada.Text_IO.Put_Line (Baz.Value.Str);
+
+ Consume_Data (Baz);
+
+ Ada.Text_IO.Put_Line (Baz.Value.Str);
+
+end Warn22;
diff --git a/gcc/testsuite/gnat.dg/warn23.adb b/gcc/testsuite/gnat.dg/warn23.adb
new file mode 100644
index 0000000..63d0557
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn23.adb
@@ -0,0 +1,17 @@
+-- { dg-do compile }
+
+procedure Warn23 is
+
+ type Enum_Type is (A, B, C);
+
+ function Poll (E : out Enum_Type) return Boolean
+ with Convention => Ada,
+ Import => True;
+
+ E : Enum_Type;
+
+begin
+ while Poll (E) loop
+ null;
+ end loop;
+end;
diff --git a/gcc/testsuite/gnat.dg/warn24.adb b/gcc/testsuite/gnat.dg/warn24.adb
new file mode 100644
index 0000000..e7c9f8a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn24.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+
+procedure Warn24 is
+ type List_D (D : Boolean);
+
+ type List_Acc is access List_D;
+
+ type List_D (D : Boolean) is record
+ Next : List_Acc (D); -- { dg-warning "constraint is ignored on component that is access to current record" }
+ end record;
+
+ X : List_D (True);
+begin
+ X.Next := new List_D (False);
+end Warn24;
diff --git a/gcc/testsuite/gnat.dg/warn25.adb b/gcc/testsuite/gnat.dg/warn25.adb
new file mode 100644
index 0000000..e784870
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn25.adb
@@ -0,0 +1,23 @@
+-- { dg-do compile }
+-- { dg-options "-gnatwa" }
+
+with Ada.Exceptions;
+procedure Warn25 is
+ CASA_Unavailable : Ada.Exceptions.Exception_Occurrence;
+ use Ada.Exceptions;
+begin
+ while True loop
+ declare
+ begin
+ if Exception_Identity (CASA_Unavailable) = Null_Id then
+ exit;
+ end if;
+ exception
+ when E : others =>
+ Save_Occurrence (Source => E, Target => CASA_Unavailable);
+ end;
+ end loop;
+ if Exception_Identity (CASA_Unavailable) /= Null_Id then
+ Reraise_Occurrence (CASA_Unavailable);
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/warn26.adb b/gcc/testsuite/gnat.dg/warn26.adb
new file mode 100644
index 0000000..08b681f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn26.adb
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+
+procedure Warn26 is
+
+ Monitor_Period_Min : constant := 5;
+ Monitor_Period_Max : constant := 30;
+
+ type Monitor_Period is range Monitor_Period_Min .. Monitor_Period_Max;
+
+ subtype Period_T is Positive range 5 .. 30;
+
+ function Id (X : Period_T) return Period_T is (X);
+ Input_Period : Period_T := Id (20);
+begin
+ if Input_Period in
+ Integer (Monitor_Period'First) .. Integer ( Monitor_Period'Last)
+ then
+ null;
+ end if;
+end Warn26;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 9a10418..0272e6f8 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -8,6 +8,13 @@
hooks provided by each test case. */
#define COMBINED_TEST
+/* test-accessing-bitfield.c */
+#define create_code create_code_accessing_bitfield
+#define verify_code verify_code_accessing_bitfield
+#include "test-accessing-bitfield.c"
+#undef create_code
+#undef verify_code
+
/* test-accessing-struct.c */
#define create_code create_code_accessing_struct
#define verify_code verify_code_accessing_struct
@@ -266,6 +273,9 @@ struct testcase
};
const struct testcase testcases[] = {
+ {"accessing_bitfield",
+ create_code_accessing_bitfield,
+ verify_code_accessing_bitfield},
{"accessing_struct",
create_code_accessing_struct,
verify_code_accessing_struct},
diff --git a/gcc/testsuite/jit.dg/test-accessing-bitfield.c b/gcc/testsuite/jit.dg/test-accessing-bitfield.c
new file mode 100644
index 0000000..5e80351
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-accessing-bitfield.c
@@ -0,0 +1,130 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+struct bit_foo
+{
+ int i:3;
+ int x:5;
+ int y:5;
+ int z:10;
+ int j:3;
+};
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ void
+ test_bitfield_access (struct bit_foo *f)
+ {
+ f->z = f->x + f->y;
+ }
+ */
+ gcc_jit_type *void_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_field *i =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 3,
+ "i");
+ gcc_jit_field *x =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 5,
+ "x");
+ gcc_jit_field *y =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 5,
+ "y");
+ gcc_jit_field *z =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 10,
+ "z");
+ gcc_jit_field *j =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 3,
+ "j");
+ gcc_jit_field *fields[] = {i, x, y, z, j};
+ gcc_jit_struct *struct_type =
+ gcc_jit_context_new_struct_type (ctxt, NULL, "bit_foo", 5, fields);
+ gcc_jit_type *ptr_type =
+ gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_type));
+
+ /* Build the test function. */
+ gcc_jit_param *param_f =
+ gcc_jit_context_new_param (ctxt, NULL, ptr_type, "f");
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ "test_bitfield_access",
+ 1, &param_f,
+ 0);
+
+ /* f->x + f->y */
+ gcc_jit_rvalue *sum =
+ gcc_jit_context_new_binary_op (
+ ctxt, NULL,
+ GCC_JIT_BINARY_OP_PLUS,
+ int_type,
+ gcc_jit_lvalue_as_rvalue (
+ gcc_jit_rvalue_dereference_field (
+ gcc_jit_param_as_rvalue (param_f),
+ NULL,
+ x)),
+ gcc_jit_lvalue_as_rvalue (
+ gcc_jit_rvalue_dereference_field (
+ gcc_jit_param_as_rvalue (param_f),
+ NULL,
+ y)));
+
+ /* f->z = ... */
+ gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+ gcc_jit_block_add_assignment (
+ block,
+ NULL,
+ gcc_jit_rvalue_dereference_field (
+ gcc_jit_param_as_rvalue (param_f),
+ NULL,
+ z),
+ sum);
+ gcc_jit_block_end_with_void_return (block, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef void (*fn_type) (struct bit_foo *);
+ CHECK_NON_NULL (result);
+
+ fn_type test_bitfield_access =
+ (fn_type)gcc_jit_result_get_code (result, "test_bitfield_access");
+ CHECK_NON_NULL (test_bitfield_access);
+
+ struct bit_foo tmp;
+ tmp.i = 3;
+ tmp.x = 5;
+ tmp.y = 7;
+ tmp.z = 0;
+ tmp.j = 3;
+
+ /* Call the JIT-generated function. */
+ test_bitfield_access (&tmp);
+
+ /* Verify that the code correctly modified the field "z". */
+ CHECK_VALUE (tmp.z, 12);
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_binary_op-bad-res-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_binary_op-bad-res-type.c
new file mode 100644
index 0000000..fbbb2e7
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_binary_op-bad-res-type.c
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to create a binary operator with invalid result type. */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *void_ptr_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
+
+ gcc_jit_context_new_binary_op (
+ ctxt,
+ NULL,
+ GCC_JIT_BINARY_OP_MINUS,
+ void_ptr_type,
+ gcc_jit_context_new_rvalue_from_int (ctxt,
+ int_type,
+ 1),
+ gcc_jit_context_new_rvalue_from_int (ctxt,
+ int_type,
+ 2));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_context_new_binary_op: gcc_jit_binary_op "
+ "GCC_JIT_BINARY_OP_MINUS with operands a: "
+ "(int)1 b: (int)2 has non-numeric result_type: void *");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c
new file mode 100644
index 0000000..d2ef5a8
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-type.c
@@ -0,0 +1,53 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to declare a bit-field with invalid type. */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *bool_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL);
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *long_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG);
+ gcc_jit_type *float_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
+
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ bool_type,
+ 3,
+ "b");
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 3,
+ "i");
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ long_type,
+ 3,
+ "l");
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ float_type,
+ 5,
+ "f");
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_context_new_bitfield: bit-field f has non "
+ "integral type float");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c
new file mode 100644
index 0000000..67db120
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_bitfield-invalid-width.c
@@ -0,0 +1,44 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to declare a bit-field with invalid width. */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *short_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SHORT);
+ gcc_jit_field *i =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ short_type,
+ 3,
+ "i");
+ gcc_jit_field *j =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ short_type,
+ 157,
+ "j");
+ gcc_jit_field *fields[] = {i, j};
+ gcc_jit_context_new_struct_type (ctxt, NULL, "bit_foo", 2, fields);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+ char error_str[256];
+ snprintf (error_str, sizeof (error_str),
+ "width of bit-field j (width: 157) is wider than its type "
+ "(width: %zu)", 8 * sizeof (short));
+
+ /* Verify that the correct error message was emitted. */
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ error_str);
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_unary_op-bad-res-type.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_unary_op-bad-res-type.c
new file mode 100644
index 0000000..fae722a
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_unary_op-bad-res-type.c
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to create an unary operator with invalid result type. */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *void_ptr_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
+
+ gcc_jit_context_new_unary_op (
+ ctxt,
+ NULL,
+ GCC_JIT_UNARY_OP_LOGICAL_NEGATE,
+ void_ptr_type,
+ gcc_jit_context_new_rvalue_from_int (ctxt,
+ int_type,
+ 1));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_context_new_unary_op: gcc_jit_unary_op "
+ "GCC_JIT_UNARY_OP_LOGICAL_NEGATE with operand "
+ "(int)1 has non-numeric result_type: void *");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c
new file mode 100644
index 0000000..f102a6a
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_get_address-bitfield.c
@@ -0,0 +1,66 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+/* Try to dereference a bit-field. */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ struct bit_foo
+ {
+ int i:3;
+ int j:3;
+ };
+
+ struct bit_foo f;
+ &(f.j)
+ */
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_field *i =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 3,
+ "i");
+ gcc_jit_field *j =
+ gcc_jit_context_new_bitfield (ctxt,
+ NULL,
+ int_type,
+ 3,
+ "j");
+ gcc_jit_field *fields[] = {i, j};
+ gcc_jit_type *struct_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt, NULL, "bit_foo", 2, fields));
+
+ gcc_jit_lvalue *f_struct =
+ gcc_jit_context_new_global (ctxt,
+ NULL,
+ GCC_JIT_GLOBAL_INTERNAL,
+ struct_type,
+ "f");
+
+ gcc_jit_lvalue_get_address (
+ gcc_jit_lvalue_access_field (
+ f_struct,
+ NULL,
+ j),
+ NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "cannot take address of bit-field");
+}
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 116be7b..56ef63e 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -159,9 +159,9 @@ HOST_WIDE_INT random_seed;
the support provided depends on the backend. */
rtx stack_limit_rtx;
-struct target_flag_state default_target_flag_state;
+class target_flag_state default_target_flag_state;
#if SWITCHABLE_TARGET
-struct target_flag_state *this_target_flag_state = &default_target_flag_state;
+class target_flag_state *this_target_flag_state = &default_target_flag_state;
#else
#define this_target_flag_state (&default_target_flag_state)
#endif
@@ -543,27 +543,6 @@ compile_file (void)
process_pending_assemble_externals ();
}
- /* Emit LTO marker if LTO info has been previously emitted. This is
- used by collect2 to determine whether an object file contains IL.
- We used to emit an undefined reference here, but this produces
- link errors if an object file with IL is stored into a shared
- library without invoking lto1. */
- if (flag_generate_lto || flag_generate_offload)
- {
-#if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
- ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE,
- "__gnu_lto_v1",
- HOST_WIDE_INT_1U, 8);
-#elif defined ASM_OUTPUT_ALIGNED_COMMON
- ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_v1",
- HOST_WIDE_INT_1U, 8);
-#else
- ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_v1",
- HOST_WIDE_INT_1U,
- HOST_WIDE_INT_1U);
-#endif
- }
-
/* Let linker plugin know that this is a slim object and must be LTOed
even when user did not ask for it. */
if (flag_generate_lto && !flag_fat_lto_objects)
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index b8a62a6..976cf3c 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -675,7 +675,7 @@ aff_combination_mult (aff_tree *c1, aff_tree *c2, aff_tree *r)
element exists. If IDX is not NULL, it is set to the index of VAL in
COMB. */
-static struct aff_comb_elt *
+static class aff_comb_elt *
aff_combination_find_elt (aff_tree *comb, tree val, unsigned *idx)
{
unsigned i;
@@ -695,8 +695,9 @@ aff_combination_find_elt (aff_tree *comb, tree val, unsigned *idx)
/* Element of the cache that maps ssa name NAME to its expanded form
as an affine expression EXPANSION. */
-struct name_expansion
+class name_expansion
{
+public:
aff_tree expansion;
/* True if the expansion for the name is just being generated. */
@@ -715,7 +716,7 @@ aff_combination_expand (aff_tree *comb ATTRIBUTE_UNUSED,
tree e;
gimple *def;
widest_int scale;
- struct name_expansion *exp;
+ class name_expansion *exp;
aff_combination_zero (&to_add, comb->type);
for (i = 0; i < comb->n; i++)
@@ -794,7 +795,7 @@ aff_combination_expand (aff_tree *comb ATTRIBUTE_UNUSED,
default:
continue;
}
- exp = XNEW (struct name_expansion);
+ exp = XNEW (class name_expansion);
exp->in_progress = 1;
if (!*cache)
*cache = new hash_map<tree, name_expansion *>;
@@ -931,7 +932,7 @@ aff_combination_constant_multiple_p (aff_tree *val, aff_tree *div,
for (i = 0; i < div->n; i++)
{
- struct aff_comb_elt *elt
+ class aff_comb_elt *elt
= aff_combination_find_elt (val, div->elts[i].val, NULL);
if (!elt)
return false;
diff --git a/gcc/tree-affine.h b/gcc/tree-affine.h
index 257e8f6..2164820 100644
--- a/gcc/tree-affine.h
+++ b/gcc/tree-affine.h
@@ -28,8 +28,9 @@ along with GCC; see the file COPYING3. If not see
/* Element of an affine combination. */
-struct aff_comb_elt
+class aff_comb_elt
{
+public:
/* The value of the element. */
tree val;
@@ -37,8 +38,9 @@ struct aff_comb_elt
widest_int coef;
};
-struct aff_tree
+class aff_tree
{
+public:
/* Type of the result of the combination. */
tree type;
@@ -54,7 +56,7 @@ struct aff_tree
The coefficients are always sign extended from the precision of TYPE
(regardless of signedness of TYPE). */
- struct aff_comb_elt elts[MAX_AFF_ELTS];
+ class aff_comb_elt elts[MAX_AFF_ELTS];
/* Remainder of the expression. Usually NULL, used only if there are more
than MAX_AFF_ELTS elements. Type of REST will be either sizetype for
@@ -62,7 +64,7 @@ struct aff_tree
tree rest;
};
-struct name_expansion;
+class name_expansion;
void aff_combination_const (aff_tree *, tree, const poly_widest_int &);
void aff_combination_elt (aff_tree *, tree, tree);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index a585efe..54ee63a 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -256,7 +256,7 @@ build_gimple_cfg (gimple_seq seq)
come immediately before the condition in BB, if any. */
static void
-replace_loop_annotate_in_block (basic_block bb, struct loop *loop)
+replace_loop_annotate_in_block (basic_block bb, class loop *loop)
{
gimple_stmt_iterator gsi = gsi_last_bb (bb);
gimple *stmt = gsi_stmt (gsi);
@@ -311,7 +311,7 @@ replace_loop_annotate_in_block (basic_block bb, struct loop *loop)
static void
replace_loop_annotate (void)
{
- struct loop *loop;
+ class loop *loop;
basic_block bb;
gimple_stmt_iterator gsi;
gimple *stmt;
@@ -1437,19 +1437,19 @@ make_gimple_asm_edges (basic_block bb)
(almost) no new labels should be created. */
/* A map from basic block index to the leading label of that block. */
-static struct label_record
+struct label_record
{
/* The label. */
tree label;
/* True if the label is referenced from somewhere. */
bool used;
-} *label_for_bb;
+};
/* Given LABEL return the first label in the same basic block. */
static tree
-main_block_label (tree label)
+main_block_label (tree label, label_record *label_for_bb)
{
basic_block bb = label_to_block (cfun, label);
tree main_label = label_for_bb[bb->index].label;
@@ -1468,7 +1468,7 @@ main_block_label (tree label)
/* Clean up redundant labels within the exception tree. */
static void
-cleanup_dead_labels_eh (void)
+cleanup_dead_labels_eh (label_record *label_for_bb)
{
eh_landing_pad lp;
eh_region r;
@@ -1481,7 +1481,7 @@ cleanup_dead_labels_eh (void)
for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
if (lp && lp->post_landing_pad)
{
- lab = main_block_label (lp->post_landing_pad);
+ lab = main_block_label (lp->post_landing_pad, label_for_bb);
if (lab != lp->post_landing_pad)
{
EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
@@ -1503,7 +1503,7 @@ cleanup_dead_labels_eh (void)
{
lab = c->label;
if (lab)
- c->label = main_block_label (lab);
+ c->label = main_block_label (lab, label_for_bb);
}
}
break;
@@ -1511,7 +1511,7 @@ cleanup_dead_labels_eh (void)
case ERT_ALLOWED_EXCEPTIONS:
lab = r->u.allowed.label;
if (lab)
- r->u.allowed.label = main_block_label (lab);
+ r->u.allowed.label = main_block_label (lab, label_for_bb);
break;
}
}
@@ -1526,7 +1526,8 @@ void
cleanup_dead_labels (void)
{
basic_block bb;
- label_for_bb = XCNEWVEC (struct label_record, last_basic_block_for_fn (cfun));
+ label_record *label_for_bb = XCNEWVEC (struct label_record,
+ last_basic_block_for_fn (cfun));
/* Find a suitable label for each block. We use the first user-defined
label if there is one, or otherwise just the first label we see. */
@@ -1582,7 +1583,7 @@ cleanup_dead_labels (void)
label = gimple_cond_true_label (cond_stmt);
if (label)
{
- new_label = main_block_label (label);
+ new_label = main_block_label (label, label_for_bb);
if (new_label != label)
gimple_cond_set_true_label (cond_stmt, new_label);
}
@@ -1590,7 +1591,7 @@ cleanup_dead_labels (void)
label = gimple_cond_false_label (cond_stmt);
if (label)
{
- new_label = main_block_label (label);
+ new_label = main_block_label (label, label_for_bb);
if (new_label != label)
gimple_cond_set_false_label (cond_stmt, new_label);
}
@@ -1607,7 +1608,7 @@ cleanup_dead_labels (void)
{
tree case_label = gimple_switch_label (switch_stmt, i);
label = CASE_LABEL (case_label);
- new_label = main_block_label (label);
+ new_label = main_block_label (label, label_for_bb);
if (new_label != label)
CASE_LABEL (case_label) = new_label;
}
@@ -1622,7 +1623,7 @@ cleanup_dead_labels (void)
for (i = 0; i < n; ++i)
{
tree cons = gimple_asm_label_op (asm_stmt, i);
- tree label = main_block_label (TREE_VALUE (cons));
+ tree label = main_block_label (TREE_VALUE (cons), label_for_bb);
TREE_VALUE (cons) = label;
}
break;
@@ -1635,7 +1636,7 @@ cleanup_dead_labels (void)
{
ggoto *goto_stmt = as_a <ggoto *> (stmt);
label = gimple_goto_dest (goto_stmt);
- new_label = main_block_label (label);
+ new_label = main_block_label (label, label_for_bb);
if (new_label != label)
gimple_goto_set_dest (goto_stmt, new_label);
}
@@ -1648,7 +1649,7 @@ cleanup_dead_labels (void)
label = gimple_transaction_label_norm (txn);
if (label)
{
- new_label = main_block_label (label);
+ new_label = main_block_label (label, label_for_bb);
if (new_label != label)
gimple_transaction_set_label_norm (txn, new_label);
}
@@ -1656,7 +1657,7 @@ cleanup_dead_labels (void)
label = gimple_transaction_label_uninst (txn);
if (label)
{
- new_label = main_block_label (label);
+ new_label = main_block_label (label, label_for_bb);
if (new_label != label)
gimple_transaction_set_label_uninst (txn, new_label);
}
@@ -1664,7 +1665,7 @@ cleanup_dead_labels (void)
label = gimple_transaction_label_over (txn);
if (label)
{
- new_label = main_block_label (label);
+ new_label = main_block_label (label, label_for_bb);
if (new_label != label)
gimple_transaction_set_label_over (txn, new_label);
}
@@ -1677,7 +1678,7 @@ cleanup_dead_labels (void)
}
/* Do the same for the exception region tree labels. */
- cleanup_dead_labels_eh ();
+ cleanup_dead_labels_eh (label_for_bb);
/* Finally, purge dead labels. All user-defined labels and labels that
can be the target of non-local gotos and labels which have their
@@ -1996,7 +1997,7 @@ replace_uses_by (tree name, tree val)
/* Also update the trees stored in loop structures. */
if (current_loops)
{
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, 0)
{
@@ -2223,7 +2224,7 @@ remove_bb (basic_block bb)
if (current_loops)
{
- struct loop *loop = bb->loop_father;
+ class loop *loop = bb->loop_father;
/* If a loop gets removed, clean up the information associated
with it. */
@@ -2547,7 +2548,7 @@ dump_cfg_stats (FILE *file)
num_edges = 0;
FOR_EACH_BB_FN (bb, cfun)
num_edges += EDGE_COUNT (bb->succs);
- size = num_edges * sizeof (struct edge_def);
+ size = num_edges * sizeof (class edge_def);
total += size;
fprintf (file, fmt_str_2, "Edges", num_edges, SIZE_AMOUNT (size));
@@ -5756,6 +5757,7 @@ gimple_make_forwarder_block (edge fallthru)
basic_block dummy, bb;
tree var;
gphi_iterator gsi;
+ bool forward_location_p;
dummy = fallthru->src;
bb = fallthru->dest;
@@ -5763,6 +5765,9 @@ gimple_make_forwarder_block (edge fallthru)
if (single_pred_p (bb))
return;
+ /* We can forward location info if we have only one predecessor. */
+ forward_location_p = single_pred_p (dummy);
+
/* If we redirected a branch we must create new PHI nodes at the
start of BB. */
for (gsi = gsi_start_phis (dummy); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -5774,7 +5779,8 @@ gimple_make_forwarder_block (edge fallthru)
new_phi = create_phi_node (var, bb);
gimple_phi_set_result (phi, copy_ssa_name (var, phi));
add_phi_arg (new_phi, gimple_phi_result (phi), fallthru,
- UNKNOWN_LOCATION);
+ forward_location_p
+ ? gimple_phi_arg_location (phi, 0) : UNKNOWN_LOCATION);
}
/* Add the arguments we have stored on edges. */
@@ -6378,7 +6384,7 @@ gimple_duplicate_sese_region (edge entry, edge exit,
{
unsigned i;
bool free_region_copy = false, copying_header = false;
- struct loop *loop = entry->dest->loop_father;
+ class loop *loop = entry->dest->loop_father;
edge exit_copy;
vec<basic_block> doms = vNULL;
edge redirected;
@@ -6544,8 +6550,8 @@ gimple_duplicate_sese_tail (edge entry, edge exit,
{
unsigned i;
bool free_region_copy = false;
- struct loop *loop = exit->dest->loop_father;
- struct loop *orig_loop = entry->dest->loop_father;
+ class loop *loop = exit->dest->loop_father;
+ class loop *orig_loop = entry->dest->loop_father;
basic_block switch_bb, entry_bb, nentry_bb;
vec<basic_block> doms;
profile_count total_count = profile_count::uninitialized (),
@@ -6558,7 +6564,7 @@ gimple_duplicate_sese_tail (edge entry, edge exit,
gphi_iterator psi;
gphi *phi;
tree def;
- struct loop *target, *aloop, *cloop;
+ class loop *target, *aloop, *cloop;
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
exits[0] = exit;
@@ -7035,7 +7041,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
/* Move BB from its current loop to the copy in the new function. */
if (current_loops)
{
- struct loop *new_loop = (struct loop *)bb->loop_father->aux;
+ class loop *new_loop = (class loop *)bb->loop_father->aux;
if (new_loop)
bb->loop_father = new_loop;
}
@@ -7083,7 +7089,14 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
if (virtual_operand_p (op))
{
/* Remove the phi nodes for virtual operands (alias analysis will be
- run for the new function, anyway). */
+ run for the new function, anyway). But replace all uses that
+ might be outside of the region we move. */
+ use_operand_p use_p;
+ imm_use_iterator iter;
+ gimple *use_stmt;
+ FOR_EACH_IMM_USE_STMT (use_stmt, iter, op)
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, SSA_NAME_VAR (op));
remove_phi_node (&psi, true);
continue;
}
@@ -7299,7 +7312,7 @@ replace_block_vars_by_duplicates (tree block, hash_map<tree, tree> *vars_map,
static void
fixup_loop_arrays_after_move (struct function *fn1, struct function *fn2,
- struct loop *loop)
+ class loop *loop)
{
/* Discard it from the old loop array. */
(*get_loops (fn1))[loop->num] = NULL;
@@ -7459,8 +7472,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
edge_iterator ei;
htab_t new_label_map;
hash_map<void *, void *> *eh_map;
- struct loop *loop = entry_bb->loop_father;
- struct loop *loop0 = get_loop (saved_cfun, 0);
+ class loop *loop = entry_bb->loop_father;
+ class loop *loop0 = get_loop (saved_cfun, 0);
struct move_stmt_d d;
/* If ENTRY does not strictly dominate EXIT, this cannot be an SESE
@@ -7568,8 +7581,8 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
{
if (bb->loop_father->header == bb)
{
- struct loop *this_loop = bb->loop_father;
- struct loop *outer = loop_outer (this_loop);
+ class loop *this_loop = bb->loop_father;
+ class loop *outer = loop_outer (this_loop);
if (outer == loop
/* If the SESE region contains some bbs ending with
a noreturn call, those are considered to belong
@@ -7609,7 +7622,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
/* Fix up orig_loop_num. If the block referenced in it has been moved
to dest_cfun, update orig_loop_num field, otherwise clear it. */
- struct loop *dloop;
+ class loop *dloop;
signed char *moved_orig_loop_num = NULL;
FOR_EACH_LOOP_FN (dest_cfun, dloop, 0)
if (dloop->orig_loop_num)
@@ -7717,14 +7730,14 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
loop0->aux = NULL;
/* Loop sizes are no longer correct, fix them up. */
loop->num_nodes -= num_nodes;
- for (struct loop *outer = loop_outer (loop);
+ for (class loop *outer = loop_outer (loop);
outer; outer = loop_outer (outer))
outer->num_nodes -= num_nodes;
loop0->num_nodes -= bbs.length () - num_nodes;
if (saved_cfun->has_simduid_loops || saved_cfun->has_force_vectorize_loops)
{
- struct loop *aloop;
+ class loop *aloop;
for (i = 0; vec_safe_iterate (loops->larray, i, &aloop); i++)
if (aloop != NULL)
{
@@ -8175,14 +8188,14 @@ print_loops_bb (FILE *file, basic_block bb, int indent, int verbosity)
}
}
-static void print_loop_and_siblings (FILE *, struct loop *, int, int);
+static void print_loop_and_siblings (FILE *, class loop *, int, int);
/* Pretty print LOOP on FILE, indented INDENT spaces. Following
VERBOSITY level this outputs the contents of the loop, or just its
structure. */
static void
-print_loop (FILE *file, struct loop *loop, int indent, int verbosity)
+print_loop (FILE *file, class loop *loop, int indent, int verbosity)
{
char *s_indent;
basic_block bb;
@@ -8248,7 +8261,7 @@ print_loop (FILE *file, struct loop *loop, int indent, int verbosity)
loop, or just its structure. */
static void
-print_loop_and_siblings (FILE *file, struct loop *loop, int indent,
+print_loop_and_siblings (FILE *file, class loop *loop, int indent,
int verbosity)
{
if (loop == NULL)
@@ -8275,13 +8288,13 @@ print_loops (FILE *file, int verbosity)
/* Dump a loop. */
DEBUG_FUNCTION void
-debug (struct loop &ref)
+debug (class loop &ref)
{
print_loop (stderr, &ref, 0, /*verbosity*/0);
}
DEBUG_FUNCTION void
-debug (struct loop *ptr)
+debug (class loop *ptr)
{
if (ptr)
debug (*ptr);
@@ -8292,13 +8305,13 @@ debug (struct loop *ptr)
/* Dump a loop verbosely. */
DEBUG_FUNCTION void
-debug_verbose (struct loop &ref)
+debug_verbose (class loop &ref)
{
print_loop (stderr, &ref, 0, /*verbosity*/3);
}
DEBUG_FUNCTION void
-debug_verbose (struct loop *ptr)
+debug_verbose (class loop *ptr)
{
if (ptr)
debug (*ptr);
@@ -8318,7 +8331,7 @@ debug_loops (int verbosity)
/* Print on stderr the code of LOOP, at some VERBOSITY level. */
DEBUG_FUNCTION void
-debug_loop (struct loop *loop, int verbosity)
+debug_loop (class loop *loop, int verbosity)
{
print_loop (stderr, loop, 0, verbosity);
}
diff --git a/gcc/tree-cfg.h b/gcc/tree-cfg.h
index 836f8e8..7329161 100644
--- a/gcc/tree-cfg.h
+++ b/gcc/tree-cfg.h
@@ -83,12 +83,12 @@ extern void dump_function_to_file (tree, FILE *, dump_flags_t);
extern void debug_function (tree, dump_flags_t);
extern void print_loops_bb (FILE *, basic_block, int, int);
extern void print_loops (FILE *, int);
-extern void debug (struct loop &ref);
-extern void debug (struct loop *ptr);
-extern void debug_verbose (struct loop &ref);
-extern void debug_verbose (struct loop *ptr);
+extern void debug (class loop &ref);
+extern void debug (class loop *ptr);
+extern void debug_verbose (class loop &ref);
+extern void debug_verbose (class loop *ptr);
extern void debug_loops (int);
-extern void debug_loop (struct loop *, int);
+extern void debug_loop (class loop *, int);
extern void debug_loop_num (unsigned, int);
extern void remove_edge_and_dominated_blocks (edge);
extern bool gimple_purge_dead_eh_edges (basic_block);
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index f50fd20..5ed62260 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -52,8 +52,8 @@ chrec_fold_plus_poly_poly (enum tree_code code,
tree poly1)
{
tree left, right;
- struct loop *loop0 = get_chrec_loop (poly0);
- struct loop *loop1 = get_chrec_loop (poly1);
+ class loop *loop0 = get_chrec_loop (poly0);
+ class loop *loop1 = get_chrec_loop (poly1);
tree rtype = code == POINTER_PLUS_EXPR ? chrec_type (poly1) : type;
gcc_assert (poly0);
@@ -144,8 +144,8 @@ chrec_fold_multiply_poly_poly (tree type,
{
tree t0, t1, t2;
int var;
- struct loop *loop0 = get_chrec_loop (poly0);
- struct loop *loop1 = get_chrec_loop (poly1);
+ class loop *loop0 = get_chrec_loop (poly0);
+ class loop *loop1 = get_chrec_loop (poly1);
gcc_assert (poly0);
gcc_assert (poly1);
@@ -539,7 +539,7 @@ chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k)
{
tree arg0, arg1, binomial_n_k;
tree type = TREE_TYPE (chrec);
- struct loop *var_loop = get_loop (cfun, var);
+ class loop *var_loop = get_loop (cfun, var);
while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
&& flow_loop_nested_p (var_loop, get_chrec_loop (chrec)))
@@ -720,7 +720,7 @@ tree
hide_evolution_in_other_loops_than_loop (tree chrec,
unsigned loop_num)
{
- struct loop *loop = get_loop (cfun, loop_num), *chloop;
+ class loop *loop = get_loop (cfun, loop_num), *chloop;
if (automatically_generated_chrec_p (chrec))
return chrec;
@@ -761,7 +761,7 @@ chrec_component_in_loop_num (tree chrec,
bool right)
{
tree component;
- struct loop *loop = get_loop (cfun, loop_num), *chloop;
+ class loop *loop = get_loop (cfun, loop_num), *chloop;
if (automatically_generated_chrec_p (chrec))
return chrec;
@@ -843,7 +843,7 @@ reset_evolution_in_loop (unsigned loop_num,
tree chrec,
tree new_evol)
{
- struct loop *loop = get_loop (cfun, loop_num);
+ class loop *loop = get_loop (cfun, loop_num);
if (POINTER_TYPE_P (chrec_type (chrec)))
gcc_assert (ptrofftype_p (chrec_type (new_evol)));
@@ -939,7 +939,7 @@ is_multivariate_chrec (const_tree chrec)
static bool
chrec_contains_symbols (const_tree chrec, hash_set<const_tree> &visited,
- struct loop *loop)
+ class loop *loop)
{
int i, n;
@@ -977,7 +977,7 @@ chrec_contains_symbols (const_tree chrec, hash_set<const_tree> &visited,
the chrec is considered as a SYMBOL. */
bool
-chrec_contains_symbols (const_tree chrec, struct loop* loop)
+chrec_contains_symbols (const_tree chrec, class loop* loop)
{
hash_set<const_tree> visited;
return chrec_contains_symbols (chrec, visited, loop);
@@ -1296,7 +1296,7 @@ nb_vars_in_chrec (tree chrec)
the conversion succeeded, false otherwise. */
bool
-convert_affine_scev (struct loop *loop, tree type,
+convert_affine_scev (class loop *loop, tree type,
tree *base, tree *step, gimple *at_stmt,
bool use_overflow_semantics, tree from)
{
@@ -1427,7 +1427,7 @@ chrec_convert_1 (tree type, tree chrec, gimple *at_stmt,
{
tree ct, res;
tree base, step;
- struct loop *loop;
+ class loop *loop;
if (automatically_generated_chrec_p (chrec))
return chrec;
@@ -1563,7 +1563,7 @@ chrec_convert_aggressive (tree type, tree chrec, bool *fold_conversions)
if (!*fold_conversions && evolution_function_is_affine_p (chrec))
{
tree base, step;
- struct loop *loop;
+ class loop *loop;
loop = get_chrec_loop (chrec);
base = CHREC_LEFT (chrec);
diff --git a/gcc/tree-chrec.h b/gcc/tree-chrec.h
index 3b5c090..423d8fb 100644
--- a/gcc/tree-chrec.h
+++ b/gcc/tree-chrec.h
@@ -77,13 +77,13 @@ extern tree hide_evolution_in_other_loops_than_loop (tree, unsigned);
extern tree reset_evolution_in_loop (unsigned, tree, tree);
extern tree chrec_merge (tree, tree);
extern void for_each_scev_op (tree *, bool (*) (tree *, void *), void *);
-extern bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple *,
+extern bool convert_affine_scev (class loop *, tree, tree *, tree *, gimple *,
bool, tree = NULL);
/* Observers. */
extern bool eq_evolutions_p (const_tree, const_tree);
extern bool is_multivariate_chrec (const_tree);
-extern bool chrec_contains_symbols (const_tree, struct loop * = NULL);
+extern bool chrec_contains_symbols (const_tree, class loop * = NULL);
extern bool chrec_contains_symbols_defined_in_loop (const_tree, unsigned);
extern bool chrec_contains_undetermined (const_tree);
extern bool tree_contains_chrecs (const_tree, int *);
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 9ea8638..fa37a0d 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -448,6 +448,12 @@ enum omp_clause_code {
/* OpenMP clause: defaultmap (tofrom: scalar). */
OMP_CLAUSE_DEFAULTMAP,
+ /* OpenMP clause: order (concurrent). */
+ OMP_CLAUSE_ORDER,
+
+ /* OpenMP clause: bind (binding). */
+ OMP_CLAUSE_BIND,
+
/* Internally used only clause, holding SIMD uid. */
OMP_CLAUSE__SIMDUID_,
@@ -536,6 +542,12 @@ enum omp_clause_defaultmap_kind {
OMP_CLAUSE_DEFAULTMAP_MASK = 7 * (OMP_CLAUSE_DEFAULTMAP_CATEGORY_MASK + 1)
};
+enum omp_clause_bind_kind {
+ OMP_CLAUSE_BIND_TEAMS,
+ OMP_CLAUSE_BIND_PARALLEL,
+ OMP_CLAUSE_BIND_THREAD
+};
+
/* memory-order-clause on OpenMP atomic/flush constructs or
argument of atomic_default_mem_order clause. */
enum omp_memory_order {
@@ -1528,6 +1540,7 @@ struct GTY(()) tree_omp_clause {
enum omp_clause_linear_kind linear_kind;
enum tree_code if_modifier;
enum omp_clause_defaultmap_kind defaultmap_kind;
+ enum omp_clause_bind_kind bind_kind;
/* The dimension a OMP_CLAUSE__GRIDDIM_ clause of a gridified target
construct describes. */
unsigned int dimension;
@@ -1908,7 +1921,7 @@ struct GTY(()) tree_optimization_option {
/* Forward declaration, defined in target-globals.h. */
-struct GTY(()) target_globals;
+class GTY(()) target_globals;
/* Target options used by a function. */
@@ -1916,7 +1929,7 @@ struct GTY(()) tree_target_option {
struct tree_base base;
/* Target globals for the corresponding target option. */
- struct target_globals *globals;
+ class target_globals *globals;
/* The optimization options used by the user. */
struct cl_target_option *opts;
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 4dc03ef..7f75b7e 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -127,7 +127,7 @@ static struct datadep_stats
static bool subscript_dependence_tester_1 (struct data_dependence_relation *,
unsigned int, unsigned int,
- struct loop *);
+ class loop *);
/* Returns true iff A divides B. */
static inline bool
@@ -448,7 +448,7 @@ dump_data_dependence_relation (FILE *outf,
else if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
{
unsigned int i;
- struct loop *loopi;
+ class loop *loopi;
subscript *sub;
FOR_EACH_VEC_ELT (DDR_SUBSCRIPTS (ddr), i, sub)
@@ -583,7 +583,8 @@ debug_ddrs (vec<ddr_p> ddrs)
static void
split_constant_offset (tree exp, tree *var, tree *off,
- hash_map<tree, std::pair<tree, tree> > &cache);
+ hash_map<tree, std::pair<tree, tree> > &cache,
+ unsigned *limit);
/* Helper function for split_constant_offset. Expresses OP0 CODE OP1
(the type of the result is TYPE) as VAR + OFF, where OFF is a nonzero
@@ -594,7 +595,8 @@ split_constant_offset (tree exp, tree *var, tree *off,
static bool
split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
tree *var, tree *off,
- hash_map<tree, std::pair<tree, tree> > &cache)
+ hash_map<tree, std::pair<tree, tree> > &cache,
+ unsigned *limit)
{
tree var0, var1;
tree off0, off1;
@@ -615,8 +617,15 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
/* FALLTHROUGH */
case PLUS_EXPR:
case MINUS_EXPR:
- split_constant_offset (op0, &var0, &off0, cache);
- split_constant_offset (op1, &var1, &off1, cache);
+ if (TREE_CODE (op1) == INTEGER_CST)
+ {
+ split_constant_offset (op0, &var0, &off0, cache, limit);
+ *var = var0;
+ *off = size_binop (ocode, off0, fold_convert (ssizetype, op1));
+ return true;
+ }
+ split_constant_offset (op0, &var0, &off0, cache, limit);
+ split_constant_offset (op1, &var1, &off1, cache, limit);
*var = fold_build2 (code, type, var0, var1);
*off = size_binop (ocode, off0, off1);
return true;
@@ -625,7 +634,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
if (TREE_CODE (op1) != INTEGER_CST)
return false;
- split_constant_offset (op0, &var0, &off0, cache);
+ split_constant_offset (op0, &var0, &off0, cache, limit);
*var = fold_build2 (MULT_EXPR, type, var0, op1);
*off = size_binop (MULT_EXPR, off0, fold_convert (ssizetype, op1));
return true;
@@ -649,7 +658,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
if (poffset)
{
- split_constant_offset (poffset, &poffset, &off1, cache);
+ split_constant_offset (poffset, &poffset, &off1, cache, limit);
off0 = size_binop (PLUS_EXPR, off0, off1);
if (POINTER_TYPE_P (TREE_TYPE (base)))
base = fold_build_pointer_plus (base, poffset);
@@ -719,11 +728,15 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
e = std::make_pair (op0, ssize_int (0));
}
+ if (*limit == 0)
+ return false;
+ --*limit;
+
var0 = gimple_assign_rhs1 (def_stmt);
var1 = gimple_assign_rhs2 (def_stmt);
bool res = split_constant_offset_1 (type, var0, subcode, var1,
- var, off, cache);
+ var, off, cache, limit);
if (res && use_cache)
*cache.get (op0) = std::make_pair (*var, *off);
return res;
@@ -746,7 +759,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
/* Split the unconverted operand and try to prove that
wrapping isn't a problem. */
tree tmp_var, tmp_off;
- split_constant_offset (op0, &tmp_var, &tmp_off, cache);
+ split_constant_offset (op0, &tmp_var, &tmp_off, cache, limit);
/* See whether we have an SSA_NAME whose range is known
to be [A, B]. */
@@ -781,7 +794,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
*off = wide_int_to_tree (ssizetype, diff);
}
else
- split_constant_offset (op0, &var0, off, cache);
+ split_constant_offset (op0, &var0, off, cache, limit);
*var = fold_convert (type, var0);
return true;
}
@@ -798,7 +811,8 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
static void
split_constant_offset (tree exp, tree *var, tree *off,
- hash_map<tree, std::pair<tree, tree> > &cache)
+ hash_map<tree, std::pair<tree, tree> > &cache,
+ unsigned *limit)
{
tree type = TREE_TYPE (exp), op0, op1, e, o;
enum tree_code code;
@@ -812,7 +826,7 @@ split_constant_offset (tree exp, tree *var, tree *off,
code = TREE_CODE (exp);
extract_ops_from_tree (exp, &code, &op0, &op1);
- if (split_constant_offset_1 (type, op0, code, op1, &e, &o, cache))
+ if (split_constant_offset_1 (type, op0, code, op1, &e, &o, cache, limit))
{
*var = e;
*off = o;
@@ -822,10 +836,11 @@ split_constant_offset (tree exp, tree *var, tree *off,
void
split_constant_offset (tree exp, tree *var, tree *off)
{
+ unsigned limit = PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT);
static hash_map<tree, std::pair<tree, tree> > *cache;
if (!cache)
cache = new hash_map<tree, std::pair<tree, tree> > (37);
- split_constant_offset (exp, var, off, *cache);
+ split_constant_offset (exp, var, off, *cache, &limit);
cache->empty ();
}
@@ -873,7 +888,7 @@ canonicalize_base_object_address (tree addr)
opt_result
dr_analyze_innermost (innermost_loop_behavior *drb, tree ref,
- struct loop *loop, const gimple *stmt)
+ class loop *loop, const gimple *stmt)
{
poly_int64 pbitsize, pbitpos;
tree base, poffset;
@@ -1351,7 +1366,7 @@ data_ref_compare_tree (tree t1, tree t2)
check. */
opt_result
-runtime_alias_check_p (ddr_p ddr, struct loop *loop, bool speed_p)
+runtime_alias_check_p (ddr_p ddr, class loop *loop, bool speed_p)
{
if (dump_enabled_p ())
dump_printf (MSG_NOTE,
@@ -1624,7 +1639,7 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs,
Note evolution step of index needs to be considered in comparison. */
static bool
-create_intersect_range_checks_index (struct loop *loop, tree *cond_expr,
+create_intersect_range_checks_index (class loop *loop, tree *cond_expr,
const dr_with_seg_len& dr_a,
const dr_with_seg_len& dr_b)
{
@@ -1858,7 +1873,7 @@ get_segment_min_max (const dr_with_seg_len &d, tree *seg_min_out,
|| (DR_B_addr_0 + DER_B_segment_length_0) <= DR_A_addr_0)) */
static void
-create_intersect_range_checks (struct loop *loop, tree *cond_expr,
+create_intersect_range_checks (class loop *loop, tree *cond_expr,
const dr_with_seg_len& dr_a,
const dr_with_seg_len& dr_b)
{
@@ -1917,7 +1932,7 @@ create_intersect_range_checks (struct loop *loop, tree *cond_expr,
that controls which version of the loop gets executed at runtime. */
void
-create_runtime_alias_checks (struct loop *loop,
+create_runtime_alias_checks (class loop *loop,
vec<dr_with_seg_len_pair_t> *alias_pairs,
tree * cond_expr)
{
@@ -2197,7 +2212,7 @@ conflict_fn_no_dependence (void)
/* Returns true if the address of OBJ is invariant in LOOP. */
static bool
-object_address_invariant_in_loop_p (const struct loop *loop, const_tree obj)
+object_address_invariant_in_loop_p (const class loop *loop, const_tree obj)
{
while (handled_component_p (obj))
{
@@ -2231,7 +2246,7 @@ object_address_invariant_in_loop_p (const struct loop *loop, const_tree obj)
bool
dr_may_alias_p (const struct data_reference *a, const struct data_reference *b,
- struct loop *loop_nest)
+ class loop *loop_nest)
{
tree addr_a = DR_BASE_OBJECT (a);
tree addr_b = DR_BASE_OBJECT (b);
@@ -2892,7 +2907,7 @@ analyze_ziv_subscript (tree chrec_a,
chrec_dont_know. */
static tree
-max_stmt_executions_tree (struct loop *loop)
+max_stmt_executions_tree (class loop *loop)
{
widest_int nit;
@@ -3046,7 +3061,7 @@ analyze_siv_subscript_cst_affine (tree chrec_a,
if (tree_fold_divides_p (CHREC_RIGHT (chrec_b), difference))
{
HOST_WIDE_INT numiter;
- struct loop *loop = get_chrec_loop (chrec_b);
+ class loop *loop = get_chrec_loop (chrec_b);
*overlaps_a = conflict_fn (1, affine_fn_cst (integer_zero_node));
tmp = fold_build2 (EXACT_DIV_EXPR, type,
@@ -3127,7 +3142,7 @@ analyze_siv_subscript_cst_affine (tree chrec_a,
if (tree_fold_divides_p (CHREC_RIGHT (chrec_b), difference))
{
HOST_WIDE_INT numiter;
- struct loop *loop = get_chrec_loop (chrec_b);
+ class loop *loop = get_chrec_loop (chrec_b);
*overlaps_a = conflict_fn (1, affine_fn_cst (integer_zero_node));
tmp = fold_build2 (EXACT_DIV_EXPR, type, difference,
@@ -4023,7 +4038,7 @@ analyze_miv_subscript (tree chrec_a,
conflict_function **overlaps_a,
conflict_function **overlaps_b,
tree *last_conflicts,
- struct loop *loop_nest)
+ class loop *loop_nest)
{
tree type, difference;
@@ -4125,7 +4140,7 @@ analyze_overlapping_iterations (tree chrec_a,
tree chrec_b,
conflict_function **overlap_iterations_a,
conflict_function **overlap_iterations_b,
- tree *last_conflicts, struct loop *loop_nest)
+ tree *last_conflicts, class loop *loop_nest)
{
unsigned int lnn = loop_nest->num;
@@ -4275,7 +4290,7 @@ build_classic_dist_vector_1 (struct data_dependence_relation *ddr,
{
unsigned i;
lambda_vector init_v = lambda_vector_new (DDR_NB_LOOPS (ddr));
- struct loop *loop = DDR_LOOP_NEST (ddr)[0];
+ class loop *loop = DDR_LOOP_NEST (ddr)[0];
for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
{
@@ -4426,7 +4441,7 @@ add_other_self_distances (struct data_dependence_relation *ddr)
unsigned i;
int index_carry = DDR_NB_LOOPS (ddr);
subscript *sub;
- struct loop *loop = DDR_LOOP_NEST (ddr)[0];
+ class loop *loop = DDR_LOOP_NEST (ddr)[0];
FOR_EACH_VEC_ELT (DDR_SUBSCRIPTS (ddr), i, sub)
{
@@ -4546,7 +4561,7 @@ same_access_functions (const struct data_dependence_relation *ddr)
static bool
build_classic_dist_vector (struct data_dependence_relation *ddr,
- struct loop *loop_nest)
+ class loop *loop_nest)
{
bool init_b = false;
int index_carry = DDR_NB_LOOPS (ddr);
@@ -4733,7 +4748,7 @@ build_classic_dir_vector (struct data_dependence_relation *ddr)
static bool
subscript_dependence_tester_1 (struct data_dependence_relation *ddr,
unsigned int a_index, unsigned int b_index,
- struct loop *loop_nest)
+ class loop *loop_nest)
{
unsigned int i;
tree last_conflicts;
@@ -4792,7 +4807,7 @@ subscript_dependence_tester_1 (struct data_dependence_relation *ddr,
static void
subscript_dependence_tester (struct data_dependence_relation *ddr,
- struct loop *loop_nest)
+ class loop *loop_nest)
{
if (subscript_dependence_tester_1 (ddr, 0, 1, loop_nest))
dependence_stats.num_dependence_dependent++;
@@ -4807,7 +4822,7 @@ subscript_dependence_tester (struct data_dependence_relation *ddr,
static bool
access_functions_are_affine_or_constant_p (const struct data_reference *a,
- const struct loop *loop_nest)
+ const class loop *loop_nest)
{
unsigned int i;
vec<tree> fns = DR_ACCESS_FNS (a);
@@ -4832,7 +4847,7 @@ access_functions_are_affine_or_constant_p (const struct data_reference *a,
void
compute_affine_dependence (struct data_dependence_relation *ddr,
- struct loop *loop_nest)
+ class loop *loop_nest)
{
struct data_reference *dra = DDR_A (ddr);
struct data_reference *drb = DDR_B (ddr);
@@ -4975,7 +4990,7 @@ get_references_in_stmt (gimple *stmt, vec<data_ref_loc, va_heap> *references)
{
case IFN_GOMP_SIMD_LANE:
{
- struct loop *loop = gimple_bb (stmt)->loop_father;
+ class loop *loop = gimple_bb (stmt)->loop_father;
tree uid = gimple_call_arg (stmt, 0);
gcc_assert (TREE_CODE (uid) == SSA_NAME);
if (loop == NULL
@@ -5117,7 +5132,7 @@ loop_nest_has_data_refs (loop_p loop)
loop of the loop nest in which the references should be analyzed. */
opt_result
-find_data_references_in_stmt (struct loop *nest, gimple *stmt,
+find_data_references_in_stmt (class loop *nest, gimple *stmt,
vec<data_reference_p> *datarefs)
{
unsigned i;
@@ -5176,7 +5191,7 @@ graphite_find_data_references_in_stmt (edge nest, loop_p loop, gimple *stmt,
difficult case, returns NULL_TREE otherwise. */
tree
-find_data_references_in_bb (struct loop *loop, basic_block bb,
+find_data_references_in_bb (class loop *loop, basic_block bb,
vec<data_reference_p> *datarefs)
{
gimple_stmt_iterator bsi;
@@ -5206,7 +5221,7 @@ find_data_references_in_bb (struct loop *loop, basic_block bb,
arithmetic as if they were array accesses, etc. */
tree
-find_data_references_in_loop (struct loop *loop,
+find_data_references_in_loop (class loop *loop,
vec<data_reference_p> *datarefs)
{
basic_block bb, *bbs;
@@ -5331,7 +5346,7 @@ get_base_for_alignment (tree addr, unsigned int *max_alignment)
/* Recursive helper function. */
static bool
-find_loop_nest_1 (struct loop *loop, vec<loop_p> *loop_nest)
+find_loop_nest_1 (class loop *loop, vec<loop_p> *loop_nest)
{
/* Inner loops of the nest should not contain siblings. Example:
when there are two consecutive loops,
@@ -5362,7 +5377,7 @@ find_loop_nest_1 (struct loop *loop, vec<loop_p> *loop_nest)
appear in the classic distance vector. */
bool
-find_loop_nest (struct loop *loop, vec<loop_p> *loop_nest)
+find_loop_nest (class loop *loop, vec<loop_p> *loop_nest)
{
loop_nest->safe_push (loop);
if (loop->inner)
@@ -5378,7 +5393,7 @@ find_loop_nest (struct loop *loop, vec<loop_p> *loop_nest)
COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE. */
bool
-compute_data_dependences_for_loop (struct loop *loop,
+compute_data_dependences_for_loop (class loop *loop,
bool compute_self_and_read_read_dependences,
vec<loop_p> *loop_nest,
vec<data_reference_p> *datarefs,
diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h
index 69d5a82..998937f 100644
--- a/gcc/tree-data-ref.h
+++ b/gcc/tree-data-ref.h
@@ -203,8 +203,9 @@ typedef struct data_reference *data_reference_p;
including the data ref itself and the segment length for aliasing
checks. This is used to merge alias checks. */
-struct dr_with_seg_len
+class dr_with_seg_len
{
+public:
dr_with_seg_len (data_reference_p d, tree len, unsigned HOST_WIDE_INT size,
unsigned int a)
: dr (d), seg_len (len), access_size (size), align (a) {}
@@ -224,8 +225,9 @@ struct dr_with_seg_len
/* This struct contains two dr_with_seg_len objects with aliasing data
refs. Two comparisons are generated from them. */
-struct dr_with_seg_len_pair_t
+class dr_with_seg_len_pair_t
{
+public:
dr_with_seg_len_pair_t (const dr_with_seg_len& d1,
const dr_with_seg_len& d2)
: first (d1), second (d2) {}
@@ -419,8 +421,8 @@ typedef struct data_dependence_relation *ddr_p;
opt_result dr_analyze_innermost (innermost_loop_behavior *, tree,
- struct loop *, const gimple *);
-extern bool compute_data_dependences_for_loop (struct loop *, bool,
+ class loop *, const gimple *);
+extern bool compute_data_dependences_for_loop (class loop *, bool,
vec<loop_p> *,
vec<data_reference_p> *,
vec<ddr_p> *);
@@ -441,15 +443,15 @@ extern void free_dependence_relation (struct data_dependence_relation *);
extern void free_dependence_relations (vec<ddr_p> );
extern void free_data_ref (data_reference_p);
extern void free_data_refs (vec<data_reference_p> );
-extern opt_result find_data_references_in_stmt (struct loop *, gimple *,
+extern opt_result find_data_references_in_stmt (class loop *, gimple *,
vec<data_reference_p> *);
extern bool graphite_find_data_references_in_stmt (edge, loop_p, gimple *,
vec<data_reference_p> *);
-tree find_data_references_in_loop (struct loop *, vec<data_reference_p> *);
+tree find_data_references_in_loop (class loop *, vec<data_reference_p> *);
bool loop_nest_has_data_refs (loop_p loop);
struct data_reference *create_data_ref (edge, loop_p, tree, gimple *, bool,
bool);
-extern bool find_loop_nest (struct loop *, vec<loop_p> *);
+extern bool find_loop_nest (class loop *, vec<loop_p> *);
extern struct data_dependence_relation *initialize_data_dependence_relation
(struct data_reference *, struct data_reference *, vec<loop_p>);
extern void compute_affine_dependence (struct data_dependence_relation *,
@@ -458,7 +460,7 @@ extern void compute_self_dependence (struct data_dependence_relation *);
extern bool compute_all_dependences (vec<data_reference_p> ,
vec<ddr_p> *,
vec<loop_p>, bool);
-extern tree find_data_references_in_bb (struct loop *, basic_block,
+extern tree find_data_references_in_bb (class loop *, basic_block,
vec<data_reference_p> *);
extern unsigned int dr_alignment (innermost_loop_behavior *);
extern tree get_base_for_alignment (tree, unsigned int *);
@@ -473,15 +475,15 @@ dr_alignment (data_reference *dr)
}
extern bool dr_may_alias_p (const struct data_reference *,
- const struct data_reference *, struct loop *);
+ const struct data_reference *, class loop *);
extern bool dr_equal_offsets_p (struct data_reference *,
struct data_reference *);
-extern opt_result runtime_alias_check_p (ddr_p, struct loop *, bool);
+extern opt_result runtime_alias_check_p (ddr_p, class loop *, bool);
extern int data_ref_compare_tree (tree, tree);
extern void prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *,
poly_uint64);
-extern void create_runtime_alias_checks (struct loop *,
+extern void create_runtime_alias_checks (class loop *,
vec<dr_with_seg_len_pair_t> *, tree*);
extern tree dr_direction_indicator (struct data_reference *);
extern tree dr_zero_step_indicator (struct data_reference *);
@@ -572,7 +574,7 @@ ddr_dependence_level (ddr_p ddr)
static inline int
index_in_loop_nest (int var, vec<loop_p> loop_nest)
{
- struct loop *loopi;
+ class loop *loopi;
int var_index;
for (var_index = 0; loop_nest.iterate (var_index, &loopi); var_index++)
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index 58cb1ee..51c0965 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -604,6 +604,7 @@ dequeue_and_dump (dump_info_p di)
break;
case TRY_FINALLY_EXPR:
+ case EH_ELSE_EXPR:
dump_child ("op 0", TREE_OPERAND (t, 0));
dump_child ("op 1", TREE_OPERAND (t, 1));
break;
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 23c56b5..5bb07e4 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -503,7 +503,11 @@ replace_goto_queue_1 (gimple *stmt, struct leh_tf_state *tf,
seq = find_goto_replacement (tf, temp);
if (seq)
{
- gsi_insert_seq_before (gsi, gimple_seq_copy (seq), GSI_SAME_STMT);
+ gimple_stmt_iterator i;
+ seq = gimple_seq_copy (seq);
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ gimple_set_location (gsi_stmt (i), gimple_location (stmt));
+ gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
gsi_remove (gsi, false);
return;
}
@@ -811,15 +815,6 @@ emit_resx (gimple_seq *seq, eh_region region)
record_stmt_eh_region (region->outer, x);
}
-/* Emit an EH_DISPATCH statement into SEQ for REGION. */
-
-static void
-emit_eh_dispatch (gimple_seq *seq, eh_region region)
-{
- geh_dispatch *x = gimple_build_eh_dispatch (region->index);
- gimple_seq_add_stmt (seq, x);
-}
-
/* Note that the current EH region may contain a throw, or a
call to a function which itself may contain a throw. */
@@ -1001,11 +996,14 @@ honor_protect_cleanup_actions (struct leh_state *outer_state,
gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
finally = gimple_eh_else_e_body (eh_else);
- /* Let the ELSE see the exception that's being processed. */
- eh_region save_ehp = this_state->ehp_region;
- this_state->ehp_region = this_state->cur_region;
- lower_eh_constructs_1 (this_state, &finally);
- this_state->ehp_region = save_ehp;
+ /* Let the ELSE see the exception that's being processed, but
+ since the cleanup is outside the try block, process it with
+ outer_state, otherwise it may be used as a cleanup for
+ itself, and Bad Things (TM) ensue. */
+ eh_region save_ehp = outer_state->ehp_region;
+ outer_state->ehp_region = this_state->cur_region;
+ lower_eh_constructs_1 (outer_state, &finally);
+ outer_state->ehp_region = save_ehp;
}
else
{
@@ -1762,7 +1760,9 @@ lower_catch (struct leh_state *state, gtry *tp)
tree out_label;
gimple_seq new_seq, cleanup;
gimple *x;
+ geh_dispatch *eh_dispatch;
location_t try_catch_loc = gimple_location (tp);
+ location_t catch_loc = UNKNOWN_LOCATION;
if (flag_exceptions)
{
@@ -1776,7 +1776,8 @@ lower_catch (struct leh_state *state, gtry *tp)
return gimple_try_eval (tp);
new_seq = NULL;
- emit_eh_dispatch (&new_seq, try_region);
+ eh_dispatch = gimple_build_eh_dispatch (try_region->index);
+ gimple_seq_add_stmt (&new_seq, eh_dispatch);
emit_resx (&new_seq, try_region);
this_state.cur_region = state->cur_region;
@@ -1799,6 +1800,8 @@ lower_catch (struct leh_state *state, gtry *tp)
gimple_seq handler;
catch_stmt = as_a <gcatch *> (gsi_stmt (gsi));
+ if (catch_loc == UNKNOWN_LOCATION)
+ catch_loc = gimple_location (catch_stmt);
c = gen_eh_region_catch (try_region, gimple_catch_types (catch_stmt));
handler = gimple_catch_handler (catch_stmt);
@@ -1822,6 +1825,10 @@ lower_catch (struct leh_state *state, gtry *tp)
break;
}
+ /* Try to set a location on the dispatching construct to avoid inheriting
+ the location of the previous statement. */
+ gimple_set_location (eh_dispatch, catch_loc);
+
gimple_try_set_cleanup (tp, new_seq);
gimple_seq new_eh_seq = eh_seq;
@@ -1857,11 +1864,13 @@ lower_eh_filter (struct leh_state *state, gtry *tp)
if (!eh_region_may_contain_throw (this_region))
return gimple_try_eval (tp);
- new_seq = NULL;
this_state.cur_region = state->cur_region;
this_state.ehp_region = this_region;
- emit_eh_dispatch (&new_seq, this_region);
+ new_seq = NULL;
+ x = gimple_build_eh_dispatch (this_region->index);
+ gimple_set_location (x, gimple_location (tp));
+ gimple_seq_add_stmt (&new_seq, x);
emit_resx (&new_seq, this_region);
this_region->u.allowed.label = create_artificial_label (UNKNOWN_LOCATION);
@@ -3752,6 +3761,7 @@ lower_eh_dispatch (basic_block src, geh_dispatch *stmt)
filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)));
filter = make_ssa_name (filter, x);
gimple_call_set_lhs (x, filter);
+ gimple_set_location (x, gimple_location (stmt));
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
/* Turn the default label into a default case. */
@@ -3759,6 +3769,7 @@ lower_eh_dispatch (basic_block src, geh_dispatch *stmt)
sort_case_labels (labels);
x = gimple_build_switch (filter, default_label, labels);
+ gimple_set_location (x, gimple_location (stmt));
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
}
}
@@ -3775,6 +3786,7 @@ lower_eh_dispatch (basic_block src, geh_dispatch *stmt)
filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)));
filter = make_ssa_name (filter, x);
gimple_call_set_lhs (x, filter);
+ gimple_set_location (x, gimple_location (stmt));
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
r->u.allowed.label = NULL;
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 98566e3..d9e540f 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -502,7 +502,7 @@ fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
cd-equivalent if they are executed under the same condition. */
static inline void
-add_to_predicate_list (struct loop *loop, basic_block bb, tree nc)
+add_to_predicate_list (class loop *loop, basic_block bb, tree nc)
{
tree bc, *tp;
basic_block dom_bb;
@@ -567,7 +567,7 @@ add_to_predicate_list (struct loop *loop, basic_block bb, tree nc)
the loop to be if-converted. */
static void
-add_to_dst_predicate_list (struct loop *loop, edge e,
+add_to_dst_predicate_list (class loop *loop, edge e,
tree prev_cond, tree cond)
{
if (!flow_bb_inside_loop_p (loop, e->dest))
@@ -584,7 +584,7 @@ add_to_dst_predicate_list (struct loop *loop, edge e,
/* Return true if one of the successor edges of BB exits LOOP. */
static bool
-bb_with_exit_edge_p (struct loop *loop, basic_block bb)
+bb_with_exit_edge_p (class loop *loop, basic_block bb)
{
edge e;
edge_iterator ei;
@@ -661,7 +661,7 @@ phi_convertible_by_degenerating_args (gphi *phi)
ANY_COMPLICATED_PHI if PHI is complicated. */
static bool
-if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi)
+if_convertible_phi_p (class loop *loop, basic_block bb, gphi *phi)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -756,7 +756,7 @@ idx_within_array_bound (tree ref, tree *idx, void *dta)
widest_int niter, valid_niter, delta, wi_step;
tree ev, init, step;
tree low, high;
- struct loop *loop = (struct loop*) dta;
+ class loop *loop = (class loop*) dta;
/* Only support within-bound access for array references. */
if (TREE_CODE (ref) != ARRAY_REF)
@@ -822,7 +822,7 @@ idx_within_array_bound (tree ref, tree *idx, void *dta)
static bool
ref_within_array_bound (gimple *stmt, tree ref)
{
- struct loop *loop = loop_containing_stmt (stmt);
+ class loop *loop = loop_containing_stmt (stmt);
gcc_assert (loop != NULL);
return for_each_index (&ref, idx_within_array_bound, loop);
@@ -1128,7 +1128,7 @@ all_preds_critical_p (basic_block bb)
inside LOOP. */
static bool
-if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
+if_convertible_bb_p (class loop *loop, basic_block bb, basic_block exit_bb)
{
edge e;
edge_iterator ei;
@@ -1197,7 +1197,7 @@ pred_blocks_visited_p (basic_block bb, bitmap *visited)
predecessors are already selected. */
static basic_block *
-get_loop_body_in_if_conv_order (const struct loop *loop)
+get_loop_body_in_if_conv_order (const class loop *loop)
{
basic_block *blocks, *blocks_in_bfs_order;
basic_block bb;
@@ -1344,7 +1344,7 @@ predicate_bbs (loop_p loop)
/* Build region by adding loop pre-header and post-header blocks. */
static vec<basic_block>
-build_region (struct loop *loop)
+build_region (class loop *loop)
{
vec<basic_block> region = vNULL;
basic_block exit_bb = NULL;
@@ -1378,7 +1378,7 @@ build_region (struct loop *loop)
in if_convertible_loop_p. */
static bool
-if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs)
+if_convertible_loop_p_1 (class loop *loop, vec<data_reference_p> *refs)
{
unsigned int i;
basic_block exit_bb = NULL;
@@ -1518,7 +1518,7 @@ if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs)
- if its basic blocks and phi nodes are if convertible. */
static bool
-if_convertible_loop_p (struct loop *loop)
+if_convertible_loop_p (class loop *loop)
{
edge e;
edge_iterator ei;
@@ -1597,7 +1597,7 @@ is_cond_scalar_reduction (gimple *phi, gimple **reduc, tree arg_0, tree arg_1,
gimple *header_phi = NULL;
enum tree_code reduction_op;
basic_block bb = gimple_bb (phi);
- struct loop *loop = bb->loop_father;
+ class loop *loop = bb->loop_father;
edge latch_e = loop_latch_edge (loop);
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -2004,7 +2004,7 @@ predicate_scalar_phi (gphi *phi, gimple_stmt_iterator *gsi)
LOOP->header block with conditional modify expressions. */
static void
-predicate_all_scalar_phis (struct loop *loop)
+predicate_all_scalar_phis (class loop *loop)
{
basic_block bb;
unsigned int orig_loop_num_nodes = loop->num_nodes;
@@ -2526,7 +2526,7 @@ remove_conditions_and_labels (loop_p loop)
blocks. Replace PHI nodes with conditional modify expressions. */
static void
-combine_blocks (struct loop *loop)
+combine_blocks (class loop *loop)
{
basic_block bb, exit_bb, merge_target_bb;
unsigned int orig_loop_num_nodes = loop->num_nodes;
@@ -2719,12 +2719,12 @@ combine_blocks (struct loop *loop)
out of LOOP_VECTORIZED must have 100% probability so the profile remains
consistent after the condition is folded in the vectorizer. */
-static struct loop *
-version_loop_for_if_conversion (struct loop *loop, vec<gimple *> *preds)
+static class loop *
+version_loop_for_if_conversion (class loop *loop, vec<gimple *> *preds)
{
basic_block cond_bb;
tree cond = make_ssa_name (boolean_type_node);
- struct loop *new_loop;
+ class loop *new_loop;
gimple *g;
gimple_stmt_iterator gsi;
unsigned int save_length;
@@ -2781,7 +2781,7 @@ version_loop_for_if_conversion (struct loop *loop, vec<gimple *> *preds)
inner loop's exit block. */
static bool
-versionable_outer_loop_p (struct loop *loop)
+versionable_outer_loop_p (class loop *loop)
{
if (!loop_outer (loop)
|| loop->dont_vectorize
@@ -2815,7 +2815,7 @@ versionable_outer_loop_p (struct loop *loop)
Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */
static bool
-ifcvt_split_critical_edges (struct loop *loop, bool aggressive_if_conv)
+ifcvt_split_critical_edges (class loop *loop, bool aggressive_if_conv)
{
basic_block *body;
basic_block bb;
@@ -2982,11 +2982,11 @@ ifcvt_local_dce (basic_block bb)
changed. */
unsigned int
-tree_if_conversion (struct loop *loop, vec<gimple *> *preds)
+tree_if_conversion (class loop *loop, vec<gimple *> *preds)
{
unsigned int todo = 0;
bool aggressive_if_conv;
- struct loop *rloop;
+ class loop *rloop;
bitmap exit_bbs;
again:
@@ -3001,7 +3001,7 @@ tree_if_conversion (struct loop *loop, vec<gimple *> *preds)
aggressive_if_conv = loop->force_vectorize;
if (!aggressive_if_conv)
{
- struct loop *outer_loop = loop_outer (loop);
+ class loop *outer_loop = loop_outer (loop);
if (outer_loop && outer_loop->force_vectorize)
aggressive_if_conv = true;
}
@@ -3027,10 +3027,10 @@ tree_if_conversion (struct loop *loop, vec<gimple *> *preds)
|| any_complicated_phi
|| flag_tree_loop_if_convert != 1)
{
- struct loop *vloop
+ class loop *vloop
= (versionable_outer_loop_p (loop_outer (loop))
? loop_outer (loop) : loop);
- struct loop *nloop = version_loop_for_if_conversion (vloop, preds);
+ class loop *nloop = version_loop_for_if_conversion (vloop, preds);
if (nloop == NULL)
goto cleanup;
if (vloop != loop)
@@ -3138,7 +3138,7 @@ pass_if_conversion::gate (function *fun)
unsigned int
pass_if_conversion::execute (function *fun)
{
- struct loop *loop;
+ class loop *loop;
unsigned todo = 0;
if (number_of_loops (fun) <= 1)
diff --git a/gcc/tree-if-conv.h b/gcc/tree-if-conv.h
index c136ebb..a83380b 100644
--- a/gcc/tree-if-conv.h
+++ b/gcc/tree-if-conv.h
@@ -19,6 +19,6 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_IF_CONV_H
#define GCC_TREE_IF_CONV_H
-unsigned int tree_if_conversion (struct loop *, vec<gimple *> * = NULL);
+unsigned int tree_if_conversion (class loop *, vec<gimple *> * = NULL);
#endif /* GCC_TREE_IF_CONV_H */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 42e4597..4311309 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2804,15 +2804,15 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
static void
copy_loops (copy_body_data *id,
- struct loop *dest_parent, struct loop *src_parent)
+ class loop *dest_parent, class loop *src_parent)
{
- struct loop *src_loop = src_parent->inner;
+ class loop *src_loop = src_parent->inner;
while (src_loop)
{
if (!id->blocks_to_copy
|| bitmap_bit_p (id->blocks_to_copy, src_loop->header->index))
{
- struct loop *dest_loop = alloc_loop ();
+ class loop *dest_loop = alloc_loop ();
/* Assign the new loop its header and latch and associate
those with the new loop. */
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 3881aaf..8178486 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -506,7 +506,7 @@ bb_top_order_cmp (const void *x, const void *y)
statements in loop copies. */
static void
-stmts_from_loop (struct loop *loop, vec<gimple *> *stmts)
+stmts_from_loop (class loop *loop, vec<gimple *> *stmts)
{
unsigned int i;
basic_block *bbs = get_loop_body_in_custom_order (loop, bb_top_order_cmp);
@@ -564,7 +564,7 @@ free_rdg (struct graph *rdg)
collected and recorded in global data DATAREFS_VEC. */
static struct graph *
-build_rdg (struct loop *loop, control_dependences *cd)
+build_rdg (class loop *loop, control_dependences *cd)
{
struct graph *rdg;
@@ -787,10 +787,10 @@ stmt_has_scalar_dependences_outside_loop (loop_p loop, gimple *stmt)
/* Return a copy of LOOP placed before LOOP. */
-static struct loop *
-copy_loop_before (struct loop *loop)
+static class loop *
+copy_loop_before (class loop *loop)
{
- struct loop *res;
+ class loop *res;
edge preheader = loop_preheader_edge (loop);
initialize_original_copy_tables ();
@@ -805,7 +805,7 @@ copy_loop_before (struct loop *loop)
/* Creates an empty basic block after LOOP. */
static void
-create_bb_after_loop (struct loop *loop)
+create_bb_after_loop (class loop *loop)
{
edge exit = single_exit (loop);
@@ -822,7 +822,7 @@ create_bb_after_loop (struct loop *loop)
basic blocks of a loop are taken in dom order. */
static void
-generate_loops_for_partition (struct loop *loop, partition *partition,
+generate_loops_for_partition (class loop *loop, partition *partition,
bool copy_p)
{
unsigned i;
@@ -994,7 +994,7 @@ const_with_all_bytes_same (tree val)
/* Generate a call to memset for PARTITION in LOOP. */
static void
-generate_memset_builtin (struct loop *loop, partition *partition)
+generate_memset_builtin (class loop *loop, partition *partition)
{
gimple_stmt_iterator gsi;
tree mem, fn, nb_bytes;
@@ -1048,7 +1048,7 @@ generate_memset_builtin (struct loop *loop, partition *partition)
/* Generate a call to memcpy for PARTITION in LOOP. */
static void
-generate_memcpy_builtin (struct loop *loop, partition *partition)
+generate_memcpy_builtin (class loop *loop, partition *partition)
{
gimple_stmt_iterator gsi;
gimple *fn_call;
@@ -1092,7 +1092,7 @@ generate_memcpy_builtin (struct loop *loop, partition *partition)
/* Remove and destroy the loop LOOP. */
static void
-destroy_loop (struct loop *loop)
+destroy_loop (class loop *loop)
{
unsigned nbbs = loop->num_nodes;
edge exit = single_exit (loop);
@@ -1169,7 +1169,7 @@ destroy_loop (struct loop *loop)
/* Generates code for PARTITION. Return whether LOOP needs to be destroyed. */
static bool
-generate_code_for_partition (struct loop *loop,
+generate_code_for_partition (class loop *loop,
partition *partition, bool copy_p)
{
switch (partition->kind)
@@ -1346,7 +1346,7 @@ build_rdg_partition_for_vertex (struct graph *rdg, int v)
data references. */
static bool
-find_single_drs (struct loop *loop, struct graph *rdg, partition *partition,
+find_single_drs (class loop *loop, struct graph *rdg, partition *partition,
data_reference_p *dst_dr, data_reference_p *src_dr)
{
unsigned i;
@@ -1469,7 +1469,7 @@ compute_access_range (loop_p loop_nest, data_reference_p dr, tree *base,
{
location_t loc = gimple_location (DR_STMT (dr));
basic_block bb = gimple_bb (DR_STMT (dr));
- struct loop *loop = bb->loop_father;
+ class loop *loop = bb->loop_father;
tree ref = DR_REF (dr);
tree access_base = build_fold_addr_expr (ref);
tree access_size = TYPE_SIZE_UNIT (TREE_TYPE (ref));
@@ -2426,7 +2426,7 @@ data_ref_segment_size (struct data_reference *dr, tree niters)
DR. */
static inline bool
-latch_dominated_by_data_ref (struct loop *loop, data_reference *dr)
+latch_dominated_by_data_ref (class loop *loop, data_reference *dr)
{
return dominated_by_p (CDI_DOMINATORS, single_exit (loop)->src,
gimple_bb (DR_STMT (dr)));
@@ -2436,7 +2436,7 @@ latch_dominated_by_data_ref (struct loop *loop, data_reference *dr)
data dependence relations ALIAS_DDRS. */
static void
-compute_alias_check_pairs (struct loop *loop, vec<ddr_p> *alias_ddrs,
+compute_alias_check_pairs (class loop *loop, vec<ddr_p> *alias_ddrs,
vec<dr_with_seg_len_pair_t> *comp_alias_pairs)
{
unsigned int i;
@@ -2508,11 +2508,11 @@ compute_alias_check_pairs (struct loop *loop, vec<ddr_p> *alias_ddrs,
static void
version_loop_by_alias_check (vec<struct partition *> *partitions,
- struct loop *loop, vec<ddr_p> *alias_ddrs)
+ class loop *loop, vec<ddr_p> *alias_ddrs)
{
profile_probability prob;
basic_block cond_bb;
- struct loop *nloop;
+ class loop *nloop;
tree lhs, arg0, cond_expr = NULL_TREE;
gimple_seq cond_stmts = NULL;
gimple *call_stmt = NULL;
@@ -2723,7 +2723,7 @@ fuse_memset_builtins (vec<struct partition *> *partitions)
ALIAS_DDRS contains ddrs which need runtime alias check. */
static void
-finalize_partitions (struct loop *loop, vec<struct partition *> *partitions,
+finalize_partitions (class loop *loop, vec<struct partition *> *partitions,
vec<ddr_p> *alias_ddrs)
{
unsigned i;
@@ -2780,7 +2780,7 @@ finalize_partitions (struct loop *loop, vec<struct partition *> *partitions,
Set *DESTROY_P to whether LOOP needs to be destroyed. */
static int
-distribute_loop (struct loop *loop, vec<gimple *> stmts,
+distribute_loop (class loop *loop, vec<gimple *> stmts,
control_dependences *cd, int *nb_calls, bool *destroy_p,
bool only_patterns_p)
{
@@ -3060,7 +3060,7 @@ public:
WORK_LIST. Return false if there is nothing for distribution. */
static bool
-find_seed_stmts_for_distribution (struct loop *loop, vec<gimple *> *work_list)
+find_seed_stmts_for_distribution (class loop *loop, vec<gimple *> *work_list)
{
basic_block *bbs = get_loop_body_in_dom_order (loop);
@@ -3114,10 +3114,10 @@ find_seed_stmts_for_distribution (struct loop *loop, vec<gimple *> *work_list)
/* Given innermost LOOP, return the outermost enclosing loop that forms a
perfect loop nest. */
-static struct loop *
-prepare_perfect_loop_nest (struct loop *loop)
+static class loop *
+prepare_perfect_loop_nest (class loop *loop)
{
- struct loop *outer = loop_outer (loop);
+ class loop *outer = loop_outer (loop);
tree niters = number_of_latch_executions (loop);
/* TODO: We only support the innermost 3-level loop nest distribution
@@ -3143,7 +3143,7 @@ prepare_perfect_loop_nest (struct loop *loop)
unsigned int
pass_loop_distribution::execute (function *fun)
{
- struct loop *loop;
+ class loop *loop;
bool changed = false;
basic_block bb;
control_dependences *cd = NULL;
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index e703cd9..1527456 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1343,6 +1343,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_AUTO:
@@ -2073,6 +2074,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_AUTO:
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 713b0b0..eb35ebf 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -129,8 +129,9 @@ ssa_is_replaceable_p (gimple *stmt)
rarely more than 6, and in the bootstrap of gcc, the maximum number
of nodes encountered was 12. */
-struct elim_graph
+class elim_graph
{
+public:
elim_graph (var_map map);
/* Size of the elimination vectors. */
@@ -171,14 +172,43 @@ struct elim_graph
use its location. Otherwise search instructions in predecessors
of E for a location, and use that one. That makes sense because
we insert on edges for PHI nodes, and effects of PHIs happen on
- the end of the predecessor conceptually. */
+ the end of the predecessor conceptually. An exception is made
+ for EH edges because we don't want to drag the source location
+ of unrelated statements at the beginning of handlers; they would
+ be further reused for various EH constructs, which would damage
+ the coverage information. */
static void
set_location_for_edge (edge e)
{
if (e->goto_locus)
+ set_curr_insn_location (e->goto_locus);
+ else if (e->flags & EDGE_EH)
{
- set_curr_insn_location (e->goto_locus);
+ basic_block bb = e->dest;
+ gimple_stmt_iterator gsi;
+
+ do
+ {
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ if (is_gimple_debug (stmt))
+ continue;
+ if (gimple_has_location (stmt) || gimple_block (stmt))
+ {
+ set_curr_insn_location (gimple_location (stmt));
+ return;
+ }
+ }
+ /* Nothing found in this basic block. Make a half-assed attempt
+ to continue with another block. */
+ if (single_succ_p (bb))
+ bb = single_succ (bb);
+ else
+ bb = e->dest;
+ }
+ while (bb != e->dest);
}
else
{
@@ -564,7 +594,11 @@ eliminate_build (elim_graph *g)
continue;
Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
- locus = gimple_phi_arg_location_from_edge (phi, g->e);
+ /* See set_location_for_edge for the rationale. */
+ if (g->e->flags & EDGE_EH)
+ locus = UNKNOWN_LOCATION;
+ else
+ locus = gimple_phi_arg_location_from_edge (phi, g->e);
/* If this argument is a constant, or a SSA_NAME which is being
left in SSA form, just queue a copy to be emitted on this
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 6b8c8cd..f5cb411 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -412,7 +412,7 @@ lambda_transform_legal_p (lambda_trans_matrix trans,
in parallel). */
static bool
-loop_parallel_p (struct loop *loop, struct obstack * parloop_obstack)
+loop_parallel_p (class loop *loop, struct obstack * parloop_obstack)
{
vec<ddr_p> dependence_relations;
vec<data_reference_p> datarefs;
@@ -468,7 +468,7 @@ loop_parallel_p (struct loop *loop, struct obstack * parloop_obstack)
BB_IRREDUCIBLE_LOOP flag. */
static inline bool
-loop_has_blocks_with_irreducible_flag (struct loop *loop)
+loop_has_blocks_with_irreducible_flag (class loop *loop)
{
unsigned i;
basic_block *bbs = get_loop_body_in_dom_order (loop);
@@ -572,7 +572,7 @@ reduc_stmt_res (gimple *stmt)
the loop described in DATA. */
int
-initialize_reductions (reduction_info **slot, struct loop *loop)
+initialize_reductions (reduction_info **slot, class loop *loop)
{
tree init;
tree type, arg;
@@ -1034,7 +1034,7 @@ add_field_for_name (name_to_copy_elt **slot, tree type)
reduction's data structure. */
int
-create_phi_for_local_result (reduction_info **slot, struct loop *loop)
+create_phi_for_local_result (reduction_info **slot, class loop *loop)
{
struct reduction_info *const reduc = *slot;
edge e;
@@ -1158,11 +1158,11 @@ create_call_for_reduction_1 (reduction_info **slot, struct clsn_data *clsn_data)
LD_ST_DATA describes the shared data structure where
shared data is stored in and loaded from. */
static void
-create_call_for_reduction (struct loop *loop,
+create_call_for_reduction (class loop *loop,
reduction_info_table_type *reduction_list,
struct clsn_data *ld_st_data)
{
- reduction_list->traverse <struct loop *, create_phi_for_local_result> (loop);
+ reduction_list->traverse <class loop *, create_phi_for_local_result> (loop);
/* Find the fallthru edge from GIMPLE_OMP_CONTINUE. */
basic_block continue_bb = single_pred (loop->latch);
ld_st_data->load_bb = FALLTHRU_EDGE (continue_bb)->dest;
@@ -1640,7 +1640,7 @@ replace_uses_in_bb_by (tree name, tree val, basic_block bb)
bound. */
static void
-transform_to_exit_first_loop_alt (struct loop *loop,
+transform_to_exit_first_loop_alt (class loop *loop,
reduction_info_table_type *reduction_list,
tree bound)
{
@@ -1797,7 +1797,7 @@ transform_to_exit_first_loop_alt (struct loop *loop,
transformation is successful. */
static bool
-try_transform_to_exit_first_loop_alt (struct loop *loop,
+try_transform_to_exit_first_loop_alt (class loop *loop,
reduction_info_table_type *reduction_list,
tree nit)
{
@@ -1916,7 +1916,7 @@ try_transform_to_exit_first_loop_alt (struct loop *loop,
LOOP. */
static void
-transform_to_exit_first_loop (struct loop *loop,
+transform_to_exit_first_loop (class loop *loop,
reduction_info_table_type *reduction_list,
tree nit)
{
@@ -2030,7 +2030,7 @@ transform_to_exit_first_loop (struct loop *loop,
that number is to be determined later. */
static void
-create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
+create_parallel_loop (class loop *loop, tree loop_fn, tree data,
tree new_data, unsigned n_threads, location_t loc,
bool oacc_kernels_p)
{
@@ -2266,9 +2266,9 @@ num_phis (basic_block bb, bool count_virtual_p)
REDUCTION_LIST describes the reductions existent in the LOOP. */
static void
-gen_parallel_loop (struct loop *loop,
+gen_parallel_loop (class loop *loop,
reduction_info_table_type *reduction_list,
- unsigned n_threads, struct tree_niter_desc *niter,
+ unsigned n_threads, class tree_niter_desc *niter,
bool oacc_kernels_p)
{
tree many_iterations_cond, type, nit;
@@ -2441,7 +2441,7 @@ gen_parallel_loop (struct loop *loop,
/* Generate initializations for reductions. */
if (!reduction_list->is_empty ())
- reduction_list->traverse <struct loop *, initialize_reductions> (loop);
+ reduction_list->traverse <class loop *, initialize_reductions> (loop);
/* Eliminate the references to local variables from the loop. */
gcc_assert (single_exit (loop));
@@ -2489,7 +2489,7 @@ gen_parallel_loop (struct loop *loop,
/* Returns true when LOOP contains vector phi nodes. */
static bool
-loop_has_vector_phi_nodes (struct loop *loop ATTRIBUTE_UNUSED)
+loop_has_vector_phi_nodes (class loop *loop ATTRIBUTE_UNUSED)
{
unsigned i;
basic_block *bbs = get_loop_body_in_dom_order (loop);
@@ -2695,7 +2695,7 @@ gather_scalar_reductions (loop_p loop, reduction_info_table_type *reduction_list
/* Try to initialize NITER for code generation part. */
static bool
-try_get_loop_niter (loop_p loop, struct tree_niter_desc *niter)
+try_get_loop_niter (loop_p loop, class tree_niter_desc *niter)
{
edge exit = single_dom_exit (loop);
@@ -2737,7 +2737,7 @@ get_omp_data_i_param (void)
and return addr. Otherwise, return NULL_TREE. */
static tree
-find_reduc_addr (struct loop *loop, gphi *phi)
+find_reduc_addr (class loop *loop, gphi *phi)
{
edge e = loop_preheader_edge (loop);
tree arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
@@ -2907,7 +2907,7 @@ try_create_reduction_list (loop_p loop,
/* Return true if LOOP contains phis with ADDR_EXPR in args. */
static bool
-loop_has_phi_with_address_arg (struct loop *loop)
+loop_has_phi_with_address_arg (class loop *loop)
{
basic_block *bbs = get_loop_body (loop);
bool res = false;
@@ -3244,7 +3244,7 @@ oacc_entry_exit_single_gang (bitmap in_loop_bbs, vec<basic_block> region_bbs,
outside LOOP by guarding them such that only a single gang executes them. */
static bool
-oacc_entry_exit_ok (struct loop *loop,
+oacc_entry_exit_ok (class loop *loop,
reduction_info_table_type *reduction_list)
{
basic_block *loop_bbs = get_loop_body_in_dom_order (loop);
@@ -3289,9 +3289,9 @@ parallelize_loops (bool oacc_kernels_p)
{
unsigned n_threads;
bool changed = false;
- struct loop *loop;
- struct loop *skip_loop = NULL;
- struct tree_niter_desc niter_desc;
+ class loop *loop;
+ class loop *skip_loop = NULL;
+ class tree_niter_desc niter_desc;
struct obstack parloop_obstack;
HOST_WIDE_INT estimated;
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 3a0b380..1c8df3d 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -132,7 +132,7 @@ protected:
}
};
-class varpool_node;
+struct varpool_node;
struct cgraph_node;
struct lto_symtab_encoder_d;
@@ -552,6 +552,7 @@ extern rtl_opt_pass *make_pass_rtl_unroll_loops (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_rtl_doloop (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_rtl_loop_done (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_lower_subreg2 (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_web (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_cse2 (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_df_initialize_opt (gcc::context *ctxt);
@@ -567,7 +568,7 @@ extern rtl_opt_pass *make_pass_partition_blocks (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_match_asm_constraints (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_split_all_insns (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_fast_rtl_byte_dce (gcc::context *ctxt);
-extern rtl_opt_pass *make_pass_lower_subreg2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_lower_subreg3 (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_mode_switching (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_sms (gcc::context *ctxt);
extern rtl_opt_pass *make_pass_sched (gcc::context *ctxt);
@@ -632,7 +633,7 @@ extern bool execute_one_pass (opt_pass *);
extern void execute_pass_list (function *, opt_pass *);
extern void execute_ipa_pass_list (opt_pass *);
extern void execute_ipa_summary_passes (ipa_opt_pass_d *);
-extern void execute_all_ipa_transforms (void);
+extern void execute_all_ipa_transforms (bool);
extern void execute_all_ipa_stmt_fixups (struct cgraph_node *, gimple **);
extern bool pass_init_dump_file (opt_pass *);
extern void pass_fini_dump_file (opt_pass *);
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 8e83a71..299c45e 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -243,8 +243,9 @@ along with GCC; see the file COPYING3. If not see
/* Data references (or phi nodes that carry data reference values across
loop iterations). */
-typedef struct dref_d
+typedef class dref_d
{
+public:
/* The reference itself. */
struct data_reference *ref;
@@ -734,7 +735,7 @@ determine_offset (struct data_reference *a, struct data_reference *b,
it is executed whenever the loop is entered. */
static basic_block
-last_always_executed_block (struct loop *loop)
+last_always_executed_block (class loop *loop)
{
unsigned i;
vec<edge> exits = get_loop_exit_edges (loop);
@@ -751,7 +752,7 @@ last_always_executed_block (struct loop *loop)
/* Splits dependence graph on DATAREFS described by DEPENDS to components. */
static struct component *
-split_data_refs_to_components (struct loop *loop,
+split_data_refs_to_components (class loop *loop,
vec<data_reference_p> datarefs,
vec<ddr_p> depends)
{
@@ -895,7 +896,7 @@ split_data_refs_to_components (struct loop *loop,
comps[ca] = comp;
}
- dataref = XCNEW (struct dref_d);
+ dataref = XCNEW (class dref_d);
dataref->ref = dr;
dataref->stmt = DR_STMT (dr);
dataref->offset = 0;
@@ -930,7 +931,7 @@ end:
loop. */
static bool
-suitable_component_p (struct loop *loop, struct component *comp)
+suitable_component_p (class loop *loop, struct component *comp)
{
unsigned i;
dref a, first;
@@ -986,7 +987,7 @@ suitable_component_p (struct loop *loop, struct component *comp)
the beginning of this file. LOOP is the current loop. */
static struct component *
-filter_suitable_components (struct loop *loop, struct component *comps)
+filter_suitable_components (class loop *loop, struct component *comps)
{
struct component **comp, *act;
@@ -1231,7 +1232,7 @@ valid_initializer_p (struct data_reference *ref,
is the root of the current chain. */
static gphi *
-find_looparound_phi (struct loop *loop, dref ref, dref root)
+find_looparound_phi (class loop *loop, dref ref, dref root)
{
tree name, init, init_ref;
gphi *phi = NULL;
@@ -1295,7 +1296,7 @@ find_looparound_phi (struct loop *loop, dref ref, dref root)
static void
insert_looparound_copy (chain_p chain, dref ref, gphi *phi)
{
- dref nw = XCNEW (struct dref_d), aref;
+ dref nw = XCNEW (class dref_d), aref;
unsigned i;
nw->stmt = phi;
@@ -1320,7 +1321,7 @@ insert_looparound_copy (chain_p chain, dref ref, gphi *phi)
(also, it may allow us to combine chains together). */
static void
-add_looparound_copies (struct loop *loop, chain_p chain)
+add_looparound_copies (class loop *loop, chain_p chain)
{
unsigned i;
dref ref, root = get_chain_root (chain);
@@ -1345,7 +1346,7 @@ add_looparound_copies (struct loop *loop, chain_p chain)
loop. */
static void
-determine_roots_comp (struct loop *loop,
+determine_roots_comp (class loop *loop,
struct component *comp,
vec<chain_p> *chains)
{
@@ -1435,7 +1436,7 @@ determine_roots_comp (struct loop *loop,
separates the references to CHAINS. LOOP is the current loop. */
static void
-determine_roots (struct loop *loop,
+determine_roots (class loop *loop,
struct component *comps, vec<chain_p> *chains)
{
struct component *comp;
@@ -1652,7 +1653,7 @@ predcom_tmp_var (tree ref, unsigned i, bitmap tmp_vars)
temporary variables are marked in TMP_VARS. */
static void
-initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
+initialize_root_vars (class loop *loop, chain_p chain, bitmap tmp_vars)
{
unsigned i;
unsigned n = chain->length;
@@ -1706,7 +1707,7 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
In this case, we can use these invariant values directly after LOOP. */
static bool
-is_inv_store_elimination_chain (struct loop *loop, chain_p chain)
+is_inv_store_elimination_chain (class loop *loop, chain_p chain)
{
if (chain->length == 0 || chain->type != CT_STORE_STORE)
return false;
@@ -1800,7 +1801,7 @@ initialize_root_vars_store_elim_1 (chain_p chain)
of the newly created root variables are marked in TMP_VARS. */
static void
-initialize_root_vars_store_elim_2 (struct loop *loop,
+initialize_root_vars_store_elim_2 (class loop *loop,
chain_p chain, bitmap tmp_vars)
{
unsigned i, n = chain->length;
@@ -1885,7 +1886,7 @@ initialize_root_vars_store_elim_2 (struct loop *loop,
(CHAIN->length - 1) iterations. */
static void
-finalize_eliminated_stores (struct loop *loop, chain_p chain)
+finalize_eliminated_stores (class loop *loop, chain_p chain)
{
unsigned i, n = chain->length;
@@ -1913,7 +1914,7 @@ finalize_eliminated_stores (struct loop *loop, chain_p chain)
initializer. */
static void
-initialize_root_vars_lm (struct loop *loop, dref root, bool written,
+initialize_root_vars_lm (class loop *loop, dref root, bool written,
vec<tree> *vars, vec<tree> inits,
bitmap tmp_vars)
{
@@ -1961,7 +1962,7 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written,
created temporary variables are marked in TMP_VARS. */
static void
-execute_load_motion (struct loop *loop, chain_p chain, bitmap tmp_vars)
+execute_load_motion (class loop *loop, chain_p chain, bitmap tmp_vars)
{
auto_vec<tree> vars;
dref a;
@@ -2102,7 +2103,7 @@ remove_stmt (gimple *stmt)
Uids of the newly created temporary variables are marked in TMP_VARS.*/
static void
-execute_pred_commoning_chain (struct loop *loop, chain_p chain,
+execute_pred_commoning_chain (class loop *loop, chain_p chain,
bitmap tmp_vars)
{
unsigned i;
@@ -2233,7 +2234,7 @@ determine_unroll_factor (vec<chain_p> chains)
Uids of the newly created temporary variables are marked in TMP_VARS. */
static void
-execute_pred_commoning (struct loop *loop, vec<chain_p> chains,
+execute_pred_commoning (class loop *loop, vec<chain_p> chains,
bitmap tmp_vars)
{
chain_p chain;
@@ -2316,7 +2317,7 @@ struct epcc_data
};
static void
-execute_pred_commoning_cbck (struct loop *loop, void *data)
+execute_pred_commoning_cbck (class loop *loop, void *data)
{
struct epcc_data *const dta = (struct epcc_data *) data;
@@ -2332,7 +2333,7 @@ execute_pred_commoning_cbck (struct loop *loop, void *data)
the header of the LOOP. */
static void
-base_names_in_chain_on (struct loop *loop, tree name, tree var)
+base_names_in_chain_on (class loop *loop, tree name, tree var)
{
gimple *stmt, *phi;
imm_use_iterator iter;
@@ -2365,7 +2366,7 @@ base_names_in_chain_on (struct loop *loop, tree name, tree var)
for those we want to perform this. */
static void
-eliminate_temp_copies (struct loop *loop, bitmap tmp_vars)
+eliminate_temp_copies (class loop *loop, bitmap tmp_vars)
{
edge e;
gphi *phi;
@@ -2750,7 +2751,7 @@ combine_chains (chain_p ch1, chain_p ch2)
for (i = 0; (ch1->refs.iterate (i, &r1)
&& ch2->refs.iterate (i, &r2)); i++)
{
- nw = XCNEW (struct dref_d);
+ nw = XCNEW (class dref_d);
nw->stmt = stmt_combining_refs (r1, r2);
nw->distance = r1->distance;
@@ -2800,7 +2801,7 @@ pcom_stmt_dominates_stmt_p (gimple *s1, gimple *s2)
/* Try to combine the CHAINS in LOOP. */
static void
-try_combine_chains (struct loop *loop, vec<chain_p> *chains)
+try_combine_chains (class loop *loop, vec<chain_p> *chains)
{
unsigned i, j;
chain_p ch1, ch2, cch;
@@ -2910,7 +2911,7 @@ try_combine_chains (struct loop *loop, vec<chain_p> *chains)
otherwise. */
static bool
-prepare_initializers_chain_store_elim (struct loop *loop, chain_p chain)
+prepare_initializers_chain_store_elim (class loop *loop, chain_p chain)
{
unsigned i, n = chain->length;
@@ -2977,7 +2978,7 @@ prepare_initializers_chain_store_elim (struct loop *loop, chain_p chain)
impossible because one of these initializers may trap, true otherwise. */
static bool
-prepare_initializers_chain (struct loop *loop, chain_p chain)
+prepare_initializers_chain (class loop *loop, chain_p chain)
{
unsigned i, n = (chain->type == CT_INVARIANT) ? 1 : chain->length;
struct data_reference *dr = get_chain_root (chain)->ref;
@@ -3033,7 +3034,7 @@ prepare_initializers_chain (struct loop *loop, chain_p chain)
be used because the initializers might trap. */
static void
-prepare_initializers (struct loop *loop, vec<chain_p> chains)
+prepare_initializers (class loop *loop, vec<chain_p> chains)
{
chain_p chain;
unsigned i;
@@ -3055,7 +3056,7 @@ prepare_initializers (struct loop *loop, vec<chain_p> chains)
if finalizer code for CHAIN can be generated, otherwise false. */
static bool
-prepare_finalizers_chain (struct loop *loop, chain_p chain)
+prepare_finalizers_chain (class loop *loop, chain_p chain)
{
unsigned i, n = chain->length;
struct data_reference *dr = get_chain_root (chain)->ref;
@@ -3103,7 +3104,7 @@ prepare_finalizers_chain (struct loop *loop, chain_p chain)
if finalizer code generation for CHAINS breaks loop closed ssa form. */
static bool
-prepare_finalizers (struct loop *loop, vec<chain_p> chains)
+prepare_finalizers (class loop *loop, vec<chain_p> chains)
{
chain_p chain;
unsigned i;
@@ -3142,7 +3143,7 @@ prepare_finalizers (struct loop *loop, vec<chain_p> chains)
/* Insert all initializing gimple stmts into loop's entry edge. */
static void
-insert_init_seqs (struct loop *loop, vec<chain_p> chains)
+insert_init_seqs (class loop *loop, vec<chain_p> chains)
{
unsigned i;
edge entry = loop_preheader_edge (loop);
@@ -3160,14 +3161,14 @@ insert_init_seqs (struct loop *loop, vec<chain_p> chains)
form was corrupted. */
static unsigned
-tree_predictive_commoning_loop (struct loop *loop)
+tree_predictive_commoning_loop (class loop *loop)
{
vec<data_reference_p> datarefs;
vec<ddr_p> dependences;
struct component *components;
vec<chain_p> chains = vNULL;
unsigned unroll_factor;
- struct tree_niter_desc desc;
+ class tree_niter_desc desc;
bool unroll = false, loop_closed_ssa = false;
edge exit;
@@ -3303,7 +3304,7 @@ end: ;
unsigned
tree_predictive_commoning (void)
{
- struct loop *loop;
+ class loop *loop;
unsigned ret = 0, changed = 0;
initialize_original_copy_tables ();
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index dacda7b..9bea132 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1040,6 +1040,29 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
pp_right_paren (pp);
break;
+ case OMP_CLAUSE_ORDER:
+ pp_string (pp, "order(concurrent)");
+ break;
+
+ case OMP_CLAUSE_BIND:
+ pp_string (pp, "bind(");
+ switch (OMP_CLAUSE_BIND_KIND (clause))
+ {
+ case OMP_CLAUSE_BIND_TEAMS:
+ pp_string (pp, "teams");
+ break;
+ case OMP_CLAUSE_BIND_PARALLEL:
+ pp_string (pp, "parallel");
+ break;
+ case OMP_CLAUSE_BIND_THREAD:
+ pp_string (pp, "thread");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ pp_right_paren (pp);
+ break;
+
case OMP_CLAUSE__SIMDUID_:
pp_string (pp, "_simduid_(");
dump_generic_node (pp, OMP_CLAUSE__SIMDUID__DECL (clause),
@@ -2815,12 +2838,34 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
newline_and_indent (pp, spc+2);
pp_right_brace (pp);
newline_and_indent (pp, spc);
- pp_string (pp,
- (TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
+ if (TREE_CODE (node) == TRY_CATCH_EXPR)
+ {
+ node = TREE_OPERAND (node, 1);
+ pp_string (pp, "catch");
+ }
+ else
+ {
+ gcc_assert (TREE_CODE (node) == TRY_FINALLY_EXPR);
+ node = TREE_OPERAND (node, 1);
+ pp_string (pp, "finally");
+ if (TREE_CODE (node) == EH_ELSE_EXPR)
+ {
+ newline_and_indent (pp, spc+2);
+ pp_left_brace (pp);
+ newline_and_indent (pp, spc+4);
+ dump_generic_node (pp, TREE_OPERAND (node, 0), spc+4,
+ flags, true);
+ newline_and_indent (pp, spc+2);
+ pp_right_brace (pp);
+ newline_and_indent (pp, spc);
+ node = TREE_OPERAND (node, 1);
+ pp_string (pp, "else");
+ }
+ }
newline_and_indent (pp, spc+2);
pp_left_brace (pp);
newline_and_indent (pp, spc+4);
- dump_generic_node (pp, TREE_OPERAND (node, 1), spc+4, flags, true);
+ dump_generic_node (pp, node, spc+4, flags, true);
newline_and_indent (pp, spc+2);
pp_right_brace (pp);
is_expr = false;
@@ -3235,6 +3280,10 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
pp_string (pp, "#pragma omp taskloop");
goto dump_omp_loop;
+ case OMP_LOOP:
+ pp_string (pp, "#pragma omp loop");
+ goto dump_omp_loop;
+
case OACC_LOOP:
pp_string (pp, "#pragma acc loop");
goto dump_omp_loop;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 81f70f1..4b72a25 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -286,8 +286,8 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "case-cfn-macros.h"
-static tree analyze_scalar_evolution_1 (struct loop *, tree);
-static tree analyze_scalar_evolution_for_address_of (struct loop *loop,
+static tree analyze_scalar_evolution_1 (class loop *, tree);
+static tree analyze_scalar_evolution_for_address_of (class loop *loop,
tree var);
/* The cached information about an SSA name with version NAME_VERSION,
@@ -370,8 +370,9 @@ find_var_scev_info (basic_block instantiated_below, tree var)
analyzing a scalar evolution, instantiating a CHREC or
resolving mixers. */
-struct instantiate_cache_type
+class instantiate_cache_type
{
+public:
htab_t map;
vec<scev_info_str> entries;
@@ -444,7 +445,7 @@ loop_phi_node_p (gimple *phi)
*/
tree
-compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
+compute_overall_effect_of_inner_loop (class loop *loop, tree evolution_fn)
{
bool val = false;
@@ -453,7 +454,7 @@ compute_overall_effect_of_inner_loop (struct loop *loop, tree evolution_fn)
else if (TREE_CODE (evolution_fn) == POLYNOMIAL_CHREC)
{
- struct loop *inner_loop = get_chrec_loop (evolution_fn);
+ class loop *inner_loop = get_chrec_loop (evolution_fn);
if (inner_loop == loop
|| flow_loop_nested_p (loop, inner_loop))
@@ -592,7 +593,7 @@ add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add,
gimple *at_stmt)
{
tree type, left, right;
- struct loop *loop = get_loop (cfun, loop_nb), *chloop;
+ class loop *loop = get_loop (cfun, loop_nb), *chloop;
switch (TREE_CODE (chrec_before))
{
@@ -839,7 +840,7 @@ add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code,
analyze, then give up. */
gcond *
-get_loop_exit_condition (const struct loop *loop)
+get_loop_exit_condition (const class loop *loop)
{
gcond *res = NULL;
edge exit_edge = single_exit (loop);
@@ -875,14 +876,14 @@ enum t_bool {
};
-static t_bool follow_ssa_edge (struct loop *loop, gimple *, gphi *,
+static t_bool follow_ssa_edge (class loop *loop, gimple *, gphi *,
tree *, int);
/* Follow the ssa edge into the binary expression RHS0 CODE RHS1.
Return true if the strongly connected component has been found. */
static t_bool
-follow_ssa_edge_binary (struct loop *loop, gimple *at_stmt,
+follow_ssa_edge_binary (class loop *loop, gimple *at_stmt,
tree type, tree rhs0, enum tree_code code, tree rhs1,
gphi *halting_phi, tree *evolution_of_loop,
int limit)
@@ -1017,7 +1018,7 @@ follow_ssa_edge_binary (struct loop *loop, gimple *at_stmt,
Return true if the strongly connected component has been found. */
static t_bool
-follow_ssa_edge_expr (struct loop *loop, gimple *at_stmt, tree expr,
+follow_ssa_edge_expr (class loop *loop, gimple *at_stmt, tree expr,
gphi *halting_phi, tree *evolution_of_loop,
int limit)
{
@@ -1108,7 +1109,7 @@ follow_ssa_edge_expr (struct loop *loop, gimple *at_stmt, tree expr,
Return true if the strongly connected component has been found. */
static t_bool
-follow_ssa_edge_in_rhs (struct loop *loop, gimple *stmt,
+follow_ssa_edge_in_rhs (class loop *loop, gimple *stmt,
gphi *halting_phi, tree *evolution_of_loop,
int limit)
{
@@ -1169,7 +1170,7 @@ backedge_phi_arg_p (gphi *phi, int i)
static inline t_bool
follow_ssa_edge_in_condition_phi_branch (int i,
- struct loop *loop,
+ class loop *loop,
gphi *condition_phi,
gphi *halting_phi,
tree *evolution_of_branch,
@@ -1204,7 +1205,7 @@ follow_ssa_edge_in_condition_phi_branch (int i,
loop. */
static t_bool
-follow_ssa_edge_in_condition_phi (struct loop *loop,
+follow_ssa_edge_in_condition_phi (class loop *loop,
gphi *condition_phi,
gphi *halting_phi,
tree *evolution_of_loop, int limit)
@@ -1251,12 +1252,12 @@ follow_ssa_edge_in_condition_phi (struct loop *loop,
considered as a single statement. */
static t_bool
-follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
+follow_ssa_edge_inner_loop_phi (class loop *outer_loop,
gphi *loop_phi_node,
gphi *halting_phi,
tree *evolution_of_loop, int limit)
{
- struct loop *loop = loop_containing_stmt (loop_phi_node);
+ class loop *loop = loop_containing_stmt (loop_phi_node);
tree ev = analyze_scalar_evolution (loop, PHI_RESULT (loop_phi_node));
/* Sometimes, the inner loop is too difficult to analyze, and the
@@ -1298,10 +1299,10 @@ follow_ssa_edge_inner_loop_phi (struct loop *outer_loop,
path that is analyzed on the return walk. */
static t_bool
-follow_ssa_edge (struct loop *loop, gimple *def, gphi *halting_phi,
+follow_ssa_edge (class loop *loop, gimple *def, gphi *halting_phi,
tree *evolution_of_loop, int limit)
{
- struct loop *def_loop;
+ class loop *def_loop;
if (gimple_nop_p (def))
return t_false;
@@ -1373,7 +1374,7 @@ follow_ssa_edge (struct loop *loop, gimple *def, gphi *halting_phi,
See PR41488. */
static tree
-simplify_peeled_chrec (struct loop *loop, tree arg, tree init_cond)
+simplify_peeled_chrec (class loop *loop, tree arg, tree init_cond)
{
aff_tree aff1, aff2;
tree ev, left, right, type, step_val;
@@ -1431,7 +1432,7 @@ analyze_evolution_in_loop (gphi *loop_phi_node,
{
int i, n = gimple_phi_num_args (loop_phi_node);
tree evolution_function = chrec_not_analyzed_yet;
- struct loop *loop = loop_containing_stmt (loop_phi_node);
+ class loop *loop = loop_containing_stmt (loop_phi_node);
basic_block bb;
static bool simplify_peeled_chrec_p = true;
@@ -1559,7 +1560,7 @@ analyze_initial_condition (gphi *loop_phi_node)
{
int i, n;
tree init_cond = chrec_not_analyzed_yet;
- struct loop *loop = loop_containing_stmt (loop_phi_node);
+ class loop *loop = loop_containing_stmt (loop_phi_node);
if (dump_file && (dump_flags & TDF_SCEV))
{
@@ -1616,10 +1617,10 @@ analyze_initial_condition (gphi *loop_phi_node)
/* Analyze the scalar evolution for LOOP_PHI_NODE. */
static tree
-interpret_loop_phi (struct loop *loop, gphi *loop_phi_node)
+interpret_loop_phi (class loop *loop, gphi *loop_phi_node)
{
tree res;
- struct loop *phi_loop = loop_containing_stmt (loop_phi_node);
+ class loop *phi_loop = loop_containing_stmt (loop_phi_node);
tree init_cond;
gcc_assert (phi_loop == loop);
@@ -1653,7 +1654,7 @@ interpret_loop_phi (struct loop *loop, gphi *loop_phi_node)
analyzed. */
static tree
-interpret_condition_phi (struct loop *loop, gphi *condition_phi)
+interpret_condition_phi (class loop *loop, gphi *condition_phi)
{
int i, n = gimple_phi_num_args (condition_phi);
tree res = chrec_not_analyzed_yet;
@@ -1687,7 +1688,7 @@ interpret_condition_phi (struct loop *loop, gphi *condition_phi)
analyze the effect of an inner loop: see interpret_loop_phi. */
static tree
-interpret_rhs_expr (struct loop *loop, gimple *at_stmt,
+interpret_rhs_expr (class loop *loop, gimple *at_stmt,
tree type, tree rhs1, enum tree_code code, tree rhs2)
{
tree res, chrec1, chrec2, ctype;
@@ -1957,7 +1958,7 @@ interpret_rhs_expr (struct loop *loop, gimple *at_stmt,
/* Interpret the expression EXPR. */
static tree
-interpret_expr (struct loop *loop, gimple *at_stmt, tree expr)
+interpret_expr (class loop *loop, gimple *at_stmt, tree expr)
{
enum tree_code code;
tree type = TREE_TYPE (expr), op0, op1;
@@ -1979,7 +1980,7 @@ interpret_expr (struct loop *loop, gimple *at_stmt, tree expr)
/* Interpret the rhs of the assignment STMT. */
static tree
-interpret_gimple_assign (struct loop *loop, gimple *stmt)
+interpret_gimple_assign (class loop *loop, gimple *stmt)
{
tree type = TREE_TYPE (gimple_assign_lhs (stmt));
enum tree_code code = gimple_assign_rhs_code (stmt);
@@ -2000,11 +2001,11 @@ interpret_gimple_assign (struct loop *loop, gimple *stmt)
/* Helper recursive function. */
static tree
-analyze_scalar_evolution_1 (struct loop *loop, tree var)
+analyze_scalar_evolution_1 (class loop *loop, tree var)
{
gimple *def;
basic_block bb;
- struct loop *def_loop;
+ class loop *def_loop;
tree res;
if (TREE_CODE (var) != SSA_NAME)
@@ -2024,7 +2025,7 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var)
if (loop != def_loop)
{
res = analyze_scalar_evolution_1 (def_loop, var);
- struct loop *loop_to_skip = superloop_at_depth (def_loop,
+ class loop *loop_to_skip = superloop_at_depth (def_loop,
loop_depth (loop) + 1);
res = compute_overall_effect_of_inner_loop (loop_to_skip, res);
if (chrec_contains_symbols_defined_in_loop (res, loop->num))
@@ -2076,7 +2077,7 @@ analyze_scalar_evolution_1 (struct loop *loop, tree var)
*/
tree
-analyze_scalar_evolution (struct loop *loop, tree var)
+analyze_scalar_evolution (class loop *loop, tree var)
{
tree res;
@@ -2121,7 +2122,7 @@ analyze_scalar_evolution (struct loop *loop, tree var)
/* Analyzes and returns the scalar evolution of VAR address in LOOP. */
static tree
-analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
+analyze_scalar_evolution_for_address_of (class loop *loop, tree var)
{
return analyze_scalar_evolution (loop, build_fold_addr_expr (var));
}
@@ -2177,7 +2178,7 @@ analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
*/
static tree
-analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop,
+analyze_scalar_evolution_in_loop (class loop *wrto_loop, class loop *use_loop,
tree version, bool *folded_casts)
{
bool val = false;
@@ -2277,7 +2278,7 @@ get_instantiated_value_entry (instantiate_cache_type &cache,
static tree
loop_closed_phi_def (tree var)
{
- struct loop *loop;
+ class loop *loop;
edge exit;
gphi *phi;
gphi_iterator psi;
@@ -2301,7 +2302,7 @@ loop_closed_phi_def (tree var)
return NULL_TREE;
}
-static tree instantiate_scev_r (edge, struct loop *, struct loop *,
+static tree instantiate_scev_r (edge, class loop *, class loop *,
tree, bool *, int);
/* Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
@@ -2321,13 +2322,13 @@ static tree instantiate_scev_r (edge, struct loop *, struct loop *,
static tree
instantiate_scev_name (edge instantiate_below,
- struct loop *evolution_loop, struct loop *inner_loop,
+ class loop *evolution_loop, class loop *inner_loop,
tree chrec,
bool *fold_conversions,
int size_expr)
{
tree res;
- struct loop *def_loop;
+ class loop *def_loop;
basic_block def_bb = gimple_bb (SSA_NAME_DEF_STMT (chrec));
/* A parameter, nothing to do. */
@@ -2471,7 +2472,7 @@ instantiate_scev_name (edge instantiate_below,
static tree
instantiate_scev_poly (edge instantiate_below,
- struct loop *evolution_loop, struct loop *,
+ class loop *evolution_loop, class loop *,
tree chrec, bool *fold_conversions, int size_expr)
{
tree op1;
@@ -2516,7 +2517,7 @@ instantiate_scev_poly (edge instantiate_below,
static tree
instantiate_scev_binary (edge instantiate_below,
- struct loop *evolution_loop, struct loop *inner_loop,
+ class loop *evolution_loop, class loop *inner_loop,
tree chrec, enum tree_code code,
tree type, tree c0, tree c1,
bool *fold_conversions, int size_expr)
@@ -2584,7 +2585,7 @@ instantiate_scev_binary (edge instantiate_below,
static tree
instantiate_scev_convert (edge instantiate_below,
- struct loop *evolution_loop, struct loop *inner_loop,
+ class loop *evolution_loop, class loop *inner_loop,
tree chrec, tree type, tree op,
bool *fold_conversions, int size_expr)
{
@@ -2635,7 +2636,7 @@ instantiate_scev_convert (edge instantiate_below,
static tree
instantiate_scev_not (edge instantiate_below,
- struct loop *evolution_loop, struct loop *inner_loop,
+ class loop *evolution_loop, class loop *inner_loop,
tree chrec,
enum tree_code code, tree type, tree op,
bool *fold_conversions, int size_expr)
@@ -2686,7 +2687,7 @@ instantiate_scev_not (edge instantiate_below,
static tree
instantiate_scev_r (edge instantiate_below,
- struct loop *evolution_loop, struct loop *inner_loop,
+ class loop *evolution_loop, class loop *inner_loop,
tree chrec,
bool *fold_conversions, int size_expr)
{
@@ -2760,7 +2761,7 @@ instantiate_scev_r (edge instantiate_below,
a function parameter. */
tree
-instantiate_scev (edge instantiate_below, struct loop *evolution_loop,
+instantiate_scev (edge instantiate_below, class loop *evolution_loop,
tree chrec)
{
tree res;
@@ -2809,7 +2810,7 @@ instantiate_scev (edge instantiate_below, struct loop *evolution_loop,
of an expression. */
tree
-resolve_mixers (struct loop *loop, tree chrec, bool *folded_casts)
+resolve_mixers (class loop *loop, tree chrec, bool *folded_casts)
{
bool destr = false;
bool fold_conversions = false;
@@ -2858,10 +2859,10 @@ resolve_mixers (struct loop *loop, tree chrec, bool *folded_casts)
the loop body has been executed 6 times. */
tree
-number_of_latch_executions (struct loop *loop)
+number_of_latch_executions (class loop *loop)
{
edge exit;
- struct tree_niter_desc niter_desc;
+ class tree_niter_desc niter_desc;
tree may_be_zero;
tree res;
@@ -3046,7 +3047,7 @@ gather_stats_on_scev_database (void)
void
scev_initialize (void)
{
- struct loop *loop;
+ class loop *loop;
gcc_assert (! scev_initialized_p ());
@@ -3084,7 +3085,7 @@ scev_reset_htab (void)
void
scev_reset (void)
{
- struct loop *loop;
+ class loop *loop;
scev_reset_htab ();
@@ -3103,7 +3104,7 @@ scev_reset (void)
hypotetical IVs to be inserted into code. */
bool
-iv_can_overflow_p (struct loop *loop, tree type, tree base, tree step)
+iv_can_overflow_p (class loop *loop, tree type, tree base, tree step)
{
widest_int nit;
wide_int base_min, base_max, step_min, step_max, type_min, type_max;
@@ -3266,7 +3267,7 @@ derive_simple_iv_with_niters (tree ev, tree *niters)
infinite. */
bool
-simple_iv_with_niters (struct loop *wrto_loop, struct loop *use_loop,
+simple_iv_with_niters (class loop *wrto_loop, class loop *use_loop,
tree op, affine_iv *iv, tree *iv_niters,
bool allow_nonconstant_step)
{
@@ -3406,7 +3407,7 @@ simple_iv_with_niters (struct loop *wrto_loop, struct loop *use_loop,
affine iv unconditionally. */
bool
-simple_iv (struct loop *wrto_loop, struct loop *use_loop, tree op,
+simple_iv (class loop *wrto_loop, class loop *use_loop, tree op,
affine_iv *iv, bool allow_nonconstant_step)
{
return simple_iv_with_niters (wrto_loop, use_loop, op, iv,
@@ -3564,7 +3565,7 @@ expression_expensive_p (tree expr)
/* Do final value replacement for LOOP, return true if we did anything. */
bool
-final_value_replacement_loop (struct loop *loop)
+final_value_replacement_loop (class loop *loop)
{
/* If we do not know exact number of iterations of the loop, we cannot
replace the final value. */
@@ -3583,7 +3584,7 @@ final_value_replacement_loop (struct loop *loop)
/* Set stmt insertion pointer. All stmts are inserted before this point. */
gimple_stmt_iterator gsi = gsi_after_labels (exit->dest);
- struct loop *ex_loop
+ class loop *ex_loop
= superloop_at_depth (loop,
loop_depth (exit->dest->loop_father) + 1);
@@ -3680,6 +3681,8 @@ final_value_replacement_loop (struct loop *loop)
true, GSI_SAME_STMT);
gassign *ass = gimple_build_assign (rslt, def);
+ gimple_set_location (ass,
+ gimple_phi_arg_location (phi, exit->dest_idx));
gsi_insert_before (&gsi, ass, GSI_SAME_STMT);
if (dump_file)
{
diff --git a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h
index 621a57c..d4d6ec5 100644
--- a/gcc/tree-scalar-evolution.h
+++ b/gcc/tree-scalar-evolution.h
@@ -21,27 +21,27 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_SCALAR_EVOLUTION_H
#define GCC_TREE_SCALAR_EVOLUTION_H
-extern tree number_of_latch_executions (struct loop *);
-extern gcond *get_loop_exit_condition (const struct loop *);
+extern tree number_of_latch_executions (class loop *);
+extern gcond *get_loop_exit_condition (const class loop *);
extern void scev_initialize (void);
extern bool scev_initialized_p (void);
extern void scev_reset (void);
extern void scev_reset_htab (void);
extern void scev_finalize (void);
-extern tree analyze_scalar_evolution (struct loop *, tree);
-extern tree instantiate_scev (edge, struct loop *, tree);
-extern tree resolve_mixers (struct loop *, tree, bool *);
+extern tree analyze_scalar_evolution (class loop *, tree);
+extern tree instantiate_scev (edge, class loop *, tree);
+extern tree resolve_mixers (class loop *, tree, bool *);
extern void gather_stats_on_scev_database (void);
-extern bool final_value_replacement_loop (struct loop *);
+extern bool final_value_replacement_loop (class loop *);
extern unsigned int scev_const_prop (void);
extern bool expression_expensive_p (tree);
-extern bool simple_iv_with_niters (struct loop *, struct loop *, tree,
+extern bool simple_iv_with_niters (class loop *, class loop *, tree,
struct affine_iv *, tree *, bool);
-extern bool simple_iv (struct loop *, struct loop *, tree, struct affine_iv *,
+extern bool simple_iv (class loop *, class loop *, tree, struct affine_iv *,
bool);
-extern bool iv_can_overflow_p (struct loop *, tree, tree, tree);
-extern tree compute_overall_effect_of_inner_loop (struct loop *, tree);
+extern bool iv_can_overflow_p (class loop *, tree, tree, tree);
+extern tree compute_overall_effect_of_inner_loop (class loop *, tree);
/* Returns the basic block preceding LOOP, or the CFG entry block when
the loop is function's body. */
@@ -58,14 +58,14 @@ block_before_loop (loop_p loop)
be analyzed and instantiated. */
static inline tree
-instantiate_parameters (struct loop *loop, tree chrec)
+instantiate_parameters (class loop *loop, tree chrec)
{
return instantiate_scev (loop_preheader_edge (loop), loop, chrec);
}
/* Returns the loop of the polynomial chrec CHREC. */
-static inline struct loop *
+static inline class loop *
get_chrec_loop (const_tree chrec)
{
return get_loop (cfun, CHREC_VARIABLE (chrec));
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index e83e1b9..8004951 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -259,6 +259,20 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
? expand_expr (addr->index, NULL_RTX, pointer_mode, EXPAND_NORMAL)
: NULL_RTX);
+ /* addr->base could be an SSA_NAME that was set to a constant value. The
+ call to expand_expr may expose that constant. If so, fold the value
+ into OFF and clear BSE. Otherwise we may later try to pull a mode from
+ BSE to generate a REG, which won't work with constants because they
+ are modeless. */
+ if (bse && GET_CODE (bse) == CONST_INT)
+ {
+ if (off)
+ off = simplify_gen_binary (PLUS, pointer_mode, bse, off);
+ else
+ off = bse;
+ gcc_assert (GET_CODE (off) == CONST_INT);
+ bse = NULL_RTX;
+ }
gen_addr_rtx (pointer_mode, sym, bse, idx, st, off, &address, NULL, NULL);
if (pointer_mode != address_mode)
address = convert_memory_address (address_mode, address);
diff --git a/gcc/tree-ssa-address.h b/gcc/tree-ssa-address.h
index 9812f36..05a2321 100644
--- a/gcc/tree-ssa-address.h
+++ b/gcc/tree-ssa-address.h
@@ -33,9 +33,9 @@ extern void get_address_description (tree, struct mem_address *);
extern tree tree_mem_ref_addr (tree, tree);
extern bool valid_mem_ref_p (machine_mode, addr_space_t, struct mem_address *);
extern void move_fixed_address_to_symbol (struct mem_address *,
- struct aff_tree *);
+ class aff_tree *);
tree create_mem_ref (gimple_stmt_iterator *, tree,
- struct aff_tree *, tree, tree, tree, bool);
+ class aff_tree *, tree, tree, tree, bool);
extern void copy_ref_info (tree, tree);
tree maybe_fold_tmr (tree);
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index c3c127a..dd2a43e 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -105,6 +105,7 @@ static struct {
unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_may_alias;
unsigned HOST_WIDE_INT nonoverlapping_component_refs_p_no_alias;
unsigned HOST_WIDE_INT nonoverlapping_component_refs_since_match_p_may_alias;
+ unsigned HOST_WIDE_INT nonoverlapping_component_refs_since_match_p_must_overlap;
unsigned HOST_WIDE_INT nonoverlapping_component_refs_since_match_p_no_alias;
} alias_stats;
@@ -138,10 +139,13 @@ dump_alias_stats (FILE *s)
+ alias_stats.nonoverlapping_component_refs_p_may_alias);
fprintf (s, " nonoverlapping_component_refs_since_match_p: "
HOST_WIDE_INT_PRINT_DEC" disambiguations, "
+ HOST_WIDE_INT_PRINT_DEC" must overlaps, "
HOST_WIDE_INT_PRINT_DEC" queries\n",
alias_stats.nonoverlapping_component_refs_since_match_p_no_alias,
+ alias_stats.nonoverlapping_component_refs_since_match_p_must_overlap,
alias_stats.nonoverlapping_component_refs_since_match_p_no_alias
- + alias_stats.nonoverlapping_component_refs_since_match_p_may_alias);
+ + alias_stats.nonoverlapping_component_refs_since_match_p_may_alias
+ + alias_stats.nonoverlapping_component_refs_since_match_p_must_overlap);
fprintf (s, " aliasing_component_refs_p: "
HOST_WIDE_INT_PRINT_DEC" disambiguations, "
HOST_WIDE_INT_PRINT_DEC" queries\n",
@@ -891,6 +895,97 @@ aliasing_matching_component_refs_p (tree match1, tree ref1,
return true;
}
+/* Return true if REF is reference to zero sized trailing array. I.e.
+ struct foo {int bar; int array[0];} *fooptr;
+ fooptr->array. */
+
+static bool
+component_ref_to_zero_sized_trailing_array_p (tree ref)
+{
+ return (TREE_CODE (ref) == COMPONENT_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 1))) == ARRAY_TYPE
+ && (!TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)))
+ || integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (ref, 1)))))
+ && array_at_struct_end_p (ref));
+}
+
+/* Worker for aliasing_component_refs_p. Most parameters match parameters of
+ aliasing_component_refs_p.
+
+ Walk access path REF2 and try to find type matching TYPE1
+ (which is a start of possibly aliasing access path REF1).
+ If match is found, try to disambiguate.
+
+ Return 0 for sucessful disambiguation.
+ Return 1 if match was found but disambiguation failed
+ Return -1 if there is no match.
+ In this case MAYBE_MATCH is set to 0 if there is no type matching TYPE1
+ in access patch REF2 and -1 if we are not sure. */
+
+static int
+aliasing_component_refs_walk (tree ref1, tree type1, tree base1,
+ poly_int64 offset1, poly_int64 max_size1,
+ tree end_struct_ref1,
+ tree ref2, tree base2,
+ poly_int64 offset2, poly_int64 max_size2,
+ bool *maybe_match)
+{
+ tree ref = ref2;
+ int same_p = 0;
+
+ while (true)
+ {
+ /* We walk from inner type to the outer types. If type we see is
+ already too large to be part of type1, terminate the search. */
+ int cmp = compare_type_sizes (type1, TREE_TYPE (ref));
+
+ if (cmp < 0
+ && (!end_struct_ref1
+ || compare_type_sizes (TREE_TYPE (end_struct_ref1),
+ TREE_TYPE (ref)) < 0))
+ break;
+ /* If types may be of same size, see if we can decide about their
+ equality. */
+ if (cmp == 0)
+ {
+ same_p = same_type_for_tbaa (TREE_TYPE (ref), type1);
+ if (same_p == 1)
+ break;
+ /* In case we can't decide whether types are same try to
+ continue looking for the exact match.
+ Remember however that we possibly saw a match
+ to bypass the access path continuations tests we do later. */
+ if (same_p == -1)
+ *maybe_match = true;
+ }
+ if (!handled_component_p (ref))
+ break;
+ ref = TREE_OPERAND (ref, 0);
+ }
+ if (same_p == 1)
+ {
+ /* We assume that arrays can overlap by multiple of their elements
+ size as tested in gcc.dg/torture/alias-2.c.
+ This partial overlap happen only when both arrays are bases of
+ the access and not contained within another component ref.
+ To be safe we also assume partial overlap for VLAs. */
+ if (TREE_CODE (TREE_TYPE (base1)) == ARRAY_TYPE
+ && (!TYPE_SIZE (TREE_TYPE (base1))
+ || TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) != INTEGER_CST
+ || ref == base2))
+ /* Setting maybe_match to true triggers
+ nonoverlapping_component_refs_p test later that still may do
+ useful disambiguation. */
+ *maybe_match = true;
+ else
+ return aliasing_matching_component_refs_p (base1, ref1,
+ offset1, max_size1,
+ ref, ref2,
+ offset2, max_size2);
+ }
+ return -1;
+}
+
/* Determine if the two component references REF1 and REF2 which are
based on access types TYPE1 and TYPE2 and of which at least one is based
on an indirect reference may alias.
@@ -915,7 +1010,6 @@ aliasing_component_refs_p (tree ref1,
disambiguating q->i and p->a.j. */
tree base1, base2;
tree type1, type2;
- int same_p1 = 0, same_p2 = 0;
bool maybe_match = false;
tree end_struct_ref1 = NULL, end_struct_ref2 = NULL;
@@ -934,11 +1028,7 @@ aliasing_component_refs_p (tree ref1,
Because we compare sizes of arrays just by sizes of their elements,
we only need to care about zero sized array fields here. */
- if (TREE_CODE (base1) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (base1, 1))) == ARRAY_TYPE
- && (!TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base1, 1)))
- || integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base1, 1)))))
- && array_at_struct_end_p (base1))
+ if (component_ref_to_zero_sized_trailing_array_p (base1))
{
gcc_checking_assert (!end_struct_ref1);
end_struct_ref1 = base1;
@@ -952,11 +1042,7 @@ aliasing_component_refs_p (tree ref1,
base2 = ref2;
while (handled_component_p (base2))
{
- if (TREE_CODE (base2) == COMPONENT_REF
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (base2, 1))) == ARRAY_TYPE
- && (!TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base2, 1)))
- || integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_OPERAND (base2, 1)))))
- && array_at_struct_end_p (base2))
+ if (component_ref_to_zero_sized_trailing_array_p (base2))
{
gcc_checking_assert (!end_struct_ref2);
end_struct_ref2 = base2;
@@ -980,57 +1066,13 @@ aliasing_component_refs_p (tree ref1,
|| (end_struct_ref2
&& compare_type_sizes (TREE_TYPE (end_struct_ref2), type1) >= 0))
{
- tree ref = ref2;
- while (true)
- {
- /* We walk from inner type to the outer types. If type we see is
- already too large to be part of type1, terminate the search. */
- int cmp = compare_type_sizes (type1, TREE_TYPE (ref));
-
- if (cmp < 0
- && (!end_struct_ref1
- || compare_type_sizes (TREE_TYPE (end_struct_ref1),
- TREE_TYPE (ref)) < 0))
- break;
- /* If types may be of same size, see if we can decide about their
- equality. */
- if (cmp == 0)
- {
- same_p2 = same_type_for_tbaa (TREE_TYPE (ref), type1);
- if (same_p2 == 1)
- break;
- /* In case we can't decide whether types are same try to
- continue looking for the exact match.
- Remember however that we possibly saw a match
- to bypass the access path continuations tests we do later. */
- if (same_p2 == -1)
- maybe_match = true;
- }
- if (!handled_component_p (ref))
- break;
- ref = TREE_OPERAND (ref, 0);
- }
- if (same_p2 == 1)
- {
- /* We assume that arrays can overlap by multiple of their elements
- size as tested in gcc.dg/torture/alias-2.c.
- This partial overlap happen only when both arrays are bases of
- the access and not contained within another component ref.
- To be safe we also assume partial overlap for VLAs. */
- if (TREE_CODE (TREE_TYPE (base1)) == ARRAY_TYPE
- && (!TYPE_SIZE (TREE_TYPE (base1))
- || TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) != INTEGER_CST
- || ref == base2))
- /* Setting maybe_match to true triggers
- nonoverlapping_component_refs_p test later that still may do
- useful disambiguation. */
- maybe_match = true;
- else
- return aliasing_matching_component_refs_p (base1, ref1,
- offset1, max_size1,
- ref, ref2,
- offset2, max_size2);
- }
+ int res = aliasing_component_refs_walk (ref1, type1, base1,
+ offset1, max_size1,
+ end_struct_ref1,
+ ref2, base2, offset2, max_size2,
+ &maybe_match);
+ if (res != -1)
+ return res;
}
/* If we didn't find a common base, try the other way around. */
@@ -1038,42 +1080,13 @@ aliasing_component_refs_p (tree ref1,
|| (end_struct_ref1
&& compare_type_sizes (TREE_TYPE (end_struct_ref1), type1) <= 0))
{
- tree ref = ref1;
- while (true)
- {
- int cmp = compare_type_sizes (type2, TREE_TYPE (ref));
- if (cmp < 0
- && (!end_struct_ref2
- || compare_type_sizes (TREE_TYPE (end_struct_ref2),
- TREE_TYPE (ref)) < 0))
- break;
- /* If types may be of same size, see if we can decide about their
- equality. */
- if (cmp == 0)
- {
- same_p1 = same_type_for_tbaa (TREE_TYPE (ref), type2);
- if (same_p1 == 1)
- break;
- if (same_p1 == -1)
- maybe_match = true;
- }
- if (!handled_component_p (ref))
- break;
- ref = TREE_OPERAND (ref, 0);
- }
- if (same_p1 == 1)
- {
- if (TREE_CODE (TREE_TYPE (base2)) == ARRAY_TYPE
- && (!TYPE_SIZE (TREE_TYPE (base2))
- || TREE_CODE (TYPE_SIZE (TREE_TYPE (base2))) != INTEGER_CST
- || ref == base1))
- maybe_match = true;
- else
- return aliasing_matching_component_refs_p (ref, ref1,
- offset1, max_size1,
- base2, ref2,
- offset2, max_size2);
- }
+ int res = aliasing_component_refs_walk (ref2, type2, base2,
+ offset2, max_size2,
+ end_struct_ref2,
+ ref1, base1, offset1, max_size1,
+ &maybe_match);
+ if (res != -1)
+ return res;
}
/* In the following code we make an assumption that the types in access
@@ -1124,6 +1137,94 @@ aliasing_component_refs_p (tree ref1,
return false;
}
+/* FIELD1 and FIELD2 are two fields of component refs. We assume
+ that bases of both component refs are either equivalent or nonoverlapping.
+ We do not assume that the containers of FIELD1 and FIELD2 are of the
+ same type or size.
+
+ Return 0 in case the base address of component_refs are same then
+ FIELD1 and FIELD2 have same address. Note that FIELD1 and FIELD2
+ may not be of same type or size.
+
+ Return 1 if FIELD1 and FIELD2 are non-overlapping.
+
+ Return -1 otherwise.
+
+ Main difference between 0 and -1 is to let
+ nonoverlapping_component_refs_since_match_p discover the semantically
+ equivalent part of the access path.
+
+ Note that this function is used even with -fno-strict-aliasing
+ and makes use of no TBAA assumptions. */
+
+static int
+nonoverlapping_component_refs_p_1 (const_tree field1, const_tree field2)
+{
+ /* If both fields are of the same type, we could save hard work of
+ comparing offsets. */
+ tree type1 = DECL_CONTEXT (field1);
+ tree type2 = DECL_CONTEXT (field2);
+
+ if (TREE_CODE (type1) == RECORD_TYPE
+ && DECL_BIT_FIELD_REPRESENTATIVE (field1))
+ field1 = DECL_BIT_FIELD_REPRESENTATIVE (field1);
+ if (TREE_CODE (type2) == RECORD_TYPE
+ && DECL_BIT_FIELD_REPRESENTATIVE (field2))
+ field2 = DECL_BIT_FIELD_REPRESENTATIVE (field2);
+
+ /* ??? Bitfields can overlap at RTL level so punt on them.
+ FIXME: RTL expansion should be fixed by adjusting the access path
+ when producing MEM_ATTRs for MEMs which are wider than
+ the bitfields similarly as done in set_mem_attrs_minus_bitpos. */
+ if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2))
+ return -1;
+
+ /* Assume that different FIELD_DECLs never overlap within a RECORD_TYPE. */
+ if (type1 == type2 && TREE_CODE (type1) == RECORD_TYPE)
+ return field1 != field2;
+
+ /* In common case the offsets and bit offsets will be the same.
+ However if frontends do not agree on the alignment, they may be
+ different even if they actually represent same address.
+ Try the common case first and if that fails calcualte the
+ actual bit offset. */
+ if (tree_int_cst_equal (DECL_FIELD_OFFSET (field1),
+ DECL_FIELD_OFFSET (field2))
+ && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (field1),
+ DECL_FIELD_BIT_OFFSET (field2)))
+ return 0;
+
+ /* Note that it may be possible to use component_ref_field_offset
+ which would provide offsets as trees. However constructing and folding
+ trees is expensive and does not seem to be worth the compile time
+ cost. */
+
+ poly_uint64 offset1, offset2;
+ poly_uint64 bit_offset1, bit_offset2;
+
+ if (poly_int_tree_p (DECL_FIELD_OFFSET (field1), &offset1)
+ && poly_int_tree_p (DECL_FIELD_OFFSET (field2), &offset2)
+ && poly_int_tree_p (DECL_FIELD_BIT_OFFSET (field1), &bit_offset1)
+ && poly_int_tree_p (DECL_FIELD_BIT_OFFSET (field2), &bit_offset2))
+ {
+ offset1 = (offset1 << LOG2_BITS_PER_UNIT) + bit_offset1;
+ offset2 = (offset2 << LOG2_BITS_PER_UNIT) + bit_offset2;
+
+ if (known_eq (offset1, offset2))
+ return 0;
+
+ poly_uint64 size1, size2;
+
+ if (poly_int_tree_p (DECL_SIZE (field1), &size1)
+ && poly_int_tree_p (DECL_SIZE (field2), &size2)
+ && !ranges_maybe_overlap_p (offset1, size1, offset2, size2))
+ return 1;
+ }
+ /* Resort to slower overlap checking by looking for matching types in
+ the middle of access path. */
+ return -1;
+}
+
/* Try to disambiguate REF1 and REF2 under the assumption that MATCH1 and
MATCH2 either point to the same address or are disjoint.
MATCH1 and MATCH2 are assumed to be ref in the access path of REF1 and REF2
@@ -1149,62 +1250,66 @@ static int
nonoverlapping_component_refs_since_match_p (tree match1, tree ref1,
tree match2, tree ref2)
{
+ /* Early return if there are no references to match, we do not need
+ to walk the access paths.
+
+ Do not consider this as may-alias for stats - it is more useful
+ to have information how many disambiguations happened provided that
+ the query was meaningful. */
+
+ if (match1 == ref1 || !handled_component_p (ref1)
+ || match2 == ref2 || !handled_component_p (ref2))
+ return -1;
+
auto_vec<tree, 16> component_refs1;
auto_vec<tree, 16> component_refs2;
/* Create the stack of handled components for REF1. */
- while (handled_component_p (ref1))
+ while (handled_component_p (ref1) && ref1 != match1)
{
if (TREE_CODE (ref1) == VIEW_CONVERT_EXPR
|| TREE_CODE (ref1) == BIT_FIELD_REF)
component_refs1.truncate (0);
else
component_refs1.safe_push (ref1);
- if (ref1 == match1)
- break;
ref1 = TREE_OPERAND (ref1, 0);
}
- if (TREE_CODE (ref1) == MEM_REF && ref1 != match1)
- {
- if (!integer_zerop (TREE_OPERAND (ref1, 1)))
- {
- ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias;
- return -1;
- }
- }
- /* TODO: Handle TARGET_MEM_REF later. */
- if (TREE_CODE (ref1) == TARGET_MEM_REF && ref1 != match1)
- {
- ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias;
- return -1;
- }
/* Create the stack of handled components for REF2. */
- while (handled_component_p (ref2))
+ while (handled_component_p (ref2) && ref2 != match2)
{
if (TREE_CODE (ref2) == VIEW_CONVERT_EXPR
|| TREE_CODE (ref2) == BIT_FIELD_REF)
component_refs2.truncate (0);
else
component_refs2.safe_push (ref2);
- if (ref2 == match2)
- break;
ref2 = TREE_OPERAND (ref2, 0);
}
- if (TREE_CODE (ref2) == MEM_REF && ref2 != match2)
- {
- if (!integer_zerop (TREE_OPERAND (ref2, 1)))
- {
- ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias;
- return -1;
- }
- }
- if (TREE_CODE (ref2) == TARGET_MEM_REF && ref2 != match2)
+
+ bool mem_ref1 = TREE_CODE (ref1) == MEM_REF && ref1 != match1;
+ bool mem_ref2 = TREE_CODE (ref2) == MEM_REF && ref2 != match2;
+
+ /* If only one of access path starts with MEM_REF check that offset is 0
+ so the addresses stays the same after stripping it.
+ TODO: In this case we may walk the other access path until we get same
+ offset.
+
+ If both starts with MEM_REF, offset has to be same. */
+ if ((mem_ref1 && !mem_ref2 && !integer_zerop (TREE_OPERAND (ref1, 1)))
+ || (mem_ref2 && !mem_ref1 && !integer_zerop (TREE_OPERAND (ref2, 1)))
+ || (mem_ref1 && mem_ref2
+ && !tree_int_cst_equal (TREE_OPERAND (ref1, 1),
+ TREE_OPERAND (ref2, 1))))
{
++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias;
return -1;
}
+ /* TARGET_MEM_REF are never wrapped in handled components, so we do not need
+ to handle them here at all. */
+ gcc_checking_assert (TREE_CODE (ref1) != TARGET_MEM_REF
+ && TREE_CODE (ref2) != TARGET_MEM_REF);
+
/* Pop the stacks in parallel and examine the COMPONENT_REFs of the same
rank. This is sufficient because we start from the same DECL and you
cannot reference several fields at a time with COMPONENT_REFs (unlike
@@ -1213,15 +1318,18 @@ nonoverlapping_component_refs_since_match_p (tree match1, tree ref1,
case the return value will precisely be false. */
while (true)
{
+ bool seen_noncomponent_ref_p = false;
do
{
if (component_refs1.is_empty ())
{
++alias_stats
- .nonoverlapping_component_refs_since_match_p_may_alias;
+ .nonoverlapping_component_refs_since_match_p_must_overlap;
return 0;
}
ref1 = component_refs1.pop ();
+ if (TREE_CODE (ref1) != COMPONENT_REF)
+ seen_noncomponent_ref_p = true;
}
while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref1, 0))));
@@ -1230,21 +1338,19 @@ nonoverlapping_component_refs_since_match_p (tree match1, tree ref1,
if (component_refs2.is_empty ())
{
++alias_stats
- .nonoverlapping_component_refs_since_match_p_may_alias;
+ .nonoverlapping_component_refs_since_match_p_must_overlap;
return 0;
}
ref2 = component_refs2.pop ();
+ if (TREE_CODE (ref2) != COMPONENT_REF)
+ seen_noncomponent_ref_p = true;
}
while (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (TREE_OPERAND (ref2, 0))));
- /* Beware of BIT_FIELD_REF. */
- if (TREE_CODE (ref1) != COMPONENT_REF
- || TREE_CODE (ref2) != COMPONENT_REF)
- {
- ++alias_stats
- .nonoverlapping_component_refs_since_match_p_may_alias;
- return -1;
- }
+ /* BIT_FIELD_REF and VIEW_CONVERT_EXPR are taken off the vectors
+ earlier. */
+ gcc_checking_assert (TREE_CODE (ref1) == COMPONENT_REF
+ && TREE_CODE (ref2) == COMPONENT_REF);
tree field1 = TREE_OPERAND (ref1, 1);
tree field2 = TREE_OPERAND (ref2, 1);
@@ -1255,41 +1361,53 @@ nonoverlapping_component_refs_since_match_p (tree match1, tree ref1,
tree type1 = DECL_CONTEXT (field1);
tree type2 = DECL_CONTEXT (field2);
- /* We cannot disambiguate fields in a union or qualified union. */
- if (type1 != type2 || TREE_CODE (type1) != RECORD_TYPE)
+ /* If we skipped array refs on type of different sizes, we can
+ no longer be sure that there are not partial overlaps. */
+ if (seen_noncomponent_ref_p
+ && !operand_equal_p (TYPE_SIZE (type1), TYPE_SIZE (type2), 0))
{
- ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias;
+ ++alias_stats
+ .nonoverlapping_component_refs_since_match_p_may_alias;
return -1;
}
- if (field1 != field2)
+ int cmp = nonoverlapping_component_refs_p_1 (field1, field2);
+ if (cmp == -1)
{
- /* A field and its representative need to be considered the
- same. */
- if (DECL_BIT_FIELD_REPRESENTATIVE (field1) == field2
- || DECL_BIT_FIELD_REPRESENTATIVE (field2) == field1)
- {
- ++alias_stats
- .nonoverlapping_component_refs_since_match_p_may_alias;
- return 0;
- }
- /* Different fields of the same record type cannot overlap.
- ??? Bitfields can overlap at RTL level so punt on them. */
- if (DECL_BIT_FIELD (field1) && DECL_BIT_FIELD (field2))
- {
- ++alias_stats
- .nonoverlapping_component_refs_since_match_p_may_alias;
- return 0;
- }
- ++alias_stats.nonoverlapping_component_refs_since_match_p_no_alias;
+ ++alias_stats
+ .nonoverlapping_component_refs_since_match_p_may_alias;
+ return -1;
+ }
+ else if (cmp == 1)
+ {
+ ++alias_stats
+ .nonoverlapping_component_refs_since_match_p_no_alias;
return 1;
}
}
- ++alias_stats.nonoverlapping_component_refs_since_match_p_may_alias;
+ ++alias_stats.nonoverlapping_component_refs_since_match_p_must_overlap;
return 0;
}
+/* Return TYPE_UID which can be used to match record types we consider
+ same for TBAA purposes. */
+
+static inline int
+ncr_type_uid (const_tree field)
+{
+ /* ??? We cannot simply use the type of operand #0 of the refs here
+ as the Fortran compiler smuggles type punning into COMPONENT_REFs
+ for common blocks instead of using unions like everyone else. */
+ tree type = DECL_FIELD_CONTEXT (field);
+ /* With LTO types considered same_type_for_tbaa_p
+ from different translation unit may not have same
+ main variant. They however have same TYPE_CANONICAL. */
+ if (TYPE_CANONICAL (type))
+ return TYPE_UID (TYPE_CANONICAL (type));
+ return TYPE_UID (type);
+}
+
/* qsort compare function to sort FIELD_DECLs after their
DECL_FIELD_CONTEXT TYPE_UID. */
@@ -1298,8 +1416,9 @@ ncr_compar (const void *field1_, const void *field2_)
{
const_tree field1 = *(const_tree *) const_cast <void *>(field1_);
const_tree field2 = *(const_tree *) const_cast <void *>(field2_);
- unsigned int uid1 = TYPE_UID (DECL_FIELD_CONTEXT (field1));
- unsigned int uid2 = TYPE_UID (DECL_FIELD_CONTEXT (field2));
+ unsigned int uid1 = ncr_type_uid (field1);
+ unsigned int uid2 = ncr_type_uid (field2);
+
if (uid1 < uid2)
return -1;
else if (uid1 > uid2)
@@ -1313,14 +1432,16 @@ ncr_compar (const void *field1_, const void *field2_)
static bool
nonoverlapping_component_refs_p (const_tree x, const_tree y)
{
+ /* Early return if we have nothing to do.
+
+ Do not consider this as may-alias for stats - it is more useful
+ to have information how many disambiguations happened provided that
+ the query was meaningful. */
if (!flag_strict_aliasing
|| !x || !y
|| !handled_component_p (x)
|| !handled_component_p (y))
- {
- ++alias_stats.nonoverlapping_component_refs_p_may_alias;
- return false;
- }
+ return false;
auto_vec<const_tree, 16> fieldsx;
while (handled_component_p (x))
@@ -1364,10 +1485,9 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y)
if (fieldsx.length () == 1
&& fieldsy.length () == 1)
{
- if ((DECL_FIELD_CONTEXT (fieldsx[0])
- == DECL_FIELD_CONTEXT (fieldsy[0]))
- && fieldsx[0] != fieldsy[0]
- && !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0])))
+ if (same_type_for_tbaa (DECL_FIELD_CONTEXT (fieldsx[0]),
+ DECL_FIELD_CONTEXT (fieldsy[0])) == 1
+ && nonoverlapping_component_refs_p_1 (fieldsx[0], fieldsy[0]) == 1)
{
++alias_stats.nonoverlapping_component_refs_p_no_alias;
return true;
@@ -1400,31 +1520,18 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y)
{
const_tree fieldx = fieldsx[i];
const_tree fieldy = fieldsy[j];
- tree typex = DECL_FIELD_CONTEXT (fieldx);
- tree typey = DECL_FIELD_CONTEXT (fieldy);
- if (typex == typey)
+
+ /* We're left with accessing different fields of a structure,
+ no possible overlap. */
+ if (same_type_for_tbaa (DECL_FIELD_CONTEXT (fieldx),
+ DECL_FIELD_CONTEXT (fieldy)) == 1
+ && nonoverlapping_component_refs_p_1 (fieldx, fieldy) == 1)
{
- /* We're left with accessing different fields of a structure,
- no possible overlap. */
- if (fieldx != fieldy)
- {
- /* A field and its representative need to be considered the
- same. */
- if (DECL_BIT_FIELD_REPRESENTATIVE (fieldx) == fieldy
- || DECL_BIT_FIELD_REPRESENTATIVE (fieldy) == fieldx)
- ;
- /* Different fields of the same record type cannot overlap.
- ??? Bitfields can overlap at RTL level so punt on them. */
- else if (DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy))
- ;
- else
- {
- ++alias_stats.nonoverlapping_component_refs_p_no_alias;
- return true;
- }
- }
+ ++alias_stats.nonoverlapping_component_refs_p_no_alias;
+ return true;
}
- if (TYPE_UID (typex) < TYPE_UID (typey))
+
+ if (ncr_type_uid (fieldx) < ncr_type_uid (fieldy))
{
i++;
if (i == fieldsx.length ())
@@ -1452,8 +1559,10 @@ nonoverlapping_component_refs_p (const_tree x, const_tree y)
static bool
decl_refs_may_alias_p (tree ref1, tree base1,
poly_int64 offset1, poly_int64 max_size1,
+ poly_int64 size1,
tree ref2, tree base2,
- poly_int64 offset2, poly_int64 max_size2)
+ poly_int64 offset2, poly_int64 max_size2,
+ poly_int64 size2)
{
gcc_checking_assert (DECL_P (base1) && DECL_P (base2));
@@ -1466,6 +1575,10 @@ decl_refs_may_alias_p (tree ref1, tree base1,
if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
return false;
+ /* If there is must alias, there is no use disambiguating further. */
+ if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
+ return true;
+
/* For components with variable position, the above test isn't sufficient,
so we disambiguate component references manually. */
if (ref1 && ref2
@@ -1487,10 +1600,12 @@ decl_refs_may_alias_p (tree ref1, tree base1,
static bool
indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
poly_int64 offset1, poly_int64 max_size1,
+ poly_int64 size1,
alias_set_type ref1_alias_set,
alias_set_type base1_alias_set,
tree ref2 ATTRIBUTE_UNUSED, tree base2,
poly_int64 offset2, poly_int64 max_size2,
+ poly_int64 size2,
alias_set_type ref2_alias_set,
alias_set_type base2_alias_set, bool tbaa_p)
{
@@ -1598,7 +1713,19 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
&& (TREE_CODE (TREE_TYPE (base1)) != ARRAY_TYPE
|| (TYPE_SIZE (TREE_TYPE (base1))
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (base1))) == INTEGER_CST)))
- return ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2);
+ {
+ if (!ranges_maybe_overlap_p (doffset1, max_size1, doffset2, max_size2))
+ return false;
+ if (!ref1 || !ref2
+ /* If there is must alias, there is no use disambiguating further. */
+ || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
+ return true;
+ int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
+ base2, ref2);
+ if (res == -1)
+ return !nonoverlapping_component_refs_p (ref1, ref2);
+ return !res;
+ }
/* Do access-path based disambiguation. */
if (ref1 && ref2
@@ -1623,10 +1750,12 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
static bool
indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
poly_int64 offset1, poly_int64 max_size1,
+ poly_int64 size1,
alias_set_type ref1_alias_set,
alias_set_type base1_alias_set,
tree ref2 ATTRIBUTE_UNUSED, tree base2,
poly_int64 offset2, poly_int64 max_size2,
+ poly_int64 size2,
alias_set_type ref2_alias_set,
alias_set_type base2_alias_set, bool tbaa_p)
{
@@ -1671,6 +1800,9 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
if (!ranges_maybe_overlap_p (offset1 + moff1, max_size1,
offset2 + moff2, max_size2))
return false;
+ /* If there is must alias, there is no use disambiguating further. */
+ if (known_eq (size1, max_size1) && known_eq (size2, max_size2))
+ return true;
if (ref1 && ref2)
{
int res = nonoverlapping_component_refs_since_match_p (NULL, ref1,
@@ -1717,7 +1849,18 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
can overlap by an exact multiple of their element size.
See gcc.dg/torture/alias-2.c. */
&& TREE_CODE (TREE_TYPE (ptrtype1)) != ARRAY_TYPE)
- return ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2);
+ {
+ if (!ranges_maybe_overlap_p (offset1, max_size1, offset2, max_size2))
+ return false;
+ if (!ref1 || !ref2
+ || (known_eq (size1, max_size1) && known_eq (size2, max_size2)))
+ return true;
+ int res = nonoverlapping_component_refs_since_match_p (base1, ref1,
+ base2, ref2);
+ if (res == -1)
+ return !nonoverlapping_component_refs_p (ref1, ref2);
+ return !res;
+ }
/* Do access-path based disambiguation. */
if (ref1 && ref2
@@ -1802,7 +1945,9 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
var2_p = DECL_P (base2);
if (var1_p && var2_p)
return decl_refs_may_alias_p (ref1->ref, base1, offset1, max_size1,
- ref2->ref, base2, offset2, max_size2);
+ ref1->size,
+ ref2->ref, base2, offset2, max_size2,
+ ref2->size);
/* Handle restrict based accesses.
??? ao_ref_base strips inner MEM_REF [&decl], recover from that
@@ -1870,21 +2015,21 @@ refs_may_alias_p_2 (ao_ref *ref1, ao_ref *ref2, bool tbaa_p)
/* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators. */
if (var1_p && ind2_p)
return indirect_ref_may_alias_decl_p (ref2->ref, base2,
- offset2, max_size2,
+ offset2, max_size2, ref2->size,
ao_ref_alias_set (ref2),
ao_ref_base_alias_set (ref2),
ref1->ref, base1,
- offset1, max_size1,
+ offset1, max_size1, ref1->size,
ao_ref_alias_set (ref1),
ao_ref_base_alias_set (ref1),
tbaa_p);
else if (ind1_p && ind2_p)
return indirect_refs_may_alias_p (ref1->ref, base1,
- offset1, max_size1,
+ offset1, max_size1, ref1->size,
ao_ref_alias_set (ref1),
ao_ref_base_alias_set (ref1),
ref2->ref, base2,
- offset2, max_size2,
+ offset2, max_size2, ref2->size,
ao_ref_alias_set (ref2),
ao_ref_base_alias_set (ref2),
tbaa_p);
@@ -3003,8 +3148,8 @@ stmt_kills_ref_p (gimple *stmt, tree ref)
static bool
maybe_skip_until (gimple *phi, tree &target, basic_block target_bb,
- ao_ref *ref, tree vuse, unsigned int &limit, bitmap *visited,
- bool abort_on_visited,
+ ao_ref *ref, tree vuse, bool tbaa_p, unsigned int &limit,
+ bitmap *visited, bool abort_on_visited,
void *(*translate)(ao_ref *, tree, void *, bool *),
void *data)
{
@@ -3038,7 +3183,7 @@ maybe_skip_until (gimple *phi, tree &target, basic_block target_bb,
/* An already visited PHI node ends the walk successfully. */
if (bitmap_bit_p (*visited, SSA_NAME_VERSION (PHI_RESULT (def_stmt))))
return !abort_on_visited;
- vuse = get_continuation_for_phi (def_stmt, ref, limit,
+ vuse = get_continuation_for_phi (def_stmt, ref, tbaa_p, limit,
visited, abort_on_visited,
translate, data);
if (!vuse)
@@ -3053,7 +3198,7 @@ maybe_skip_until (gimple *phi, tree &target, basic_block target_bb,
if ((int)limit <= 0)
return false;
--limit;
- if (stmt_may_clobber_ref_p_1 (def_stmt, ref))
+ if (stmt_may_clobber_ref_p_1 (def_stmt, ref, tbaa_p))
{
bool disambiguate_only = true;
if (translate
@@ -3085,7 +3230,7 @@ maybe_skip_until (gimple *phi, tree &target, basic_block target_bb,
Returns NULL_TREE if no suitable virtual operand can be found. */
tree
-get_continuation_for_phi (gimple *phi, ao_ref *ref,
+get_continuation_for_phi (gimple *phi, ao_ref *ref, bool tbaa_p,
unsigned int &limit, bitmap *visited,
bool abort_on_visited,
void *(*translate)(ao_ref *, tree, void *, bool *),
@@ -3128,7 +3273,8 @@ get_continuation_for_phi (gimple *phi, ao_ref *ref,
arg1 = PHI_ARG_DEF (phi, i);
if (arg1 == arg0)
;
- else if (! maybe_skip_until (phi, arg0, dom, ref, arg1, limit, visited,
+ else if (! maybe_skip_until (phi, arg0, dom, ref, arg1, tbaa_p,
+ limit, visited,
abort_on_visited,
/* Do not translate when walking over
backedges. */
@@ -3172,7 +3318,7 @@ get_continuation_for_phi (gimple *phi, ao_ref *ref,
TODO: Cache the vector of equivalent vuses per ref, vuse pair. */
void *
-walk_non_aliased_vuses (ao_ref *ref, tree vuse,
+walk_non_aliased_vuses (ao_ref *ref, tree vuse, bool tbaa_p,
void *(*walker)(ao_ref *, tree, void *),
void *(*translate)(ao_ref *, tree, void *, bool *),
tree (*valueize)(tree),
@@ -3213,7 +3359,7 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse,
if (gimple_nop_p (def_stmt))
break;
else if (gimple_code (def_stmt) == GIMPLE_PHI)
- vuse = get_continuation_for_phi (def_stmt, ref, limit,
+ vuse = get_continuation_for_phi (def_stmt, ref, tbaa_p, limit,
&visited, translated, translate, data);
else
{
@@ -3223,7 +3369,7 @@ walk_non_aliased_vuses (ao_ref *ref, tree vuse,
break;
}
--limit;
- if (stmt_may_clobber_ref_p_1 (def_stmt, ref))
+ if (stmt_may_clobber_ref_p_1 (def_stmt, ref, tbaa_p))
{
if (!translate)
break;
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index cee8449..c7c6020 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -68,8 +68,9 @@ struct GTY(()) pt_solution
/* Simplified and cached information about a memory reference tree.
Used by the alias-oracle internally and externally in alternate
interfaces. */
-struct ao_ref
+class ao_ref
{
+public:
/* The original full memory reference tree or NULL_TREE if that is
not available. */
tree ref;
@@ -131,11 +132,11 @@ extern bool call_may_clobber_ref_p (gcall *, tree);
extern bool call_may_clobber_ref_p_1 (gcall *, ao_ref *);
extern bool stmt_kills_ref_p (gimple *, tree);
extern bool stmt_kills_ref_p (gimple *, ao_ref *);
-extern tree get_continuation_for_phi (gimple *, ao_ref *,
+extern tree get_continuation_for_phi (gimple *, ao_ref *, bool,
unsigned int &, bitmap *, bool,
void *(*)(ao_ref *, tree, void *, bool *),
void *);
-extern void *walk_non_aliased_vuses (ao_ref *, tree,
+extern void *walk_non_aliased_vuses (ao_ref *, tree, bool,
void *(*)(ao_ref *, tree, void *),
void *(*)(ao_ref *, tree, void *, bool *),
tree (*)(tree), unsigned &, void *);
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 51b9d9f..4dd7035 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -157,7 +157,8 @@ typedef enum
VARYING
} ccp_lattice_t;
-struct ccp_prop_value_t {
+class ccp_prop_value_t {
+public:
/* Lattice value. */
ccp_lattice_t lattice_val;
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 2ea0a66..2ca0d02 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -674,8 +674,9 @@ ssa_conflicts_dump (FILE *file, ssa_conflicts *ptr)
marked as being live. This delays clearing of these bitmaps until
they are actually needed again. */
-struct live_track
+class live_track
{
+public:
bitmap_obstack obstack; /* A place to allocate our bitmaps. */
bitmap_head live_base_var; /* Indicates if a basevar is live. */
bitmap_head *live_base_partitions; /* Live partitions for each basevar. */
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index c73fbab..6398c1e 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -411,7 +411,7 @@ find_obviously_necessary_stmts (bool aggressive)
/* Prevent the empty possibly infinite loops from being removed. */
if (aggressive)
{
- struct loop *loop;
+ class loop *loop;
if (mark_irreducible_loops ())
FOR_EACH_BB_FN (bb, cfun)
{
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index b0d56fc..2d03866 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -395,7 +395,7 @@ edge_info::record_simple_equiv (tree lhs, tree rhs)
void
free_dom_edge_info (edge e)
{
- class edge_info *edge_info = (struct edge_info *)e->aux;
+ class edge_info *edge_info = (class edge_info *)e->aux;
if (edge_info)
delete edge_info;
@@ -543,7 +543,7 @@ record_edge_info (basic_block bb)
bool can_infer_simple_equiv
= !(HONOR_SIGNED_ZEROS (op0)
&& real_zerop (op0));
- struct edge_info *edge_info;
+ class edge_info *edge_info;
edge_info = new class edge_info (true_edge);
record_conditions (&edge_info->cond_equivalences, cond, inverted);
@@ -567,7 +567,7 @@ record_edge_info (basic_block bb)
bool can_infer_simple_equiv
= !(HONOR_SIGNED_ZEROS (op1)
&& (TREE_CODE (op1) == SSA_NAME || real_zerop (op1)));
- struct edge_info *edge_info;
+ class edge_info *edge_info;
edge_info = new class edge_info (true_edge);
record_conditions (&edge_info->cond_equivalences, cond, inverted);
@@ -913,21 +913,26 @@ simplify_stmt_for_jump_threading (gimple *stmt,
find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j);
+ /* Is there only one such label? */
if (i == j)
{
tree label = gimple_switch_label (switch_stmt, i);
tree singleton;
+ /* The i'th label will only be taken if the value range of the
+ operand is entirely within the bounds of this label. */
if (CASE_HIGH (label) != NULL_TREE
? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0
&& tree_int_cst_compare (CASE_HIGH (label), vr->max ()) >= 0)
: (vr->singleton_p (&singleton)
&& tree_int_cst_equal (CASE_LOW (label), singleton)))
return label;
-
- if (i > j)
- return gimple_switch_label (switch_stmt, 0);
}
+
+ /* If there are no such labels, then the default label
+ will be taken. */
+ if (i > j)
+ return gimple_switch_label (switch_stmt, 0);
}
if (vr->kind () == VR_ANTI_RANGE)
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index df05a55..5b7c4fc 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -107,42 +107,42 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write)
{
switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
{
- case BUILT_IN_MEMCPY:
- case BUILT_IN_MEMMOVE:
- case BUILT_IN_MEMSET:
- case BUILT_IN_MEMCPY_CHK:
- case BUILT_IN_MEMMOVE_CHK:
- case BUILT_IN_MEMSET_CHK:
- {
- tree size = NULL_TREE;
- if (gimple_call_num_args (stmt) == 3)
- size = gimple_call_arg (stmt, 2);
- tree ptr = gimple_call_arg (stmt, 0);
- ao_ref_init_from_ptr_and_size (write, ptr, size);
- return true;
- }
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMSET:
+ case BUILT_IN_MEMCPY_CHK:
+ case BUILT_IN_MEMMOVE_CHK:
+ case BUILT_IN_MEMSET_CHK:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRNCPY_CHK:
+ {
+ tree size = gimple_call_arg (stmt, 2);
+ tree ptr = gimple_call_arg (stmt, 0);
+ ao_ref_init_from_ptr_and_size (write, ptr, size);
+ return true;
+ }
- /* A calloc call can never be dead, but it can make
- subsequent stores redundant if they store 0 into
- the same memory locations. */
- case BUILT_IN_CALLOC:
- {
- tree nelem = gimple_call_arg (stmt, 0);
- tree selem = gimple_call_arg (stmt, 1);
- tree lhs;
- if (TREE_CODE (nelem) == INTEGER_CST
- && TREE_CODE (selem) == INTEGER_CST
- && (lhs = gimple_call_lhs (stmt)) != NULL_TREE)
- {
- tree size = fold_build2 (MULT_EXPR, TREE_TYPE (nelem),
- nelem, selem);
- ao_ref_init_from_ptr_and_size (write, lhs, size);
- return true;
- }
- }
+ /* A calloc call can never be dead, but it can make
+ subsequent stores redundant if they store 0 into
+ the same memory locations. */
+ case BUILT_IN_CALLOC:
+ {
+ tree nelem = gimple_call_arg (stmt, 0);
+ tree selem = gimple_call_arg (stmt, 1);
+ tree lhs;
+ if (TREE_CODE (nelem) == INTEGER_CST
+ && TREE_CODE (selem) == INTEGER_CST
+ && (lhs = gimple_call_lhs (stmt)) != NULL_TREE)
+ {
+ tree size = fold_build2 (MULT_EXPR, TREE_TYPE (nelem),
+ nelem, selem);
+ ao_ref_init_from_ptr_and_size (write, lhs, size);
+ return true;
+ }
+ }
- default:
- break;
+ default:
+ break;
}
}
else if (is_gimple_assign (stmt))
@@ -469,8 +469,10 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live, gimple *stmt)
{
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMMOVE:
+ case BUILT_IN_STRNCPY:
case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMMOVE_CHK:
+ case BUILT_IN_STRNCPY_CHK:
{
int head_trim, tail_trim;
compute_trims (ref, live, &head_trim, &tail_trim, stmt);
@@ -964,57 +966,60 @@ dse_dom_walker::dse_optimize_stmt (gimple_stmt_iterator *gsi)
tree fndecl = gimple_call_fndecl (stmt);
switch (DECL_FUNCTION_CODE (fndecl))
{
- case BUILT_IN_MEMCPY:
- case BUILT_IN_MEMMOVE:
- case BUILT_IN_MEMSET:
- case BUILT_IN_MEMCPY_CHK:
- case BUILT_IN_MEMMOVE_CHK:
- case BUILT_IN_MEMSET_CHK:
- {
- /* Occasionally calls with an explicit length of zero
- show up in the IL. It's pointless to do analysis
- on them, they're trivially dead. */
- tree size = gimple_call_arg (stmt, 2);
- if (integer_zerop (size))
- {
- delete_dead_or_redundant_call (gsi, "dead");
- return;
- }
-
- /* If this is a memset call that initializes an object
- to zero, it may be redundant with an earlier memset
- or empty CONSTRUCTOR of a larger object. */
- if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET
- || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET_CHK)
- && integer_zerop (gimple_call_arg (stmt, 1)))
- dse_optimize_redundant_stores (stmt);
-
- enum dse_store_status store_status;
- m_byte_tracking_enabled
- = setup_live_bytes_from_ref (&ref, m_live_bytes);
- store_status = dse_classify_store (&ref, stmt,
- m_byte_tracking_enabled,
- m_live_bytes);
- if (store_status == DSE_STORE_LIVE)
- return;
-
- if (store_status == DSE_STORE_MAYBE_PARTIAL_DEAD)
- {
- maybe_trim_memstar_call (&ref, m_live_bytes, stmt);
- return;
- }
-
- if (store_status == DSE_STORE_DEAD)
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_STRNCPY:
+ case BUILT_IN_MEMSET:
+ case BUILT_IN_MEMCPY_CHK:
+ case BUILT_IN_MEMMOVE_CHK:
+ case BUILT_IN_STRNCPY_CHK:
+ case BUILT_IN_MEMSET_CHK:
+ {
+ /* Occasionally calls with an explicit length of zero
+ show up in the IL. It's pointless to do analysis
+ on them, they're trivially dead. */
+ tree size = gimple_call_arg (stmt, 2);
+ if (integer_zerop (size))
+ {
delete_dead_or_redundant_call (gsi, "dead");
+ return;
+ }
+
+ /* If this is a memset call that initializes an object
+ to zero, it may be redundant with an earlier memset
+ or empty CONSTRUCTOR of a larger object. */
+ if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET
+ || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_MEMSET_CHK)
+ && integer_zerop (gimple_call_arg (stmt, 1)))
+ dse_optimize_redundant_stores (stmt);
+
+ enum dse_store_status store_status;
+ m_byte_tracking_enabled
+ = setup_live_bytes_from_ref (&ref, m_live_bytes);
+ store_status = dse_classify_store (&ref, stmt,
+ m_byte_tracking_enabled,
+ m_live_bytes);
+ if (store_status == DSE_STORE_LIVE)
return;
- }
- case BUILT_IN_CALLOC:
- /* We already know the arguments are integer constants. */
- dse_optimize_redundant_stores (stmt);
+ if (store_status == DSE_STORE_MAYBE_PARTIAL_DEAD)
+ {
+ maybe_trim_memstar_call (&ref, m_live_bytes, stmt);
+ return;
+ }
- default:
+ if (store_status == DSE_STORE_DEAD)
+ delete_dead_or_redundant_call (gsi, "dead");
return;
+ }
+
+ case BUILT_IN_CALLOC:
+ /* We already know the arguments are integer constants. */
+ dse_optimize_redundant_stores (stmt);
+ return;
+
+ default:
+ return;
}
}
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index e9ae8e0..9908794 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -79,7 +79,7 @@ var_map_base_fini (var_map map)
function. */
var_map
-init_var_map (int size, struct loop *loop)
+init_var_map (int size, class loop *loop)
{
var_map map;
@@ -852,7 +852,7 @@ remove_unused_locals (void)
if (cfun->has_simduid_loops)
{
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, 0)
if (loop->simduid && !is_used_p (loop->simduid))
loop->simduid = NULL_TREE;
diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h
index 78b033b..5bef4d5 100644
--- a/gcc/tree-ssa-live.h
+++ b/gcc/tree-ssa-live.h
@@ -80,7 +80,7 @@ typedef struct _var_map
/* Value used to represent no partition number. */
#define NO_PARTITION -1
-extern var_map init_var_map (int, struct loop* = NULL);
+extern var_map init_var_map (int, class loop* = NULL);
extern void delete_var_map (var_map);
extern int var_union (var_map, tree, tree);
extern void partition_view_normal (var_map);
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index 25f562b..d92d7c8 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -48,7 +48,7 @@ along with GCC; see the file COPYING3. If not see
amount. */
static bool
-should_duplicate_loop_header_p (basic_block header, struct loop *loop,
+should_duplicate_loop_header_p (basic_block header, class loop *loop,
int *limit)
{
gimple_stmt_iterator bsi;
@@ -211,7 +211,7 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop,
/* Checks whether LOOP is a do-while style loop. */
static bool
-do_while_loop_p (struct loop *loop)
+do_while_loop_p (class loop *loop)
{
gimple *stmt = last_stmt (loop->latch);
@@ -268,7 +268,7 @@ class ch_base : public gimple_opt_pass
unsigned int copy_headers (function *fun);
/* Return true to copy headers of LOOP or false to skip. */
- virtual bool process_loop_p (struct loop *loop) = 0;
+ virtual bool process_loop_p (class loop *loop) = 0;
};
const pass_data pass_data_ch =
@@ -301,7 +301,7 @@ public:
protected:
/* ch_base method: */
- virtual bool process_loop_p (struct loop *loop);
+ virtual bool process_loop_p (class loop *loop);
}; // class pass_ch
const pass_data pass_data_ch_vect =
@@ -339,7 +339,7 @@ public:
protected:
/* ch_base method: */
- virtual bool process_loop_p (struct loop *loop);
+ virtual bool process_loop_p (class loop *loop);
}; // class pass_ch_vect
/* For all loops, copy the condition at the end of the loop body in front
@@ -349,7 +349,7 @@ protected:
unsigned int
ch_base::copy_headers (function *fun)
{
- struct loop *loop;
+ class loop *loop;
basic_block header;
edge exit, entry;
basic_block *bbs, *copied_bbs;
@@ -549,7 +549,7 @@ pass_ch_vect::execute (function *fun)
/* Apply header copying according to a very simple test of do-while shape. */
bool
-pass_ch::process_loop_p (struct loop *loop)
+pass_ch::process_loop_p (class loop *loop)
{
return !do_while_loop_p (loop);
}
@@ -557,7 +557,7 @@ pass_ch::process_loop_p (struct loop *loop)
/* Apply header-copying to loops where we might enable vectorization. */
bool
-pass_ch_vect::process_loop_p (struct loop *loop)
+pass_ch_vect::process_loop_p (class loop *loop)
{
if (!flag_tree_loop_vectorize && !loop->force_vectorize)
return false;
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 2064c29..12176e0 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -75,13 +75,13 @@ along with GCC; see the file COPYING3. If not see
struct lim_aux_data
{
- struct loop *max_loop; /* The outermost loop in that the statement
+ class loop *max_loop; /* The outermost loop in that the statement
is invariant. */
- struct loop *tgt_loop; /* The loop out of that we want to move the
+ class loop *tgt_loop; /* The loop out of that we want to move the
invariant. */
- struct loop *always_executed_in;
+ class loop *always_executed_in;
/* The outermost loop for that we are sure
the statement is executed if the loop
is entered. */
@@ -113,8 +113,9 @@ struct mem_ref_loc
/* Description of a memory reference. */
-struct im_mem_ref
+class im_mem_ref
{
+public:
unsigned id : 30; /* ID assigned to the memory reference
(its index in memory_accesses.refs_list) */
unsigned ref_canonical : 1; /* Whether mem.ref was canonicalized. */
@@ -159,7 +160,7 @@ struct mem_ref_hasher : nofree_ptr_hash <im_mem_ref>
static inline bool equal (const im_mem_ref *, const ao_ref *);
};
-/* A hash function for struct im_mem_ref object OBJ. */
+/* A hash function for class im_mem_ref object OBJ. */
inline hashval_t
mem_ref_hasher::hash (const im_mem_ref *mem)
@@ -167,7 +168,7 @@ mem_ref_hasher::hash (const im_mem_ref *mem)
return mem->hash;
}
-/* An equality function for struct im_mem_ref object MEM1 with
+/* An equality function for class im_mem_ref object MEM1 with
memory reference OBJ2. */
inline bool
@@ -225,15 +226,15 @@ static struct
static bitmap_obstack lim_bitmap_obstack;
static obstack mem_ref_obstack;
-static bool ref_indep_loop_p (struct loop *, im_mem_ref *);
-static bool ref_always_accessed_p (struct loop *, im_mem_ref *, bool);
+static bool ref_indep_loop_p (class loop *, im_mem_ref *);
+static bool ref_always_accessed_p (class loop *, im_mem_ref *, bool);
/* Minimum cost of an expensive expression. */
#define LIM_EXPENSIVE ((unsigned) PARAM_VALUE (PARAM_LIM_EXPENSIVE))
/* The outermost loop for which execution of the header guarantees that the
block will be executed. */
-#define ALWAYS_EXECUTED_IN(BB) ((struct loop *) (BB)->aux)
+#define ALWAYS_EXECUTED_IN(BB) ((class loop *) (BB)->aux)
#define SET_ALWAYS_EXECUTED_IN(BB, VAL) ((BB)->aux = (void *) (VAL))
/* ID of the shared unanalyzable mem. */
@@ -395,12 +396,12 @@ movement_possibility (gimple *stmt)
other operands, i.e. the outermost loop enclosing LOOP in that the value
of DEF is invariant. */
-static struct loop *
-outermost_invariant_loop (tree def, struct loop *loop)
+static class loop *
+outermost_invariant_loop (tree def, class loop *loop)
{
gimple *def_stmt;
basic_block def_bb;
- struct loop *max_loop;
+ class loop *max_loop;
struct lim_aux_data *lim_data;
if (!def)
@@ -443,12 +444,12 @@ outermost_invariant_loop (tree def, struct loop *loop)
If DEF is not invariant in LOOP, return false. Otherwise return TRUE. */
static bool
-add_dependency (tree def, struct lim_aux_data *data, struct loop *loop,
+add_dependency (tree def, struct lim_aux_data *data, class loop *loop,
bool add_cost)
{
gimple *def_stmt = SSA_NAME_DEF_STMT (def);
basic_block def_bb = gimple_bb (def_stmt);
- struct loop *max_loop;
+ class loop *max_loop;
struct lim_aux_data *def_data;
if (!def_bb)
@@ -559,10 +560,10 @@ stmt_cost (gimple *stmt)
REF is independent. If REF is not independent in LOOP, NULL is returned
instead. */
-static struct loop *
-outermost_indep_loop (struct loop *outer, struct loop *loop, im_mem_ref *ref)
+static class loop *
+outermost_indep_loop (class loop *outer, class loop *loop, im_mem_ref *ref)
{
- struct loop *aloop;
+ class loop *aloop;
if (ref->stored && bitmap_bit_p (ref->stored, loop->num))
return NULL;
@@ -648,8 +649,8 @@ static bool
determine_max_movement (gimple *stmt, bool must_preserve_exec)
{
basic_block bb = gimple_bb (stmt);
- struct loop *loop = bb->loop_father;
- struct loop *level;
+ class loop *loop = bb->loop_father;
+ class loop *level;
struct lim_aux_data *lim_data = get_lim_data (stmt);
tree val;
ssa_op_iter iter;
@@ -776,9 +777,9 @@ determine_max_movement (gimple *stmt, bool must_preserve_exec)
operands) is hoisted at least out of the loop LEVEL. */
static void
-set_level (gimple *stmt, struct loop *orig_loop, struct loop *level)
+set_level (gimple *stmt, class loop *orig_loop, class loop *level)
{
- struct loop *stmt_loop = gimple_bb (stmt)->loop_father;
+ class loop *stmt_loop = gimple_bb (stmt)->loop_father;
struct lim_aux_data *lim_data;
gimple *dep_stmt;
unsigned i;
@@ -973,7 +974,7 @@ invariantness_dom_walker::before_dom_children (basic_block bb)
gimple_stmt_iterator bsi;
gimple *stmt;
bool maybe_never = ALWAYS_EXECUTED_IN (bb) == NULL;
- struct loop *outermost = ALWAYS_EXECUTED_IN (bb);
+ class loop *outermost = ALWAYS_EXECUTED_IN (bb);
struct lim_aux_data *lim_data;
if (!loop_outer (bb->loop_father))
@@ -1052,7 +1053,7 @@ invariantness_dom_walker::before_dom_children (basic_block bb)
{
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
- struct loop *ol1 = outermost_invariant_loop (op1,
+ class loop *ol1 = outermost_invariant_loop (op1,
loop_containing_stmt (stmt));
/* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
@@ -1111,7 +1112,7 @@ invariantness_dom_walker::before_dom_children (basic_block bb)
unsigned int
move_computations_worker (basic_block bb)
{
- struct loop *level;
+ class loop *level;
unsigned cost = 0;
struct lim_aux_data *lim_data;
unsigned int todo = 0;
@@ -1295,7 +1296,7 @@ move_computations (void)
static bool
may_move_till (tree ref, tree *index, void *data)
{
- struct loop *loop = (struct loop *) data, *max_loop;
+ class loop *loop = (class loop *) data, *max_loop;
/* If REF is an array reference, check also that the step and the lower
bound is invariant in LOOP. */
@@ -1324,7 +1325,7 @@ may_move_till (tree ref, tree *index, void *data)
moved out of the LOOP. ORIG_LOOP is the loop in that EXPR is used. */
static void
-force_move_till_op (tree op, struct loop *orig_loop, struct loop *loop)
+force_move_till_op (tree op, class loop *orig_loop, class loop *loop)
{
gimple *stmt;
@@ -1347,8 +1348,8 @@ force_move_till_op (tree op, struct loop *orig_loop, struct loop *loop)
struct fmt_data
{
- struct loop *loop;
- struct loop *orig_loop;
+ class loop *loop;
+ class loop *orig_loop;
};
static bool
@@ -1373,7 +1374,7 @@ force_move_till (tree ref, tree *index, void *data)
/* A function to free the mem_ref object OBJ. */
static void
-memref_free (struct im_mem_ref *mem)
+memref_free (class im_mem_ref *mem)
{
mem->accesses_in_loop.release ();
}
@@ -1384,7 +1385,7 @@ memref_free (struct im_mem_ref *mem)
static im_mem_ref *
mem_ref_alloc (ao_ref *mem, unsigned hash, unsigned id)
{
- im_mem_ref *ref = XOBNEW (&mem_ref_obstack, struct im_mem_ref);
+ im_mem_ref *ref = XOBNEW (&mem_ref_obstack, class im_mem_ref);
if (mem)
ref->mem = *mem;
else
@@ -1417,7 +1418,7 @@ record_mem_ref_loc (im_mem_ref *ref, gimple *stmt, tree *loc)
necessary. Return whether a bit was changed. */
static bool
-set_ref_stored_in_loop (im_mem_ref *ref, struct loop *loop)
+set_ref_stored_in_loop (im_mem_ref *ref, class loop *loop)
{
if (!ref->stored)
ref->stored = BITMAP_ALLOC (&lim_bitmap_obstack);
@@ -1427,7 +1428,7 @@ set_ref_stored_in_loop (im_mem_ref *ref, struct loop *loop)
/* Marks reference REF as stored in LOOP. */
static void
-mark_ref_stored (im_mem_ref *ref, struct loop *loop)
+mark_ref_stored (im_mem_ref *ref, class loop *loop)
{
while (loop != current_loops->tree_root
&& set_ref_stored_in_loop (ref, loop))
@@ -1440,7 +1441,7 @@ mark_ref_stored (im_mem_ref *ref, struct loop *loop)
well. */
static void
-gather_mem_refs_stmt (struct loop *loop, gimple *stmt)
+gather_mem_refs_stmt (class loop *loop, gimple *stmt)
{
tree *mem = NULL;
hashval_t hash;
@@ -1582,8 +1583,8 @@ sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_)
{
basic_block bb1 = *(basic_block *)const_cast<void *>(bb1_);
basic_block bb2 = *(basic_block *)const_cast<void *>(bb2_);
- struct loop *loop1 = bb1->loop_father;
- struct loop *loop2 = bb2->loop_father;
+ class loop *loop1 = bb1->loop_father;
+ class loop *loop2 = bb2->loop_father;
if (loop1->num == loop2->num)
return bb1->index - bb2->index;
return bb_loop_postorder[loop1->num] < bb_loop_postorder[loop2->num] ? -1 : 1;
@@ -1596,8 +1597,8 @@ sort_locs_in_loop_postorder_cmp (const void *loc1_, const void *loc2_)
{
mem_ref_loc *loc1 = (mem_ref_loc *)const_cast<void *>(loc1_);
mem_ref_loc *loc2 = (mem_ref_loc *)const_cast<void *>(loc2_);
- struct loop *loop1 = gimple_bb (loc1->stmt)->loop_father;
- struct loop *loop2 = gimple_bb (loc2->stmt)->loop_father;
+ class loop *loop1 = gimple_bb (loc1->stmt)->loop_father;
+ class loop *loop2 = gimple_bb (loc2->stmt)->loop_father;
if (loop1->num == loop2->num)
return 0;
return bb_loop_postorder[loop1->num] < bb_loop_postorder[loop2->num] ? -1 : 1;
@@ -1610,7 +1611,7 @@ analyze_memory_references (void)
{
gimple_stmt_iterator bsi;
basic_block bb, *bbs;
- struct loop *loop, *outer;
+ class loop *loop, *outer;
unsigned i, n;
/* Collect all basic-blocks in loops and sort them after their
@@ -1701,9 +1702,9 @@ mem_refs_may_alias_p (im_mem_ref *mem1, im_mem_ref *mem2,
static int
find_ref_loc_in_loop_cmp (const void *loop_, const void *loc_)
{
- struct loop *loop = (struct loop *)const_cast<void *>(loop_);
+ class loop *loop = (class loop *)const_cast<void *>(loop_);
mem_ref_loc *loc = (mem_ref_loc *)const_cast<void *>(loc_);
- struct loop *loc_loop = gimple_bb (loc->stmt)->loop_father;
+ class loop *loc_loop = gimple_bb (loc->stmt)->loop_father;
if (loop->num == loc_loop->num
|| flow_loop_nested_p (loop, loc_loop))
return 0;
@@ -1718,7 +1719,7 @@ find_ref_loc_in_loop_cmp (const void *loop_, const void *loc_)
template <typename FN>
static bool
-for_all_locs_in_loop (struct loop *loop, im_mem_ref *ref, FN fn)
+for_all_locs_in_loop (class loop *loop, im_mem_ref *ref, FN fn)
{
unsigned i;
mem_ref_loc *loc;
@@ -1756,8 +1757,9 @@ for_all_locs_in_loop (struct loop *loop, im_mem_ref *ref, FN fn)
/* Rewrites location LOC by TMP_VAR. */
-struct rewrite_mem_ref_loc
+class rewrite_mem_ref_loc
{
+public:
rewrite_mem_ref_loc (tree tmp_var_) : tmp_var (tmp_var_) {}
bool operator () (mem_ref_loc *loc);
tree tmp_var;
@@ -1774,15 +1776,16 @@ rewrite_mem_ref_loc::operator () (mem_ref_loc *loc)
/* Rewrites all references to REF in LOOP by variable TMP_VAR. */
static void
-rewrite_mem_refs (struct loop *loop, im_mem_ref *ref, tree tmp_var)
+rewrite_mem_refs (class loop *loop, im_mem_ref *ref, tree tmp_var)
{
for_all_locs_in_loop (loop, ref, rewrite_mem_ref_loc (tmp_var));
}
/* Stores the first reference location in LOCP. */
-struct first_mem_ref_loc_1
+class first_mem_ref_loc_1
{
+public:
first_mem_ref_loc_1 (mem_ref_loc **locp_) : locp (locp_) {}
bool operator () (mem_ref_loc *loc);
mem_ref_loc **locp;
@@ -1798,7 +1801,7 @@ first_mem_ref_loc_1::operator () (mem_ref_loc *loc)
/* Returns the first reference location to REF in LOOP. */
static mem_ref_loc *
-first_mem_ref_loc (struct loop *loop, im_mem_ref *ref)
+first_mem_ref_loc (class loop *loop, im_mem_ref *ref)
{
mem_ref_loc *locp = NULL;
for_all_locs_in_loop (loop, ref, first_mem_ref_loc_1 (&locp));
@@ -2017,8 +2020,9 @@ execute_sm_if_changed (edge ex, tree mem, tree tmp_var, tree flag,
/* When REF is set on the location, set flag indicating the store. */
-struct sm_set_flag_if_changed
+class sm_set_flag_if_changed
{
+public:
sm_set_flag_if_changed (tree flag_, hash_set <basic_block> *bbs_)
: flag (flag_), bbs (bbs_) {}
bool operator () (mem_ref_loc *loc);
@@ -2045,7 +2049,7 @@ sm_set_flag_if_changed::operator () (mem_ref_loc *loc)
set, set an appropriate flag indicating the store. */
static tree
-execute_sm_if_changed_flag_set (struct loop *loop, im_mem_ref *ref,
+execute_sm_if_changed_flag_set (class loop *loop, im_mem_ref *ref,
hash_set <basic_block> *bbs)
{
tree flag;
@@ -2061,7 +2065,7 @@ execute_sm_if_changed_flag_set (struct loop *loop, im_mem_ref *ref,
to the reference from the temporary variable are emitted to exits. */
static void
-execute_sm (struct loop *loop, vec<edge> exits, im_mem_ref *ref)
+execute_sm (class loop *loop, vec<edge> exits, im_mem_ref *ref)
{
tree tmp_var, store_flag = NULL_TREE;
unsigned i;
@@ -2137,7 +2141,7 @@ execute_sm (struct loop *loop, vec<edge> exits, im_mem_ref *ref)
edges of the LOOP. */
static void
-hoist_memory_references (struct loop *loop, bitmap mem_refs,
+hoist_memory_references (class loop *loop, bitmap mem_refs,
vec<edge> exits)
{
im_mem_ref *ref;
@@ -2151,19 +2155,20 @@ hoist_memory_references (struct loop *loop, bitmap mem_refs,
}
}
-struct ref_always_accessed
+class ref_always_accessed
{
- ref_always_accessed (struct loop *loop_, bool stored_p_)
+public:
+ ref_always_accessed (class loop *loop_, bool stored_p_)
: loop (loop_), stored_p (stored_p_) {}
bool operator () (mem_ref_loc *loc);
- struct loop *loop;
+ class loop *loop;
bool stored_p;
};
bool
ref_always_accessed::operator () (mem_ref_loc *loc)
{
- struct loop *must_exec;
+ class loop *must_exec;
if (!get_lim_data (loc->stmt))
return false;
@@ -2193,7 +2198,7 @@ ref_always_accessed::operator () (mem_ref_loc *loc)
make sure REF is always stored to in LOOP. */
static bool
-ref_always_accessed_p (struct loop *loop, im_mem_ref *ref, bool stored_p)
+ref_always_accessed_p (class loop *loop, im_mem_ref *ref, bool stored_p)
{
return for_all_locs_in_loop (loop, ref,
ref_always_accessed (loop, stored_p));
@@ -2229,7 +2234,7 @@ refs_independent_p (im_mem_ref *ref1, im_mem_ref *ref2)
and its super-loops. */
static void
-record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p)
+record_dep_loop (class loop *loop, im_mem_ref *ref, bool stored_p)
{
/* We can propagate dependent-in-loop bits up the loop
hierarchy to all outer loops. */
@@ -2242,7 +2247,7 @@ record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p)
references in LOOP. */
static bool
-ref_indep_loop_p_1 (struct loop *loop, im_mem_ref *ref, bool stored_p)
+ref_indep_loop_p_1 (class loop *loop, im_mem_ref *ref, bool stored_p)
{
stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
@@ -2263,7 +2268,7 @@ ref_indep_loop_p_1 (struct loop *loop, im_mem_ref *ref, bool stored_p)
if (bitmap_bit_p (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
return false;
- struct loop *inner = loop->inner;
+ class loop *inner = loop->inner;
while (inner)
{
if (!ref_indep_loop_p_1 (inner, ref, stored_p))
@@ -2323,7 +2328,7 @@ ref_indep_loop_p_1 (struct loop *loop, im_mem_ref *ref, bool stored_p)
LOOP. */
static bool
-ref_indep_loop_p (struct loop *loop, im_mem_ref *ref)
+ref_indep_loop_p (class loop *loop, im_mem_ref *ref)
{
gcc_checking_assert (MEM_ANALYZABLE (ref));
@@ -2333,7 +2338,7 @@ ref_indep_loop_p (struct loop *loop, im_mem_ref *ref)
/* Returns true if we can perform store motion of REF from LOOP. */
static bool
-can_sm_ref_p (struct loop *loop, im_mem_ref *ref)
+can_sm_ref_p (class loop *loop, im_mem_ref *ref)
{
tree base;
@@ -2374,7 +2379,7 @@ can_sm_ref_p (struct loop *loop, im_mem_ref *ref)
motion was performed in one of the outer loops. */
static void
-find_refs_for_sm (struct loop *loop, bitmap sm_executed, bitmap refs_to_sm)
+find_refs_for_sm (class loop *loop, bitmap sm_executed, bitmap refs_to_sm)
{
bitmap refs = &memory_accesses.all_refs_stored_in_loop[loop->num];
unsigned i;
@@ -2394,7 +2399,7 @@ find_refs_for_sm (struct loop *loop, bitmap sm_executed, bitmap refs_to_sm)
on its exits). */
static bool
-loop_suitable_for_sm (struct loop *loop ATTRIBUTE_UNUSED,
+loop_suitable_for_sm (class loop *loop ATTRIBUTE_UNUSED,
vec<edge> exits)
{
unsigned i;
@@ -2412,10 +2417,10 @@ loop_suitable_for_sm (struct loop *loop ATTRIBUTE_UNUSED,
store motion was executed in one of the outer loops. */
static void
-store_motion_loop (struct loop *loop, bitmap sm_executed)
+store_motion_loop (class loop *loop, bitmap sm_executed)
{
vec<edge> exits = get_loop_exit_edges (loop);
- struct loop *subloop;
+ class loop *subloop;
bitmap sm_in_loop = BITMAP_ALLOC (&lim_bitmap_obstack);
if (loop_suitable_for_sm (loop, exits))
@@ -2438,7 +2443,7 @@ store_motion_loop (struct loop *loop, bitmap sm_executed)
static void
store_motion (void)
{
- struct loop *loop;
+ class loop *loop;
bitmap sm_executed = BITMAP_ALLOC (&lim_bitmap_obstack);
for (loop = current_loops->tree_root->inner; loop != NULL; loop = loop->next)
@@ -2454,12 +2459,12 @@ store_motion (void)
blocks that contain a nonpure call. */
static void
-fill_always_executed_in_1 (struct loop *loop, sbitmap contains_call)
+fill_always_executed_in_1 (class loop *loop, sbitmap contains_call)
{
basic_block bb = NULL, *bbs, last = NULL;
unsigned i;
edge e;
- struct loop *inn_loop = loop;
+ class loop *inn_loop = loop;
if (ALWAYS_EXECUTED_IN (loop->header) == NULL)
{
@@ -2532,7 +2537,7 @@ static void
fill_always_executed_in (void)
{
basic_block bb;
- struct loop *loop;
+ class loop *loop;
auto_sbitmap contains_call (last_basic_block_for_fn (cfun));
bitmap_clear (contains_call);
@@ -2559,7 +2564,7 @@ fill_always_executed_in (void)
static void
tree_ssa_lim_initialize (void)
{
- struct loop *loop;
+ class loop *loop;
unsigned i;
bitmap_obstack_initialize (&lim_bitmap_obstack);
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index eb0c1c9..5952cad 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -82,7 +82,7 @@ enum unroll_level
if they are not NULL. */
void
-create_canonical_iv (struct loop *loop, edge exit, tree niter,
+create_canonical_iv (class loop *loop, edge exit, tree niter,
tree *var_before = NULL, tree *var_after = NULL)
{
edge in;
@@ -161,7 +161,7 @@ struct loop_size
/* Return true if OP in STMT will be constant after peeling LOOP. */
static bool
-constant_after_peeling (tree op, gimple *stmt, struct loop *loop)
+constant_after_peeling (tree op, gimple *stmt, class loop *loop)
{
if (is_gimple_min_invariant (op))
return true;
@@ -211,7 +211,7 @@ constant_after_peeling (tree op, gimple *stmt, struct loop *loop)
Stop estimating after UPPER_BOUND is met. Return true in this case. */
static bool
-tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel,
+tree_estimate_loop_size (class loop *loop, edge exit, edge edge_to_cancel,
struct loop_size *size, int upper_bound)
{
basic_block *body = get_loop_body (loop);
@@ -441,7 +441,7 @@ estimated_unrolled_size (struct loop_size *size,
The other cases are hopefully rare and will be cleaned up later. */
static edge
-loop_edge_to_cancel (struct loop *loop)
+loop_edge_to_cancel (class loop *loop)
{
vec<edge> exits;
unsigned i;
@@ -495,9 +495,9 @@ loop_edge_to_cancel (struct loop *loop)
known to not be executed. */
static bool
-remove_exits_and_undefined_stmts (struct loop *loop, unsigned int npeeled)
+remove_exits_and_undefined_stmts (class loop *loop, unsigned int npeeled)
{
- struct nb_iter_bound *elt;
+ class nb_iter_bound *elt;
bool changed = false;
for (elt = loop->bounds; elt; elt = elt->next)
@@ -553,9 +553,9 @@ remove_exits_and_undefined_stmts (struct loop *loop, unsigned int npeeled)
discovered. */
static bool
-remove_redundant_iv_tests (struct loop *loop)
+remove_redundant_iv_tests (class loop *loop)
{
- struct nb_iter_bound *elt;
+ class nb_iter_bound *elt;
bool changed = false;
if (!loop->any_upper_bound)
@@ -569,7 +569,7 @@ remove_redundant_iv_tests (struct loop *loop)
{
basic_block bb = gimple_bb (elt->stmt);
edge exit_edge = EDGE_SUCC (bb, 0);
- struct tree_niter_desc niter;
+ class tree_niter_desc niter;
if (!loop_exit_edge_p (loop, exit_edge))
exit_edge = EDGE_SUCC (bb, 1);
@@ -629,7 +629,7 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
{
while (loops_to_unloop.length ())
{
- struct loop *loop = loops_to_unloop.pop ();
+ class loop *loop = loops_to_unloop.pop ();
int n_unroll = loops_to_unloop_nunroll.pop ();
basic_block latch = loop->latch;
edge latch_edge = loop_latch_edge (loop);
@@ -688,7 +688,7 @@ unloop_loops (bitmap loop_closed_ssa_invalidated,
a summary of the unroll to the dump file. */
static bool
-try_unroll_loop_completely (struct loop *loop,
+try_unroll_loop_completely (class loop *loop,
edge exit, tree niter, bool may_be_zero,
enum unroll_level ul,
HOST_WIDE_INT maxiter,
@@ -986,7 +986,7 @@ estimated_peeled_sequence_size (struct loop_size *size,
Parameters are the same as for try_unroll_loops_completely */
static bool
-try_peel_loop (struct loop *loop,
+try_peel_loop (class loop *loop,
edge exit, tree niter, bool may_be_zero,
HOST_WIDE_INT maxiter)
{
@@ -1155,7 +1155,7 @@ try_peel_loop (struct loop *loop,
Returns true if cfg is changed. */
static bool
-canonicalize_loop_induction_variables (struct loop *loop,
+canonicalize_loop_induction_variables (class loop *loop,
bool create_iv, enum unroll_level ul,
bool try_eval, bool allow_peel)
{
@@ -1164,7 +1164,7 @@ canonicalize_loop_induction_variables (struct loop *loop,
HOST_WIDE_INT maxiter;
bool modified = false;
dump_user_location_t locus;
- struct tree_niter_desc niter_desc;
+ class tree_niter_desc niter_desc;
bool may_be_zero = false;
/* For unrolling allow conditional constant or zero iterations, thus
@@ -1282,7 +1282,7 @@ canonicalize_loop_induction_variables (struct loop *loop,
unsigned int
canonicalize_induction_variables (void)
{
- struct loop *loop;
+ class loop *loop;
bool changed = false;
bool irred_invalidated = false;
bitmap loop_closed_ssa_invalidated = BITMAP_ALLOC (NULL);
@@ -1324,11 +1324,11 @@ canonicalize_induction_variables (void)
static bool
tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer,
- bitmap father_bbs, struct loop *loop)
+ bitmap father_bbs, class loop *loop)
{
- struct loop *loop_father;
+ class loop *loop_father;
bool changed = false;
- struct loop *inner;
+ class loop *inner;
enum unroll_level ul;
unsigned num = number_of_loops (cfun);
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index bbae83c..43ba429 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -121,7 +121,7 @@ along with GCC; see the file COPYING3. If not see
exists. */
static inline HOST_WIDE_INT
-avg_loop_niter (struct loop *loop)
+avg_loop_niter (class loop *loop)
{
HOST_WIDE_INT niter = estimated_stmt_executions_int (loop);
if (niter == -1)
@@ -175,8 +175,9 @@ enum use_type
};
/* Cost of a computation. */
-struct comp_cost
+class comp_cost
{
+public:
comp_cost (): cost (0), complexity (0), scratch (0)
{}
@@ -352,8 +353,9 @@ operator<= (comp_cost cost1, comp_cost cost2)
struct iv_inv_expr_ent;
/* The candidate - cost pair. */
-struct cost_pair
+class cost_pair
{
+public:
struct iv_cand *cand; /* The candidate. */
comp_cost cost; /* The cost. */
enum tree_code comp; /* For iv elimination, the comparison. */
@@ -396,7 +398,7 @@ struct iv_group
/* Number of IV candidates in the cost_map. */
unsigned n_map_members;
/* The costs wrto the iv candidates. */
- struct cost_pair *cost_map;
+ class cost_pair *cost_map;
/* The selected candidate for the group. */
struct iv_cand *selected;
/* Uses in the group. */
@@ -442,8 +444,9 @@ struct iv_cand
};
/* Hashtable entry for common candidate derived from iv uses. */
-struct iv_common_cand
+class iv_common_cand
{
+public:
tree base;
tree step;
/* IV uses from which this common candidate is derived. */
@@ -548,7 +551,7 @@ iv_inv_expr_hasher::equal (const iv_inv_expr_ent *expr1,
struct ivopts_data
{
/* The currently optimized loop. */
- struct loop *current_loop;
+ class loop *current_loop;
location_t loop_loc;
/* Numbers of iterations for all exits of the current loop. */
@@ -588,6 +591,9 @@ struct ivopts_data
/* The common candidates. */
vec<iv_common_cand *> iv_common_cands;
+ /* Hash map recording base object information of tree exp. */
+ hash_map<tree, tree> *base_object_map;
+
/* The maximum invariant variable id. */
unsigned max_inv_var_id;
@@ -616,8 +622,9 @@ struct ivopts_data
/* An assignment of iv candidates to uses. */
-struct iv_ca
+class iv_ca
{
+public:
/* The number of uses covered by the assignment. */
unsigned upto;
@@ -625,7 +632,7 @@ struct iv_ca
unsigned bad_groups;
/* Candidate assigned to a use, together with the related costs. */
- struct cost_pair **cand_for_group;
+ class cost_pair **cand_for_group;
/* Number of times each candidate is used. */
unsigned *n_cand_uses;
@@ -664,10 +671,10 @@ struct iv_ca_delta
struct iv_group *group;
/* An old assignment (for rollback purposes). */
- struct cost_pair *old_cp;
+ class cost_pair *old_cp;
/* A new assignment. */
- struct cost_pair *new_cp;
+ class cost_pair *new_cp;
/* Next change in the list. */
struct iv_ca_delta *next;
@@ -700,7 +707,7 @@ static comp_cost force_expr_to_var_cost (tree, bool);
/* The single loop exit if it dominates the latch, NULL otherwise. */
edge
-single_dom_exit (struct loop *loop)
+single_dom_exit (class loop *loop)
{
edge exit = single_exit (loop);
@@ -881,7 +888,7 @@ name_info (struct ivopts_data *data, tree name)
emitted in LOOP. */
static bool
-stmt_after_ip_normal_pos (struct loop *loop, gimple *stmt)
+stmt_after_ip_normal_pos (class loop *loop, gimple *stmt)
{
basic_block bb = ip_normal_pos (loop), sbb = gimple_bb (stmt);
@@ -922,7 +929,7 @@ stmt_after_inc_pos (struct iv_cand *cand, gimple *stmt, bool true_if_equal)
CAND is incremented in LOOP. */
static bool
-stmt_after_increment (struct loop *loop, struct iv_cand *cand, gimple *stmt)
+stmt_after_increment (class loop *loop, struct iv_cand *cand, gimple *stmt)
{
switch (cand->pos)
{
@@ -972,10 +979,10 @@ contains_abnormal_ssa_name_p (tree expr)
/* Returns the structure describing number of iterations determined from
EXIT of DATA->current_loop, or NULL if something goes wrong. */
-static struct tree_niter_desc *
+static class tree_niter_desc *
niter_for_exit (struct ivopts_data *data, edge exit)
{
- struct tree_niter_desc *desc;
+ class tree_niter_desc *desc;
tree_niter_desc **slot;
if (!data->niters)
@@ -991,7 +998,7 @@ niter_for_exit (struct ivopts_data *data, edge exit)
/* Try to determine number of iterations. We cannot safely work with ssa
names that appear in phi nodes on abnormal edges, so that we do not
create overlapping life ranges for them (PR 27283). */
- desc = XNEW (struct tree_niter_desc);
+ desc = XNEW (class tree_niter_desc);
if (!number_of_iterations_exit (data->current_loop,
exit, desc, true)
|| contains_abnormal_ssa_name_p (desc->niter))
@@ -1011,7 +1018,7 @@ niter_for_exit (struct ivopts_data *data, edge exit)
single dominating exit of DATA->current_loop, or NULL if something
goes wrong. */
-static struct tree_niter_desc *
+static class tree_niter_desc *
niter_for_single_dom_exit (struct ivopts_data *data)
{
edge exit = single_dom_exit (data->current_loop);
@@ -1039,61 +1046,68 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data)
data->vcands.create (20);
data->inv_expr_tab = new hash_table<iv_inv_expr_hasher> (10);
data->name_expansion_cache = NULL;
+ data->base_object_map = NULL;
data->iv_common_cand_tab = new hash_table<iv_common_cand_hasher> (10);
data->iv_common_cands.create (20);
decl_rtl_to_reset.create (20);
gcc_obstack_init (&data->iv_obstack);
}
-/* Returns a memory object to that EXPR points. In case we are able to
- determine that it does not point to any such object, NULL is returned. */
+/* walk_tree callback for determine_base_object. */
static tree
-determine_base_object (tree expr)
+determine_base_object_1 (tree *tp, int *walk_subtrees, void *wdata)
{
- enum tree_code code = TREE_CODE (expr);
- tree base, obj;
-
- /* If this is a pointer casted to any type, we need to determine
- the base object for the pointer; so handle conversions before
- throwing away non-pointer expressions. */
- if (CONVERT_EXPR_P (expr))
- return determine_base_object (TREE_OPERAND (expr, 0));
-
- if (!POINTER_TYPE_P (TREE_TYPE (expr)))
- return NULL_TREE;
-
- switch (code)
+ tree_code code = TREE_CODE (*tp);
+ tree obj = NULL_TREE;
+ if (code == ADDR_EXPR)
{
- case INTEGER_CST:
- return NULL_TREE;
-
- case ADDR_EXPR:
- obj = TREE_OPERAND (expr, 0);
- base = get_base_address (obj);
-
+ tree base = get_base_address (TREE_OPERAND (*tp, 0));
if (!base)
- return expr;
-
- if (TREE_CODE (base) == MEM_REF)
- return determine_base_object (TREE_OPERAND (base, 0));
+ obj = *tp;
+ else if (TREE_CODE (base) != MEM_REF)
+ obj = fold_convert (ptr_type_node, build_fold_addr_expr (base));
+ }
+ else if (code == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*tp)))
+ obj = fold_convert (ptr_type_node, *tp);
- return fold_convert (ptr_type_node,
- build_fold_addr_expr (base));
+ if (!obj)
+ {
+ if (!EXPR_P (*tp))
+ *walk_subtrees = 0;
- case POINTER_PLUS_EXPR:
- return determine_base_object (TREE_OPERAND (expr, 0));
+ return NULL_TREE;
+ }
+ /* Record special node for multiple base objects and stop. */
+ if (*static_cast<tree *> (wdata))
+ {
+ *static_cast<tree *> (wdata) = integer_zero_node;
+ return integer_zero_node;
+ }
+ /* Record the base object and continue looking. */
+ *static_cast<tree *> (wdata) = obj;
+ return NULL_TREE;
+}
- case PLUS_EXPR:
- case MINUS_EXPR:
- /* Pointer addition is done solely using POINTER_PLUS_EXPR. */
- gcc_unreachable ();
+/* Returns a memory object to that EXPR points with caching. Return NULL if we
+ are able to determine that it does not point to any such object; specially
+ return integer_zero_node if EXPR contains multiple base objects. */
- default:
- if (POLY_INT_CST_P (expr))
- return NULL_TREE;
- return fold_convert (ptr_type_node, expr);
+static tree
+determine_base_object (struct ivopts_data *data, tree expr)
+{
+ tree *slot, obj = NULL_TREE;
+ if (data->base_object_map)
+ {
+ if ((slot = data->base_object_map->get(expr)) != NULL)
+ return *slot;
}
+ else
+ data->base_object_map = new hash_map<tree, tree>;
+
+ (void) walk_tree_without_duplicates (&expr, determine_base_object_1, &obj);
+ data->base_object_map->put (expr, obj);
+ return obj;
}
/* Return true if address expression with non-DECL_P operand appears
@@ -1151,7 +1165,7 @@ alloc_iv (struct ivopts_data *data, tree base, tree step,
}
iv->base = base;
- iv->base_object = determine_base_object (base);
+ iv->base_object = determine_base_object (data, base);
iv->step = step;
iv->biv_p = false;
iv->nonlin_use = NULL;
@@ -1242,7 +1256,7 @@ find_bivs (struct ivopts_data *data)
affine_iv iv;
tree step, type, base, stop;
bool found = false;
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
gphi_iterator psi;
for (psi = gsi_start_phis (loop->header); !gsi_end_p (psi); gsi_next (&psi))
@@ -1300,7 +1314,7 @@ mark_bivs (struct ivopts_data *data)
gimple *def;
tree var;
struct iv *iv, *incr_iv;
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
basic_block incr_bb;
gphi_iterator psi;
@@ -1347,7 +1361,7 @@ static bool
find_givs_in_stmt_scev (struct ivopts_data *data, gimple *stmt, affine_iv *iv)
{
tree lhs, stop;
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
iv->base = NULL_TREE;
iv->step = NULL_TREE;
@@ -1411,7 +1425,7 @@ find_givs_in_bb (struct ivopts_data *data, basic_block bb)
static void
find_givs (struct ivopts_data *data)
{
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
basic_block *body = get_loop_body_in_dom_order (loop);
unsigned i;
@@ -1437,7 +1451,7 @@ find_induction_variables (struct ivopts_data *data)
if (dump_file && (dump_flags & TDF_DETAILS))
{
- struct tree_niter_desc *niter = niter_for_single_dom_exit (data);
+ class tree_niter_desc *niter = niter_for_single_dom_exit (data);
if (niter)
{
@@ -1737,8 +1751,8 @@ find_interesting_uses_cond (struct ivopts_data *data, gimple *stmt)
outside of the returned loop. Returns NULL if EXPR is not
even obviously invariant in LOOP. */
-struct loop *
-outermost_invariant_loop_for_expr (struct loop *loop, tree expr)
+class loop *
+outermost_invariant_loop_for_expr (class loop *loop, tree expr)
{
basic_block def_bb;
unsigned i, len;
@@ -1767,7 +1781,7 @@ outermost_invariant_loop_for_expr (struct loop *loop, tree expr)
len = TREE_OPERAND_LENGTH (expr);
for (i = 0; i < len; i++)
{
- struct loop *ivloop;
+ class loop *ivloop;
if (!TREE_OPERAND (expr, i))
continue;
@@ -1785,7 +1799,7 @@ outermost_invariant_loop_for_expr (struct loop *loop, tree expr)
should not be the function body. */
bool
-expr_invariant_in_loop_p (struct loop *loop, tree expr)
+expr_invariant_in_loop_p (class loop *loop, tree expr)
{
basic_block def_bb;
unsigned i, len;
@@ -1978,7 +1992,7 @@ idx_find_step (tree base, tree *idx, void *data)
struct iv *iv;
bool use_overflow_semantics = false;
tree step, iv_base, iv_step, lbound, off;
- struct loop *loop = dta->ivopts_data->current_loop;
+ class loop *loop = dta->ivopts_data->current_loop;
/* If base is a component ref, require that the offset of the reference
be invariant. */
@@ -3136,7 +3150,7 @@ add_candidate_1 (struct ivopts_data *data,
is already nonempty. */
static bool
-allow_ip_end_pos_p (struct loop *loop)
+allow_ip_end_pos_p (class loop *loop)
{
if (!ip_normal_pos (loop))
return true;
@@ -3327,8 +3341,8 @@ static void
record_common_cand (struct ivopts_data *data, tree base,
tree step, struct iv_use *use)
{
- struct iv_common_cand ent;
- struct iv_common_cand **slot;
+ class iv_common_cand ent;
+ class iv_common_cand **slot;
ent.base = base;
ent.step = step;
@@ -3357,10 +3371,10 @@ static int
common_cand_cmp (const void *p1, const void *p2)
{
unsigned n1, n2;
- const struct iv_common_cand *const *const ccand1
- = (const struct iv_common_cand *const *)p1;
- const struct iv_common_cand *const *const ccand2
- = (const struct iv_common_cand *const *)p2;
+ const class iv_common_cand *const *const ccand1
+ = (const class iv_common_cand *const *)p1;
+ const class iv_common_cand *const *const ccand2
+ = (const class iv_common_cand *const *)p2;
n1 = (*ccand1)->uses.length ();
n2 = (*ccand2)->uses.length ();
@@ -3378,7 +3392,7 @@ add_iv_candidate_derived_from_uses (struct ivopts_data *data)
data->iv_common_cands.qsort (common_cand_cmp);
for (i = 0; i < data->iv_common_cands.length (); i++)
{
- struct iv_common_cand *ptr = data->iv_common_cands[i];
+ class iv_common_cand *ptr = data->iv_common_cands[i];
/* Only add IV candidate if it's derived from multiple uses. */
if (ptr->uses.length () <= 1)
@@ -3554,7 +3568,7 @@ alloc_use_cost_map (struct ivopts_data *data)
}
group->n_map_members = size;
- group->cost_map = XCNEWVEC (struct cost_pair, size);
+ group->cost_map = XCNEWVEC (class cost_pair, size);
}
}
@@ -3610,12 +3624,12 @@ found:
/* Gets cost of (GROUP, CAND) pair. */
-static struct cost_pair *
+static class cost_pair *
get_group_iv_cost (struct ivopts_data *data, struct iv_group *group,
struct iv_cand *cand)
{
unsigned i, s;
- struct cost_pair *ret;
+ class cost_pair *ret;
if (!cand)
return NULL;
@@ -3749,7 +3763,7 @@ prepare_decl_rtl (tree *expr_p, int *ws, void *data)
static bool ATTRIBUTE_UNUSED
generic_predict_doloop_p (struct ivopts_data *data)
{
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
/* Call target hook for target dependent checks. */
if (!targetm.predict_doloop_p (loop))
@@ -3764,7 +3778,7 @@ generic_predict_doloop_p (struct ivopts_data *data)
suitable or not. Keep it as simple as possible, feel free to extend it
if you find any multiple exits cases matter. */
edge exit = single_dom_exit (loop);
- struct tree_niter_desc *niter_desc;
+ class tree_niter_desc *niter_desc;
if (!exit || !(niter_desc = niter_for_exit (data, exit)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -3828,7 +3842,7 @@ computation_cost (tree expr, bool speed)
/* Returns variable containing the value of candidate CAND at statement AT. */
static tree
-var_at_stmt (struct loop *loop, struct iv_cand *cand, gimple *stmt)
+var_at_stmt (class loop *loop, struct iv_cand *cand, gimple *stmt)
{
if (stmt_after_increment (loop, cand, stmt))
return cand->var_after;
@@ -3879,9 +3893,9 @@ determine_common_wider_type (tree *a, tree *b)
non-null. Returns false if USE cannot be expressed using CAND. */
static bool
-get_computation_aff_1 (struct loop *loop, gimple *at, struct iv_use *use,
- struct iv_cand *cand, struct aff_tree *aff_inv,
- struct aff_tree *aff_var, widest_int *prat = NULL)
+get_computation_aff_1 (class loop *loop, gimple *at, struct iv_use *use,
+ struct iv_cand *cand, class aff_tree *aff_inv,
+ class aff_tree *aff_var, widest_int *prat = NULL)
{
tree ubase = use->iv->base, ustep = use->iv->step;
tree cbase = cand->iv->base, cstep = cand->iv->step;
@@ -3985,8 +3999,8 @@ get_computation_aff_1 (struct loop *loop, gimple *at, struct iv_use *use,
form into AFF. Returns false if USE cannot be expressed using CAND. */
static bool
-get_computation_aff (struct loop *loop, gimple *at, struct iv_use *use,
- struct iv_cand *cand, struct aff_tree *aff)
+get_computation_aff (class loop *loop, gimple *at, struct iv_use *use,
+ struct iv_cand *cand, class aff_tree *aff)
{
aff_tree aff_var;
@@ -4023,7 +4037,7 @@ get_use_type (struct iv_use *use)
CAND at statement AT in LOOP. The computation is unshared. */
static tree
-get_computation_at (struct loop *loop, gimple *at,
+get_computation_at (class loop *loop, gimple *at,
struct iv_use *use, struct iv_cand *cand)
{
aff_tree aff;
@@ -4805,7 +4819,7 @@ determine_group_iv_cost_address (struct ivopts_data *data,
stores it to VAL. */
static void
-cand_value_at (struct loop *loop, struct iv_cand *cand, gimple *at, tree niter,
+cand_value_at (class loop *loop, struct iv_cand *cand, gimple *at, tree niter,
aff_tree *val)
{
aff_tree step, delta, nit;
@@ -4864,7 +4878,7 @@ iv_period (struct iv *iv)
static enum tree_code
iv_elimination_compare (struct ivopts_data *data, struct iv_use *use)
{
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
basic_block ex_bb;
edge exit;
@@ -4988,10 +5002,10 @@ difference_cannot_overflow_p (struct ivopts_data *data, tree base, tree offset)
static bool
iv_elimination_compare_lt (struct ivopts_data *data,
struct iv_cand *cand, enum tree_code *comp_p,
- struct tree_niter_desc *niter)
+ class tree_niter_desc *niter)
{
tree cand_type, a, b, mbz, nit_type = TREE_TYPE (niter->niter), offset;
- struct aff_tree nit, tmpa, tmpb;
+ class aff_tree nit, tmpa, tmpb;
enum tree_code comp;
HOST_WIDE_INT step;
@@ -5090,9 +5104,9 @@ may_eliminate_iv (struct ivopts_data *data,
basic_block ex_bb;
edge exit;
tree period;
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
aff_tree bnd;
- struct tree_niter_desc *desc = NULL;
+ class tree_niter_desc *desc = NULL;
if (TREE_CODE (cand->iv->step) != INTEGER_CST)
return false;
@@ -5700,7 +5714,7 @@ determine_set_costs (struct ivopts_data *data)
gphi *phi;
gphi_iterator psi;
tree op;
- struct loop *loop = data->current_loop;
+ class loop *loop = data->current_loop;
bitmap_iterator bi;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -5757,7 +5771,7 @@ determine_set_costs (struct ivopts_data *data)
/* Returns true if A is a cheaper cost pair than B. */
static bool
-cheaper_cost_pair (struct cost_pair *a, struct cost_pair *b)
+cheaper_cost_pair (class cost_pair *a, class cost_pair *b)
{
if (!a)
return false;
@@ -5782,7 +5796,7 @@ cheaper_cost_pair (struct cost_pair *a, struct cost_pair *b)
for more expensive, equal and cheaper respectively. */
static int
-compare_cost_pair (struct cost_pair *a, struct cost_pair *b)
+compare_cost_pair (class cost_pair *a, class cost_pair *b)
{
if (cheaper_cost_pair (a, b))
return -1;
@@ -5794,8 +5808,8 @@ compare_cost_pair (struct cost_pair *a, struct cost_pair *b)
/* Returns candidate by that USE is expressed in IVS. */
-static struct cost_pair *
-iv_ca_cand_for_group (struct iv_ca *ivs, struct iv_group *group)
+static class cost_pair *
+iv_ca_cand_for_group (class iv_ca *ivs, struct iv_group *group)
{
return ivs->cand_for_group[group->id];
}
@@ -5803,7 +5817,7 @@ iv_ca_cand_for_group (struct iv_ca *ivs, struct iv_group *group)
/* Computes the cost field of IVS structure. */
static void
-iv_ca_recount_cost (struct ivopts_data *data, struct iv_ca *ivs)
+iv_ca_recount_cost (struct ivopts_data *data, class iv_ca *ivs)
{
comp_cost cost = ivs->cand_use_cost;
@@ -5816,7 +5830,7 @@ iv_ca_recount_cost (struct ivopts_data *data, struct iv_ca *ivs)
and IVS. */
static void
-iv_ca_set_remove_invs (struct iv_ca *ivs, bitmap invs, unsigned *n_inv_uses)
+iv_ca_set_remove_invs (class iv_ca *ivs, bitmap invs, unsigned *n_inv_uses)
{
bitmap_iterator bi;
unsigned iid;
@@ -5836,11 +5850,11 @@ iv_ca_set_remove_invs (struct iv_ca *ivs, bitmap invs, unsigned *n_inv_uses)
/* Set USE not to be expressed by any candidate in IVS. */
static void
-iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs,
+iv_ca_set_no_cp (struct ivopts_data *data, class iv_ca *ivs,
struct iv_group *group)
{
unsigned gid = group->id, cid;
- struct cost_pair *cp;
+ class cost_pair *cp;
cp = ivs->cand_for_group[gid];
if (!cp)
@@ -5870,7 +5884,7 @@ iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs,
IVS. */
static void
-iv_ca_set_add_invs (struct iv_ca *ivs, bitmap invs, unsigned *n_inv_uses)
+iv_ca_set_add_invs (class iv_ca *ivs, bitmap invs, unsigned *n_inv_uses)
{
bitmap_iterator bi;
unsigned iid;
@@ -5890,8 +5904,8 @@ iv_ca_set_add_invs (struct iv_ca *ivs, bitmap invs, unsigned *n_inv_uses)
/* Set cost pair for GROUP in set IVS to CP. */
static void
-iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs,
- struct iv_group *group, struct cost_pair *cp)
+iv_ca_set_cp (struct ivopts_data *data, class iv_ca *ivs,
+ struct iv_group *group, class cost_pair *cp)
{
unsigned gid = group->id, cid;
@@ -5929,10 +5943,10 @@ iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs,
set IVS don't give any result. */
static void
-iv_ca_add_group (struct ivopts_data *data, struct iv_ca *ivs,
+iv_ca_add_group (struct ivopts_data *data, class iv_ca *ivs,
struct iv_group *group)
{
- struct cost_pair *best_cp = NULL, *cp;
+ class cost_pair *best_cp = NULL, *cp;
bitmap_iterator bi;
unsigned i;
struct iv_cand *cand;
@@ -5966,7 +5980,7 @@ iv_ca_add_group (struct ivopts_data *data, struct iv_ca *ivs,
/* Get cost for assignment IVS. */
static comp_cost
-iv_ca_cost (struct iv_ca *ivs)
+iv_ca_cost (class iv_ca *ivs)
{
/* This was a conditional expression but it triggered a bug in
Sun C 5.5. */
@@ -5981,9 +5995,9 @@ iv_ca_cost (struct iv_ca *ivs)
respectively. */
static int
-iv_ca_compare_deps (struct ivopts_data *data, struct iv_ca *ivs,
- struct iv_group *group, struct cost_pair *old_cp,
- struct cost_pair *new_cp)
+iv_ca_compare_deps (struct ivopts_data *data, class iv_ca *ivs,
+ struct iv_group *group, class cost_pair *old_cp,
+ class cost_pair *new_cp)
{
gcc_assert (old_cp && new_cp && old_cp != new_cp);
unsigned old_n_invs = ivs->n_invs;
@@ -5998,8 +6012,8 @@ iv_ca_compare_deps (struct ivopts_data *data, struct iv_ca *ivs,
it before NEXT. */
static struct iv_ca_delta *
-iv_ca_delta_add (struct iv_group *group, struct cost_pair *old_cp,
- struct cost_pair *new_cp, struct iv_ca_delta *next)
+iv_ca_delta_add (struct iv_group *group, class cost_pair *old_cp,
+ class cost_pair *new_cp, struct iv_ca_delta *next)
{
struct iv_ca_delta *change = XNEW (struct iv_ca_delta);
@@ -6055,10 +6069,10 @@ iv_ca_delta_reverse (struct iv_ca_delta *delta)
reverted instead. */
static void
-iv_ca_delta_commit (struct ivopts_data *data, struct iv_ca *ivs,
+iv_ca_delta_commit (struct ivopts_data *data, class iv_ca *ivs,
struct iv_ca_delta *delta, bool forward)
{
- struct cost_pair *from, *to;
+ class cost_pair *from, *to;
struct iv_ca_delta *act;
if (!forward)
@@ -6079,7 +6093,7 @@ iv_ca_delta_commit (struct ivopts_data *data, struct iv_ca *ivs,
/* Returns true if CAND is used in IVS. */
static bool
-iv_ca_cand_used_p (struct iv_ca *ivs, struct iv_cand *cand)
+iv_ca_cand_used_p (class iv_ca *ivs, struct iv_cand *cand)
{
return ivs->n_cand_uses[cand->id] > 0;
}
@@ -6087,7 +6101,7 @@ iv_ca_cand_used_p (struct iv_ca *ivs, struct iv_cand *cand)
/* Returns number of induction variable candidates in the set IVS. */
static unsigned
-iv_ca_n_cands (struct iv_ca *ivs)
+iv_ca_n_cands (class iv_ca *ivs)
{
return ivs->n_cands;
}
@@ -6110,14 +6124,14 @@ iv_ca_delta_free (struct iv_ca_delta **delta)
/* Allocates new iv candidates assignment. */
-static struct iv_ca *
+static class iv_ca *
iv_ca_new (struct ivopts_data *data)
{
- struct iv_ca *nw = XNEW (struct iv_ca);
+ class iv_ca *nw = XNEW (class iv_ca);
nw->upto = 0;
nw->bad_groups = 0;
- nw->cand_for_group = XCNEWVEC (struct cost_pair *,
+ nw->cand_for_group = XCNEWVEC (class cost_pair *,
data->vgroups.length ());
nw->n_cand_uses = XCNEWVEC (unsigned, data->vcands.length ());
nw->cands = BITMAP_ALLOC (NULL);
@@ -6135,7 +6149,7 @@ iv_ca_new (struct ivopts_data *data)
/* Free memory occupied by the set IVS. */
static void
-iv_ca_free (struct iv_ca **ivs)
+iv_ca_free (class iv_ca **ivs)
{
free ((*ivs)->cand_for_group);
free ((*ivs)->n_cand_uses);
@@ -6149,7 +6163,7 @@ iv_ca_free (struct iv_ca **ivs)
/* Dumps IVS to FILE. */
static void
-iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
+iv_ca_dump (struct ivopts_data *data, FILE *file, class iv_ca *ivs)
{
unsigned i;
comp_cost cost = iv_ca_cost (ivs);
@@ -6164,7 +6178,7 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
for (i = 0; i < ivs->upto; i++)
{
struct iv_group *group = data->vgroups[i];
- struct cost_pair *cp = iv_ca_cand_for_group (ivs, group);
+ class cost_pair *cp = iv_ca_cand_for_group (ivs, group);
if (cp)
fprintf (file, " group:%d --> iv_cand:%d, cost=("
"%" PRId64 ",%d)\n", group->id, cp->cand->id,
@@ -6200,14 +6214,14 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
the function will try to find a solution with mimimal iv candidates. */
static comp_cost
-iv_ca_extend (struct ivopts_data *data, struct iv_ca *ivs,
+iv_ca_extend (struct ivopts_data *data, class iv_ca *ivs,
struct iv_cand *cand, struct iv_ca_delta **delta,
unsigned *n_ivs, bool min_ncand)
{
unsigned i;
comp_cost cost;
struct iv_group *group;
- struct cost_pair *old_cp, *new_cp;
+ class cost_pair *old_cp, *new_cp;
*delta = NULL;
for (i = 0; i < ivs->upto; i++)
@@ -6253,13 +6267,13 @@ iv_ca_extend (struct ivopts_data *data, struct iv_ca *ivs,
the candidate with which we start narrowing. */
static comp_cost
-iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
+iv_ca_narrow (struct ivopts_data *data, class iv_ca *ivs,
struct iv_cand *cand, struct iv_cand *start,
struct iv_ca_delta **delta)
{
unsigned i, ci;
struct iv_group *group;
- struct cost_pair *old_cp, *new_cp, *cp;
+ class cost_pair *old_cp, *new_cp, *cp;
bitmap_iterator bi;
struct iv_cand *cnd;
comp_cost cost, best_cost, acost;
@@ -6347,7 +6361,7 @@ iv_ca_narrow (struct ivopts_data *data, struct iv_ca *ivs,
differences in DELTA. */
static comp_cost
-iv_ca_prune (struct ivopts_data *data, struct iv_ca *ivs,
+iv_ca_prune (struct ivopts_data *data, class iv_ca *ivs,
struct iv_cand *except_cand, struct iv_ca_delta **delta)
{
bitmap_iterator bi;
@@ -6396,13 +6410,13 @@ iv_ca_prune (struct ivopts_data *data, struct iv_ca *ivs,
cheaper local cost for GROUP than BEST_CP. Return pointer to
the corresponding cost_pair, otherwise just return BEST_CP. */
-static struct cost_pair*
+static class cost_pair*
cheaper_cost_with_cand (struct ivopts_data *data, struct iv_group *group,
unsigned int cand_idx, struct iv_cand *old_cand,
- struct cost_pair *best_cp)
+ class cost_pair *best_cp)
{
struct iv_cand *cand;
- struct cost_pair *cp;
+ class cost_pair *cp;
gcc_assert (old_cand != NULL && best_cp != NULL);
if (cand_idx == old_cand->id)
@@ -6424,7 +6438,7 @@ cheaper_cost_with_cand (struct ivopts_data *data, struct iv_group *group,
candidate replacement in list DELTA. */
static comp_cost
-iv_ca_replace (struct ivopts_data *data, struct iv_ca *ivs,
+iv_ca_replace (struct ivopts_data *data, class iv_ca *ivs,
struct iv_ca_delta **delta)
{
bitmap_iterator bi, bj;
@@ -6432,7 +6446,7 @@ iv_ca_replace (struct ivopts_data *data, struct iv_ca *ivs,
struct iv_cand *cand;
comp_cost orig_cost, acost;
struct iv_ca_delta *act_delta, *tmp_delta;
- struct cost_pair *old_cp, *best_cp = NULL;
+ class cost_pair *old_cp, *best_cp = NULL;
*delta = NULL;
orig_cost = iv_ca_cost (ivs);
@@ -6499,7 +6513,7 @@ iv_ca_replace (struct ivopts_data *data, struct iv_ca *ivs,
based on any memory object. */
static bool
-try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
+try_add_cand_for (struct ivopts_data *data, class iv_ca *ivs,
struct iv_group *group, bool originalp)
{
comp_cost best_cost, act_cost;
@@ -6507,7 +6521,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
bitmap_iterator bi;
struct iv_cand *cand;
struct iv_ca_delta *best_delta = NULL, *act_delta;
- struct cost_pair *cp;
+ class cost_pair *cp;
iv_ca_add_group (data, ivs, group);
best_cost = iv_ca_cost (ivs);
@@ -6611,11 +6625,11 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
/* Finds an initial assignment of candidates to uses. */
-static struct iv_ca *
+static class iv_ca *
get_initial_solution (struct ivopts_data *data, bool originalp)
{
unsigned i;
- struct iv_ca *ivs = iv_ca_new (data);
+ class iv_ca *ivs = iv_ca_new (data);
for (i = 0; i < data->vgroups.length (); i++)
if (!try_add_cand_for (data, ivs, data->vgroups[i], originalp))
@@ -6633,7 +6647,7 @@ get_initial_solution (struct ivopts_data *data, bool originalp)
static bool
try_improve_iv_set (struct ivopts_data *data,
- struct iv_ca *ivs, bool *try_replace_p)
+ class iv_ca *ivs, bool *try_replace_p)
{
unsigned i, n_ivs;
comp_cost acost, best_cost = iv_ca_cost (ivs);
@@ -6704,10 +6718,10 @@ try_improve_iv_set (struct ivopts_data *data,
greedy heuristic -- we try to replace at most one candidate in the selected
solution and remove the unused ivs while this improves the cost. */
-static struct iv_ca *
+static class iv_ca *
find_optimal_iv_set_1 (struct ivopts_data *data, bool originalp)
{
- struct iv_ca *set;
+ class iv_ca *set;
bool try_replace_p = true;
/* Get the initial solution. */
@@ -6745,12 +6759,12 @@ find_optimal_iv_set_1 (struct ivopts_data *data, bool originalp)
return set;
}
-static struct iv_ca *
+static class iv_ca *
find_optimal_iv_set (struct ivopts_data *data)
{
unsigned i;
comp_cost cost, origcost;
- struct iv_ca *set, *origset;
+ class iv_ca *set, *origset;
/* Determine the cost based on a strategy that starts with original IVs,
and try again using a strategy that prefers candidates not based
@@ -6846,7 +6860,7 @@ create_new_iv (struct ivopts_data *data, struct iv_cand *cand)
/* Creates new induction variables described in SET. */
static void
-create_new_ivs (struct ivopts_data *data, struct iv_ca *set)
+create_new_ivs (struct ivopts_data *data, class iv_ca *set)
{
unsigned i;
struct iv_cand *cand;
@@ -7200,7 +7214,7 @@ rewrite_use_compare (struct ivopts_data *data,
gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
enum tree_code compare;
struct iv_group *group = data->vgroups[use->group_id];
- struct cost_pair *cp = get_group_iv_cost (data, group, cand);
+ class cost_pair *cp = get_group_iv_cost (data, group, cand);
bound = cp->value;
if (bound)
@@ -7412,7 +7426,7 @@ remove_unused_ivs (struct ivopts_data *data, bitmap toremove)
}
}
-/* Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
+/* Frees memory occupied by class tree_niter_desc in *VALUE. Callback
for hash_map::traverse. */
bool
@@ -7523,6 +7537,8 @@ tree_ssa_iv_optimize_finalize (struct ivopts_data *data)
delete data->inv_expr_tab;
data->inv_expr_tab = NULL;
free_affine_expand_cache (&data->name_expansion_cache);
+ if (data->base_object_map)
+ delete data->base_object_map;
delete data->iv_common_cand_tab;
data->iv_common_cand_tab = NULL;
data->iv_common_cands.release ();
@@ -7595,11 +7611,11 @@ determine_scaling_factor (struct ivopts_data *data, basic_block *body)
/* Optimizes the LOOP. Returns true if anything changed. */
static bool
-tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop,
+tree_ssa_iv_optimize_loop (struct ivopts_data *data, class loop *loop,
bitmap toremove)
{
bool changed = false;
- struct iv_ca *iv_ca;
+ class iv_ca *iv_ca;
edge exit = single_dom_exit (loop);
basic_block *body;
@@ -7685,7 +7701,7 @@ finish:
void
tree_ssa_iv_optimize (void)
{
- struct loop *loop;
+ class loop *loop;
struct ivopts_data data;
auto_bitmap toremove;
diff --git a/gcc/tree-ssa-loop-ivopts.h b/gcc/tree-ssa-loop-ivopts.h
index 6f21e63..1ad4a77 100644
--- a/gcc/tree-ssa-loop-ivopts.h
+++ b/gcc/tree-ssa-loop-ivopts.h
@@ -20,18 +20,18 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_SSA_LOOP_IVOPTS_H
#define GCC_TREE_SSA_LOOP_IVOPTS_H
-extern edge single_dom_exit (struct loop *);
+extern edge single_dom_exit (class loop *);
extern void dump_iv (FILE *, struct iv *);
extern void dump_use (FILE *, struct iv_use *);
extern void dump_uses (FILE *, struct ivopts_data *);
extern void dump_cand (FILE *, struct iv_cand *);
extern bool contains_abnormal_ssa_name_p (tree);
-extern struct loop *outermost_invariant_loop_for_expr (struct loop *, tree);
-extern bool expr_invariant_in_loop_p (struct loop *, tree);
+extern class loop *outermost_invariant_loop_for_expr (class loop *, tree);
+extern bool expr_invariant_in_loop_p (class loop *, tree);
extern tree strip_offset (tree, poly_uint64_pod *);
bool may_be_nonaddressable_p (tree expr);
void tree_ssa_iv_optimize (void);
-void create_canonical_iv (struct loop *, edge, tree,
+void create_canonical_iv (class loop *, edge, tree,
tree * = NULL, tree * = NULL);
#endif /* GCC_TREE_SSA_LOOP_IVOPTS_H */
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index 7db4f09..6a1bbaa 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -58,7 +58,7 @@ static bitmap_obstack loop_renamer_obstack;
VAR_AFTER (unless they are NULL). */
void
-create_iv (tree base, tree step, tree var, struct loop *loop,
+create_iv (tree base, tree step, tree var, class loop *loop,
gimple_stmt_iterator *incr_pos, bool after,
tree *var_before, tree *var_after)
{
@@ -126,10 +126,23 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
gsi_insert_seq_on_edge_immediate (pe, stmts);
stmt = gimple_build_assign (va, incr_op, vb, step);
+ /* Prevent the increment from inheriting a bogus location if it is not put
+ immediately after a statement whose location is known. */
if (after)
- gsi_insert_after (incr_pos, stmt, GSI_NEW_STMT);
+ {
+ if (gsi_end_p (*incr_pos))
+ {
+ edge e = single_succ_edge (gsi_bb (*incr_pos));
+ gimple_set_location (stmt, e->goto_locus);
+ }
+ gsi_insert_after (incr_pos, stmt, GSI_NEW_STMT);
+ }
else
- gsi_insert_before (incr_pos, stmt, GSI_NEW_STMT);
+ {
+ if (!gsi_end_p (*incr_pos))
+ gimple_set_location (stmt, gimple_location (gsi_stmt (*incr_pos)));
+ gsi_insert_before (incr_pos, stmt, GSI_NEW_STMT);
+ }
initial = force_gimple_operand (base, &stmts, true, var);
if (stmts)
@@ -143,8 +156,8 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
/* Return the innermost superloop LOOP of USE_LOOP that is a superloop of
both DEF_LOOP and USE_LOOP. */
-static inline struct loop *
-find_sibling_superloop (struct loop *use_loop, struct loop *def_loop)
+static inline class loop *
+find_sibling_superloop (class loop *use_loop, class loop *def_loop)
{
unsigned ud = loop_depth (use_loop);
unsigned dd = loop_depth (def_loop);
@@ -183,7 +196,7 @@ compute_live_loop_exits (bitmap live_exits, bitmap use_blocks,
{
unsigned i;
bitmap_iterator bi;
- struct loop *def_loop = def_bb->loop_father;
+ class loop *def_loop = def_bb->loop_father;
unsigned def_loop_depth = loop_depth (def_loop);
bitmap def_loop_exits;
@@ -195,7 +208,7 @@ compute_live_loop_exits (bitmap live_exits, bitmap use_blocks,
EXECUTE_IF_SET_IN_BITMAP (use_blocks, 0, i, bi)
{
basic_block use_bb = BASIC_BLOCK_FOR_FN (cfun, i);
- struct loop *use_loop = use_bb->loop_father;
+ class loop *use_loop = use_bb->loop_father;
gcc_checking_assert (def_loop != use_loop
&& ! flow_loop_nested_p (def_loop, use_loop));
if (! flow_loop_nested_p (use_loop, def_loop))
@@ -221,7 +234,7 @@ compute_live_loop_exits (bitmap live_exits, bitmap use_blocks,
FOR_EACH_EDGE (e, ei, bb->preds)
{
basic_block pred = e->src;
- struct loop *pred_loop = pred->loop_father;
+ class loop *pred_loop = pred->loop_father;
unsigned pred_loop_depth = loop_depth (pred_loop);
bool pred_visited;
@@ -255,7 +268,7 @@ compute_live_loop_exits (bitmap live_exits, bitmap use_blocks,
}
def_loop_exits = BITMAP_ALLOC (&loop_renamer_obstack);
- for (struct loop *loop = def_loop;
+ for (class loop *loop = def_loop;
loop != current_loops->tree_root;
loop = loop_outer (loop))
bitmap_ior_into (def_loop_exits, loop_exits[loop->num]);
@@ -280,7 +293,7 @@ add_exit_phi (basic_block exit, tree var)
basic_block def_bb = gimple_bb (def_stmt);
FOR_EACH_EDGE (e, ei, exit->preds)
{
- struct loop *aloop = find_common_loop (def_bb->loop_father,
+ class loop *aloop = find_common_loop (def_bb->loop_father,
e->src->loop_father);
if (!flow_bb_inside_loop_p (aloop, e->dest))
break;
@@ -344,7 +357,7 @@ add_exit_phis (bitmap names_to_rename, bitmap *use_blocks, bitmap *loop_exits)
static void
get_loops_exits (bitmap *loop_exits)
{
- struct loop *loop;
+ class loop *loop;
unsigned j;
edge e;
@@ -370,7 +383,7 @@ find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks,
{
unsigned ver;
basic_block def_bb;
- struct loop *def_loop;
+ class loop *def_loop;
if (TREE_CODE (use) != SSA_NAME)
return;
@@ -519,7 +532,7 @@ find_uses_to_rename_def (tree def, bitmap *use_blocks, bitmap need_phis)
USE_BLOCKS. Record the SSA names that will need exit PHIs in NEED_PHIS. */
static void
-find_uses_to_rename_in_loop (struct loop *loop, bitmap *use_blocks,
+find_uses_to_rename_in_loop (class loop *loop, bitmap *use_blocks,
bitmap need_phis, int use_flags)
{
bool do_virtuals = (use_flags & SSA_OP_VIRTUAL_USES) != 0;
@@ -611,7 +624,7 @@ find_uses_to_rename_in_loop (struct loop *loop, bitmap *use_blocks,
void
rewrite_into_loop_closed_ssa_1 (bitmap changed_bbs, unsigned update_flag,
- int use_flags, struct loop *loop)
+ int use_flags, class loop *loop)
{
bitmap *use_blocks;
bitmap names_to_rename;
@@ -685,7 +698,7 @@ rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag)
form. */
void
-rewrite_virtuals_into_loop_closed_ssa (struct loop *loop)
+rewrite_virtuals_into_loop_closed_ssa (class loop *loop)
{
rewrite_into_loop_closed_ssa_1 (NULL, 0, SSA_OP_VIRTUAL_USES, loop);
}
@@ -741,7 +754,7 @@ check_loop_closed_ssa_bb (basic_block bb)
if LOOP is NULL, otherwise, only LOOP is checked. */
DEBUG_FUNCTION void
-verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop)
+verify_loop_closed_ssa (bool verify_ssa_p, class loop *loop)
{
if (number_of_loops (cfun) <= 1)
return;
@@ -817,7 +830,7 @@ split_loop_exit_edge (edge exit, bool copy_constants_p)
variables incremented at the end of the LOOP. */
basic_block
-ip_end_pos (struct loop *loop)
+ip_end_pos (class loop *loop)
{
return loop->latch;
}
@@ -826,7 +839,7 @@ ip_end_pos (struct loop *loop)
variables incremented just before exit condition of a LOOP. */
basic_block
-ip_normal_pos (struct loop *loop)
+ip_normal_pos (class loop *loop)
{
gimple *last;
basic_block bb;
@@ -857,7 +870,7 @@ ip_normal_pos (struct loop *loop)
the increment should be inserted after *BSI. */
void
-standard_iv_increment_position (struct loop *loop, gimple_stmt_iterator *bsi,
+standard_iv_increment_position (class loop *loop, gimple_stmt_iterator *bsi,
bool *insert_after)
{
basic_block bb = ip_normal_pos (loop), latch = ip_end_pos (loop);
@@ -905,7 +918,7 @@ copy_phi_node_args (unsigned first_new_block)
after the loop has been duplicated. */
bool
-gimple_duplicate_loop_to_header_edge (struct loop *loop, edge e,
+gimple_duplicate_loop_to_header_edge (class loop *loop, edge e,
unsigned int ndupl, sbitmap wont_exit,
edge orig, vec<edge> *to_remove,
int flags)
@@ -937,8 +950,8 @@ gimple_duplicate_loop_to_header_edge (struct loop *loop, edge e,
of iterations of the loop is returned in NITER. */
bool
-can_unroll_loop_p (struct loop *loop, unsigned factor,
- struct tree_niter_desc *niter)
+can_unroll_loop_p (class loop *loop, unsigned factor,
+ class tree_niter_desc *niter)
{
edge exit;
@@ -984,7 +997,7 @@ can_unroll_loop_p (struct loop *loop, unsigned factor,
how the exit from the unrolled loop should be controlled. */
static void
-determine_exit_conditions (struct loop *loop, struct tree_niter_desc *desc,
+determine_exit_conditions (class loop *loop, class tree_niter_desc *desc,
unsigned factor, tree *enter_cond,
tree *exit_base, tree *exit_step,
enum tree_code *exit_cmp, tree *exit_bound)
@@ -1093,7 +1106,7 @@ determine_exit_conditions (struct loop *loop, struct tree_niter_desc *desc,
dominated by BB by NUM/DEN. */
static void
-scale_dominated_blocks_in_loop (struct loop *loop, basic_block bb,
+scale_dominated_blocks_in_loop (class loop *loop, basic_block bb,
profile_count num, profile_count den)
{
basic_block son;
@@ -1115,7 +1128,7 @@ scale_dominated_blocks_in_loop (struct loop *loop, basic_block bb,
/* Return estimated niter for LOOP after unrolling by FACTOR times. */
gcov_type
-niter_for_unrolled_loop (struct loop *loop, unsigned factor)
+niter_for_unrolled_loop (class loop *loop, unsigned factor)
{
gcc_assert (factor != 0);
bool profile_p = false;
@@ -1212,8 +1225,8 @@ niter_for_unrolled_loop (struct loop *loop, unsigned factor)
#define PROB_UNROLLED_LOOP_ENTERED 90
void
-tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
- edge exit, struct tree_niter_desc *desc,
+tree_transform_and_unroll_loop (class loop *loop, unsigned factor,
+ edge exit, class tree_niter_desc *desc,
transform_callback transform,
void *data)
{
@@ -1224,7 +1237,7 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
gphi *phi_old_loop, *phi_new_loop, *phi_rest;
gphi_iterator psi_old_loop, psi_new_loop;
tree init, next, new_init;
- struct loop *new_loop;
+ class loop *new_loop;
basic_block rest, exit_bb;
edge old_entry, new_entry, old_latch, precond_edge, new_exit;
edge new_nonexit, e;
@@ -1422,8 +1435,8 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
of the arguments is the same as for tree_transform_and_unroll_loop. */
void
-tree_unroll_loop (struct loop *loop, unsigned factor,
- edge exit, struct tree_niter_desc *desc)
+tree_unroll_loop (class loop *loop, unsigned factor,
+ edge exit, class tree_niter_desc *desc)
{
tree_transform_and_unroll_loop (loop, factor, exit, desc,
NULL, NULL);
@@ -1505,7 +1518,7 @@ rewrite_all_phi_nodes_with_iv (loop_p loop, tree main_iv)
created. */
tree
-canonicalize_loop_ivs (struct loop *loop, tree *nit, bool bump_in_latch)
+canonicalize_loop_ivs (class loop *loop, tree *nit, bool bump_in_latch)
{
unsigned precision = TYPE_PRECISION (TREE_TYPE (*nit));
unsigned original_precision = precision;
diff --git a/gcc/tree-ssa-loop-manip.h b/gcc/tree-ssa-loop-manip.h
index 0020659..8263a67 100644
--- a/gcc/tree-ssa-loop-manip.h
+++ b/gcc/tree-ssa-loop-manip.h
@@ -20,41 +20,41 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_SSA_LOOP_MANIP_H
#define GCC_TREE_SSA_LOOP_MANIP_H
-typedef void (*transform_callback)(struct loop *, void *);
+typedef void (*transform_callback)(class loop *, void *);
-extern void create_iv (tree, tree, tree, struct loop *, gimple_stmt_iterator *,
+extern void create_iv (tree, tree, tree, class loop *, gimple_stmt_iterator *,
bool, tree *, tree *);
extern void rewrite_into_loop_closed_ssa_1 (bitmap, unsigned, int,
- struct loop *);
+ class loop *);
extern void rewrite_into_loop_closed_ssa (bitmap, unsigned);
-extern void rewrite_virtuals_into_loop_closed_ssa (struct loop *);
-extern void verify_loop_closed_ssa (bool, struct loop * = NULL);
+extern void rewrite_virtuals_into_loop_closed_ssa (class loop *);
+extern void verify_loop_closed_ssa (bool, class loop * = NULL);
static inline void
-checking_verify_loop_closed_ssa (bool verify_ssa_p, struct loop *loop = NULL)
+checking_verify_loop_closed_ssa (bool verify_ssa_p, class loop *loop = NULL)
{
if (flag_checking)
verify_loop_closed_ssa (verify_ssa_p, loop);
}
extern basic_block split_loop_exit_edge (edge, bool = false);
-extern basic_block ip_end_pos (struct loop *);
-extern basic_block ip_normal_pos (struct loop *);
-extern void standard_iv_increment_position (struct loop *,
+extern basic_block ip_end_pos (class loop *);
+extern basic_block ip_normal_pos (class loop *);
+extern void standard_iv_increment_position (class loop *,
gimple_stmt_iterator *, bool *);
-extern bool gimple_duplicate_loop_to_header_edge (struct loop *, edge,
+extern bool gimple_duplicate_loop_to_header_edge (class loop *, edge,
unsigned int, sbitmap,
edge, vec<edge> *,
int);
-extern bool can_unroll_loop_p (struct loop *loop, unsigned factor,
- struct tree_niter_desc *niter);
-extern gcov_type niter_for_unrolled_loop (struct loop *, unsigned);
-extern void tree_transform_and_unroll_loop (struct loop *, unsigned,
- edge, struct tree_niter_desc *,
+extern bool can_unroll_loop_p (class loop *loop, unsigned factor,
+ class tree_niter_desc *niter);
+extern gcov_type niter_for_unrolled_loop (class loop *, unsigned);
+extern void tree_transform_and_unroll_loop (class loop *, unsigned,
+ edge, class tree_niter_desc *,
transform_callback, void *);
-extern void tree_unroll_loop (struct loop *, unsigned,
- edge, struct tree_niter_desc *);
-extern tree canonicalize_loop_ivs (struct loop *, tree *, bool);
+extern void tree_unroll_loop (class loop *, unsigned,
+ edge, class tree_niter_desc *);
+extern tree canonicalize_loop_ivs (class loop *, tree *, bool);
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index f513859..cd2ced3 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -65,7 +65,7 @@ struct bounds
static bool number_of_iterations_popcount (loop_p loop, edge exit,
enum tree_code code,
- struct tree_niter_desc *niter);
+ class tree_niter_desc *niter);
/* Splits expression EXPR to a variable part VAR and constant OFFSET. */
@@ -346,7 +346,7 @@ end:
in TYPE to MIN and MAX. */
static void
-determine_value_range (struct loop *loop, tree type, tree var, mpz_t off,
+determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
mpz_t min, mpz_t max)
{
int cnt = 0;
@@ -704,7 +704,7 @@ end:
comparisons before the loop (usually created by loop header copying). */
static void
-bound_difference (struct loop *loop, tree x, tree y, bounds *bnds)
+bound_difference (class loop *loop, tree x, tree y, bounds *bnds)
{
tree type = TREE_TYPE (x);
tree varx, vary;
@@ -964,8 +964,8 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
bounds on the difference FINAL - IV->base. */
static bool
-number_of_iterations_ne (struct loop *loop, tree type, affine_iv *iv,
- tree final, struct tree_niter_desc *niter,
+number_of_iterations_ne (class loop *loop, tree type, affine_iv *iv,
+ tree final, class tree_niter_desc *niter,
bool exit_must_be_taken, bounds *bnds)
{
tree niter_type = unsigned_type_for (type);
@@ -1149,7 +1149,7 @@ number_of_iterations_ne (struct loop *loop, tree type, affine_iv *iv,
static bool
number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1,
- struct tree_niter_desc *niter,
+ class tree_niter_desc *niter,
tree *delta, tree step,
bool exit_must_be_taken, bounds *bnds)
{
@@ -1268,7 +1268,7 @@ end:
static bool
assert_no_overflow_lt (tree type, affine_iv *iv0, affine_iv *iv1,
- struct tree_niter_desc *niter, tree step)
+ class tree_niter_desc *niter, tree step)
{
tree bound, d, assumption, diff;
tree niter_type = TREE_TYPE (step);
@@ -1337,7 +1337,7 @@ assert_no_overflow_lt (tree type, affine_iv *iv0, affine_iv *iv1,
static void
assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1,
- struct tree_niter_desc *niter, bounds *bnds)
+ class tree_niter_desc *niter, bounds *bnds)
{
tree assumption = boolean_true_node, bound, diff;
tree mbz, mbzl, mbzr, type1;
@@ -1463,8 +1463,8 @@ assert_loop_rolls_lt (tree type, affine_iv *iv0, affine_iv *iv1,
that the exit must be taken eventually. */
static bool
-number_of_iterations_lt (struct loop *loop, tree type, affine_iv *iv0,
- affine_iv *iv1, struct tree_niter_desc *niter,
+number_of_iterations_lt (class loop *loop, tree type, affine_iv *iv0,
+ affine_iv *iv1, class tree_niter_desc *niter,
bool exit_must_be_taken, bounds *bnds)
{
tree niter_type = unsigned_type_for (type);
@@ -1576,8 +1576,8 @@ number_of_iterations_lt (struct loop *loop, tree type, affine_iv *iv0,
is the case). BNDS bounds the difference IV1->base - IV0->base. */
static bool
-number_of_iterations_le (struct loop *loop, tree type, affine_iv *iv0,
- affine_iv *iv1, struct tree_niter_desc *niter,
+number_of_iterations_le (class loop *loop, tree type, affine_iv *iv0,
+ affine_iv *iv1, class tree_niter_desc *niter,
bool exit_must_be_taken, bounds *bnds)
{
tree assumption;
@@ -1721,14 +1721,14 @@ adjust_cond_for_loop_until_wrap (tree type, affine_iv *iv0, tree_code *code,
if EVERY_ITERATION is true, we know the test is executed on every iteration.
The results (number of iterations and assumptions as described in
- comments at struct tree_niter_desc in tree-ssa-loop.h) are stored to NITER.
+ comments at class tree_niter_desc in tree-ssa-loop.h) are stored to NITER.
Returns false if it fails to determine number of iterations, true if it
was determined (possibly with some assumptions). */
static bool
-number_of_iterations_cond (struct loop *loop,
+number_of_iterations_cond (class loop *loop,
tree type, affine_iv *iv0, enum tree_code code,
- affine_iv *iv1, struct tree_niter_desc *niter,
+ affine_iv *iv1, class tree_niter_desc *niter,
bool only_exit, bool every_iteration)
{
bool exit_must_be_taken = false, ret;
@@ -2263,7 +2263,7 @@ tree_simplify_using_condition (tree cond, tree expr)
simplification was possible). */
tree
-simplify_using_initial_conditions (struct loop *loop, tree expr)
+simplify_using_initial_conditions (class loop *loop, tree expr)
{
edge e;
basic_block bb;
@@ -2315,7 +2315,7 @@ simplify_using_initial_conditions (struct loop *loop, tree expr)
(or EXPR unchanged, if no simplification was possible). */
static tree
-simplify_using_outer_evolutions (struct loop *loop, tree expr)
+simplify_using_outer_evolutions (class loop *loop, tree expr)
{
enum tree_code code = TREE_CODE (expr);
bool changed;
@@ -2368,7 +2368,7 @@ simplify_using_outer_evolutions (struct loop *loop, tree expr)
/* Returns true if EXIT is the only possible exit from LOOP. */
bool
-loop_only_exit_p (const struct loop *loop, const_edge exit)
+loop_only_exit_p (const class loop *loop, const_edge exit)
{
basic_block *body;
gimple_stmt_iterator bsi;
@@ -2395,15 +2395,15 @@ loop_only_exit_p (const struct loop *loop, const_edge exit)
/* Stores description of number of iterations of LOOP derived from
EXIT (an exit edge of the LOOP) in NITER. Returns true if some useful
information could be derived (and fields of NITER have meaning described
- in comments at struct tree_niter_desc declaration), false otherwise.
+ in comments at class tree_niter_desc declaration), false otherwise.
When EVERY_ITERATION is true, only tests that are known to be executed
every iteration are considered (i.e. only test that alone bounds the loop).
If AT_STMT is not NULL, this function stores LOOP's condition statement in
it when returning true. */
bool
-number_of_iterations_exit_assumptions (struct loop *loop, edge exit,
- struct tree_niter_desc *niter,
+number_of_iterations_exit_assumptions (class loop *loop, edge exit,
+ class tree_niter_desc *niter,
gcond **at_stmt, bool every_iteration)
{
gimple *last;
@@ -2598,7 +2598,7 @@ ssa_defined_by_minus_one_stmt_p (tree op, tree val)
static bool
number_of_iterations_popcount (loop_p loop, edge exit,
enum tree_code code,
- struct tree_niter_desc *niter)
+ class tree_niter_desc *niter)
{
bool adjust = true;
tree iter;
@@ -2720,8 +2720,8 @@ number_of_iterations_popcount (loop_p loop, edge exit,
the niter information holds unconditionally. */
bool
-number_of_iterations_exit (struct loop *loop, edge exit,
- struct tree_niter_desc *niter,
+number_of_iterations_exit (class loop *loop, edge exit,
+ class tree_niter_desc *niter,
bool warn, bool every_iteration)
{
gcond *stmt;
@@ -2746,13 +2746,13 @@ number_of_iterations_exit (struct loop *loop, edge exit,
chrec_dont_know is returned. */
tree
-find_loop_niter (struct loop *loop, edge *exit)
+find_loop_niter (class loop *loop, edge *exit)
{
unsigned i;
vec<edge> exits = get_loop_exit_edges (loop);
edge ex;
tree niter = NULL_TREE, aniter;
- struct tree_niter_desc desc;
+ class tree_niter_desc desc;
*exit = NULL;
FOR_EACH_VEC_ELT (exits, i, ex)
@@ -2808,7 +2808,7 @@ find_loop_niter (struct loop *loop, edge *exit)
/* Return true if loop is known to have bounded number of iterations. */
bool
-finite_loop_p (struct loop *loop)
+finite_loop_p (class loop *loop)
{
widest_int nit;
int flags;
@@ -2870,7 +2870,7 @@ finite_loop_p (struct loop *loop)
operands are constants. */
static gphi *
-chain_of_csts_start (struct loop *loop, tree x)
+chain_of_csts_start (class loop *loop, tree x)
{
gimple *stmt = SSA_NAME_DEF_STMT (x);
tree use;
@@ -2919,7 +2919,7 @@ chain_of_csts_start (struct loop *loop, tree x)
If such phi node exists, it is returned, otherwise NULL is returned. */
static gphi *
-get_base_for (struct loop *loop, tree x)
+get_base_for (class loop *loop, tree x)
{
gphi *phi;
tree init, next;
@@ -3007,7 +3007,7 @@ get_val_for (tree x, tree base)
of the iterations of LOOP if successful, chrec_dont_know otherwise. */
tree
-loop_niter_by_eval (struct loop *loop, edge exit)
+loop_niter_by_eval (class loop *loop, edge exit)
{
tree acnd;
tree op[2], val[2], next[2], aval[2];
@@ -3108,7 +3108,7 @@ loop_niter_by_eval (struct loop *loop, edge exit)
determines the number of iterations, chrec_dont_know is returned. */
tree
-find_loop_niter_by_eval (struct loop *loop, edge *exit)
+find_loop_niter_by_eval (class loop *loop, edge *exit)
{
unsigned i;
vec<edge> exits = get_loop_exit_edges (loop);
@@ -3325,7 +3325,7 @@ derive_constant_upper_bound_ops (tree type, tree op0,
/* Emit a -Waggressive-loop-optimizations warning if needed. */
static void
-do_warn_aggressive_loop_optimizations (struct loop *loop,
+do_warn_aggressive_loop_optimizations (class loop *loop,
widest_int i_bound, gimple *stmt)
{
/* Don't warn if the loop doesn't have known constant bound. */
@@ -3367,7 +3367,7 @@ do_warn_aggressive_loop_optimizations (struct loop *loop,
BOUND times. I_BOUND is a widest_int upper estimate on BOUND. */
static void
-record_estimate (struct loop *loop, tree bound, const widest_int &i_bound,
+record_estimate (class loop *loop, tree bound, const widest_int &i_bound,
gimple *at_stmt, bool is_exit, bool realistic, bool upper)
{
widest_int delta;
@@ -3399,7 +3399,7 @@ record_estimate (struct loop *loop, tree bound, const widest_int &i_bound,
|| loop->nb_iterations == NULL_TREE
|| TREE_CODE (loop->nb_iterations) != INTEGER_CST))
{
- struct nb_iter_bound *elt = ggc_alloc<nb_iter_bound> ();
+ class nb_iter_bound *elt = ggc_alloc<nb_iter_bound> ();
elt->bound = i_bound;
elt->stmt = at_stmt;
@@ -3436,7 +3436,7 @@ record_estimate (struct loop *loop, tree bound, const widest_int &i_bound,
and doesn't overflow. */
static void
-record_control_iv (struct loop *loop, struct tree_niter_desc *niter)
+record_control_iv (class loop *loop, class tree_niter_desc *niter)
{
struct control_iv *iv;
@@ -3470,7 +3470,7 @@ get_cst_init_from_scev (tree var, wide_int *init, bool is_min)
return false;
gimple *def_stmt = SSA_NAME_DEF_STMT (var);
- struct loop *loop = loop_containing_stmt (def_stmt);
+ class loop *loop = loop_containing_stmt (def_stmt);
if (loop == NULL)
return false;
@@ -3499,7 +3499,7 @@ get_cst_init_from_scev (tree var, wide_int *init, bool is_min)
UPPER is true if we are sure the induction variable does not wrap. */
static void
-record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt,
+record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt,
tree low, tree high, bool realistic, bool upper)
{
tree niter_bound, extreme, delta;
@@ -3576,7 +3576,7 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple *stmt,
struct ilb_data
{
- struct loop *loop;
+ class loop *loop;
gimple *stmt;
};
@@ -3587,7 +3587,7 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
tree ev, init, step;
tree low, high, type, next;
bool sign, upper = true, at_end = false;
- struct loop *loop = data->loop;
+ class loop *loop = data->loop;
if (TREE_CODE (base) != ARRAY_REF)
return true;
@@ -3601,7 +3601,7 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
upper = false;
}
- struct loop *dloop = loop_containing_stmt (data->stmt);
+ class loop *dloop = loop_containing_stmt (data->stmt);
if (!dloop)
return true;
@@ -3676,7 +3676,7 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
STMT is guaranteed to be executed in every iteration of LOOP.*/
static void
-infer_loop_bounds_from_ref (struct loop *loop, gimple *stmt, tree ref)
+infer_loop_bounds_from_ref (class loop *loop, gimple *stmt, tree ref)
{
struct ilb_data data;
@@ -3690,7 +3690,7 @@ infer_loop_bounds_from_ref (struct loop *loop, gimple *stmt, tree ref)
executed in every iteration of LOOP. */
static void
-infer_loop_bounds_from_array (struct loop *loop, gimple *stmt)
+infer_loop_bounds_from_array (class loop *loop, gimple *stmt)
{
if (is_gimple_assign (stmt))
{
@@ -3727,7 +3727,7 @@ infer_loop_bounds_from_array (struct loop *loop, gimple *stmt)
that pointer arithmetics in STMT does not overflow. */
static void
-infer_loop_bounds_from_pointer_arith (struct loop *loop, gimple *stmt)
+infer_loop_bounds_from_pointer_arith (class loop *loop, gimple *stmt)
{
tree def, base, step, scev, type, low, high;
tree var, ptr;
@@ -3752,7 +3752,7 @@ infer_loop_bounds_from_pointer_arith (struct loop *loop, gimple *stmt)
if (TYPE_PRECISION (type) != TYPE_PRECISION (TREE_TYPE (var)))
return;
- struct loop *uloop = loop_containing_stmt (stmt);
+ class loop *uloop = loop_containing_stmt (stmt);
scev = instantiate_parameters (loop, analyze_scalar_evolution (uloop, def));
if (chrec_contains_undetermined (scev))
return;
@@ -3786,7 +3786,7 @@ infer_loop_bounds_from_pointer_arith (struct loop *loop, gimple *stmt)
that signed arithmetics in STMT does not overflow. */
static void
-infer_loop_bounds_from_signedness (struct loop *loop, gimple *stmt)
+infer_loop_bounds_from_signedness (class loop *loop, gimple *stmt)
{
tree def, base, step, scev, type, low, high;
@@ -3838,7 +3838,7 @@ infer_loop_bounds_from_signedness (struct loop *loop, gimple *stmt)
*/
static void
-infer_loop_bounds_from_undefined (struct loop *loop)
+infer_loop_bounds_from_undefined (class loop *loop)
{
unsigned i;
basic_block *bbs;
@@ -3918,9 +3918,9 @@ bound_index (vec<widest_int> bounds, const widest_int &bound)
some bounded statement. */
static void
-discover_iteration_bound_by_body_walk (struct loop *loop)
+discover_iteration_bound_by_body_walk (class loop *loop)
{
- struct nb_iter_bound *elt;
+ class nb_iter_bound *elt;
auto_vec<widest_int> bounds;
vec<vec<basic_block> > queues = vNULL;
vec<basic_block> queue = vNULL;
@@ -4083,10 +4083,10 @@ discover_iteration_bound_by_body_walk (struct loop *loop)
count by 1. */
static void
-maybe_lower_iteration_bound (struct loop *loop)
+maybe_lower_iteration_bound (class loop *loop)
{
hash_set<gimple *> *not_executed_last_iteration = NULL;
- struct nb_iter_bound *elt;
+ class nb_iter_bound *elt;
bool found_exit = false;
auto_vec<basic_block> queue;
bitmap visited;
@@ -4183,16 +4183,65 @@ maybe_lower_iteration_bound (struct loop *loop)
delete not_executed_last_iteration;
}
+/* Get expected upper bound for number of loop iterations for
+ BUILT_IN_EXPECT_WITH_PROBABILITY for a condition COND. */
+
+static tree
+get_upper_bound_based_on_builtin_expr_with_prob (gcond *cond)
+{
+ if (cond == NULL)
+ return NULL_TREE;
+
+ tree lhs = gimple_cond_lhs (cond);
+ if (TREE_CODE (lhs) != SSA_NAME)
+ return NULL_TREE;
+
+ gimple *stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
+ gcall *def = dyn_cast<gcall *> (stmt);
+ if (def == NULL)
+ return NULL_TREE;
+
+ tree decl = gimple_call_fndecl (def);
+ if (!decl
+ || !fndecl_built_in_p (decl, BUILT_IN_EXPECT_WITH_PROBABILITY)
+ || gimple_call_num_args (stmt) != 3)
+ return NULL_TREE;
+
+ tree c = gimple_call_arg (def, 1);
+ tree condt = TREE_TYPE (lhs);
+ tree res = fold_build2 (gimple_cond_code (cond),
+ condt, c,
+ gimple_cond_rhs (cond));
+ if (TREE_CODE (res) != INTEGER_CST)
+ return NULL_TREE;
+
+
+ tree prob = gimple_call_arg (def, 2);
+ tree t = TREE_TYPE (prob);
+ tree one
+ = build_real_from_int_cst (t,
+ integer_one_node);
+ if (integer_zerop (res))
+ prob = fold_build2 (MINUS_EXPR, t, one, prob);
+ tree r = fold_build2 (RDIV_EXPR, t, one, prob);
+ if (TREE_CODE (r) != REAL_CST)
+ return NULL_TREE;
+
+ HOST_WIDE_INT probi
+ = real_to_integer (TREE_REAL_CST_PTR (r));
+ return build_int_cst (condt, probi);
+}
+
/* Records estimates on numbers of iterations of LOOP. If USE_UNDEFINED_P
is true also use estimates derived from undefined behavior. */
void
-estimate_numbers_of_iterations (struct loop *loop)
+estimate_numbers_of_iterations (class loop *loop)
{
vec<edge> exits;
tree niter, type;
unsigned i;
- struct tree_niter_desc niter_desc;
+ class tree_niter_desc niter_desc;
edge ex;
widest_int bound;
edge likely_exit;
@@ -4231,6 +4280,23 @@ estimate_numbers_of_iterations (struct loop *loop)
likely_exit = single_likely_exit (loop);
FOR_EACH_VEC_ELT (exits, i, ex)
{
+ if (ex == likely_exit)
+ {
+ gimple *stmt = last_stmt (ex->src);
+ if (stmt != NULL)
+ {
+ gcond *cond = dyn_cast<gcond *> (stmt);
+ tree niter_bound
+ = get_upper_bound_based_on_builtin_expr_with_prob (cond);
+ if (niter_bound != NULL_TREE)
+ {
+ widest_int max = derive_constant_upper_bound (niter_bound);
+ record_estimate (loop, niter_bound, max, cond,
+ true, true, false);
+ }
+ }
+ }
+
if (!number_of_iterations_exit (loop, ex, &niter_desc, false, false))
continue;
@@ -4271,7 +4337,7 @@ estimate_numbers_of_iterations (struct loop *loop)
the function returns false, otherwise returns true. */
bool
-estimated_loop_iterations (struct loop *loop, widest_int *nit)
+estimated_loop_iterations (class loop *loop, widest_int *nit)
{
/* When SCEV information is available, try to update loop iterations
estimate. Otherwise just return whatever we recorded earlier. */
@@ -4286,7 +4352,7 @@ estimated_loop_iterations (struct loop *loop, widest_int *nit)
on the number of iterations of LOOP could not be derived, returns -1. */
HOST_WIDE_INT
-estimated_loop_iterations_int (struct loop *loop)
+estimated_loop_iterations_int (class loop *loop)
{
widest_int nit;
HOST_WIDE_INT hwi_nit;
@@ -4307,7 +4373,7 @@ estimated_loop_iterations_int (struct loop *loop)
false, otherwise returns true. */
bool
-max_loop_iterations (struct loop *loop, widest_int *nit)
+max_loop_iterations (class loop *loop, widest_int *nit)
{
/* When SCEV information is available, try to update loop iterations
estimate. Otherwise just return whatever we recorded earlier. */
@@ -4322,7 +4388,7 @@ max_loop_iterations (struct loop *loop, widest_int *nit)
on the number of iterations of LOOP could not be derived, returns -1. */
HOST_WIDE_INT
-max_loop_iterations_int (struct loop *loop)
+max_loop_iterations_int (class loop *loop)
{
widest_int nit;
HOST_WIDE_INT hwi_nit;
@@ -4342,7 +4408,7 @@ max_loop_iterations_int (struct loop *loop)
false, otherwise returns true. */
bool
-likely_max_loop_iterations (struct loop *loop, widest_int *nit)
+likely_max_loop_iterations (class loop *loop, widest_int *nit)
{
/* When SCEV information is available, try to update loop iterations
estimate. Otherwise just return whatever we recorded earlier. */
@@ -4357,7 +4423,7 @@ likely_max_loop_iterations (struct loop *loop, widest_int *nit)
on the number of iterations of LOOP could not be derived, returns -1. */
HOST_WIDE_INT
-likely_max_loop_iterations_int (struct loop *loop)
+likely_max_loop_iterations_int (class loop *loop)
{
widest_int nit;
HOST_WIDE_INT hwi_nit;
@@ -4377,7 +4443,7 @@ likely_max_loop_iterations_int (struct loop *loop)
the number of execution of the latch by one. */
HOST_WIDE_INT
-estimated_stmt_executions_int (struct loop *loop)
+estimated_stmt_executions_int (class loop *loop)
{
HOST_WIDE_INT nit = estimated_loop_iterations_int (loop);
HOST_WIDE_INT snit;
@@ -4396,7 +4462,7 @@ estimated_stmt_executions_int (struct loop *loop)
false, otherwise returns true. */
bool
-max_stmt_executions (struct loop *loop, widest_int *nit)
+max_stmt_executions (class loop *loop, widest_int *nit)
{
widest_int nit_minus_one;
@@ -4415,7 +4481,7 @@ max_stmt_executions (struct loop *loop, widest_int *nit)
false, otherwise returns true. */
bool
-likely_max_stmt_executions (struct loop *loop, widest_int *nit)
+likely_max_stmt_executions (class loop *loop, widest_int *nit)
{
widest_int nit_minus_one;
@@ -4434,7 +4500,7 @@ likely_max_stmt_executions (struct loop *loop, widest_int *nit)
false, otherwise returns true. */
bool
-estimated_stmt_executions (struct loop *loop, widest_int *nit)
+estimated_stmt_executions (class loop *loop, widest_int *nit)
{
widest_int nit_minus_one;
@@ -4453,7 +4519,7 @@ estimated_stmt_executions (struct loop *loop, widest_int *nit)
void
estimate_numbers_of_iterations (function *fn)
{
- struct loop *loop;
+ class loop *loop;
/* We don't want to issue signed overflow warnings while getting
loop iteration estimates. */
@@ -4511,7 +4577,7 @@ stmt_dominates_stmt_p (gimple *s1, gimple *s2)
static bool
n_of_executions_at_most (gimple *stmt,
- struct nb_iter_bound *niter_bound,
+ class nb_iter_bound *niter_bound,
tree niter)
{
widest_int bound = niter_bound->bound;
@@ -4598,11 +4664,11 @@ nowrap_type_p (tree type)
static bool
loop_exits_before_overflow (tree base, tree step,
- gimple *at_stmt, struct loop *loop)
+ gimple *at_stmt, class loop *loop)
{
widest_int niter;
struct control_iv *civ;
- struct nb_iter_bound *bound;
+ class nb_iter_bound *bound;
tree e, delta, step_abs, unsigned_base;
tree type = TREE_TYPE (step);
tree unsigned_type, valid_niter;
@@ -4790,7 +4856,7 @@ loop_exits_before_overflow (tree base, tree step,
(4294967295, 4294967296, ...). */
static bool
-scev_var_range_cant_overflow (tree var, tree step, struct loop *loop)
+scev_var_range_cant_overflow (tree var, tree step, class loop *loop)
{
tree type;
wide_int minv, maxv, diff, step_wi;
@@ -4844,7 +4910,7 @@ scev_var_range_cant_overflow (tree var, tree step, struct loop *loop)
bool
scev_probably_wraps_p (tree var, tree base, tree step,
- gimple *at_stmt, struct loop *loop,
+ gimple *at_stmt, class loop *loop,
bool use_overflow_semantics)
{
/* FIXME: We really need something like
@@ -4896,16 +4962,16 @@ scev_probably_wraps_p (tree var, tree base, tree step,
/* Frees the information on upper bounds on numbers of iterations of LOOP. */
void
-free_numbers_of_iterations_estimates (struct loop *loop)
+free_numbers_of_iterations_estimates (class loop *loop)
{
struct control_iv *civ;
- struct nb_iter_bound *bound;
+ class nb_iter_bound *bound;
loop->nb_iterations = NULL;
loop->estimate_state = EST_NOT_COMPUTED;
for (bound = loop->bounds; bound;)
{
- struct nb_iter_bound *next = bound->next;
+ class nb_iter_bound *next = bound->next;
ggc_free (bound);
bound = next;
}
@@ -4925,7 +4991,7 @@ free_numbers_of_iterations_estimates (struct loop *loop)
void
free_numbers_of_iterations_estimates (function *fn)
{
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP_FN (fn, loop, 0)
free_numbers_of_iterations_estimates (loop);
@@ -4935,7 +5001,7 @@ free_numbers_of_iterations_estimates (function *fn)
at LOOP. */
void
-substitute_in_loop_info (struct loop *loop, tree name, tree val)
+substitute_in_loop_info (class loop *loop, tree name, tree val)
{
loop->nb_iterations = simplify_replace_tree (loop->nb_iterations, name, val);
}
diff --git a/gcc/tree-ssa-loop-niter.h b/gcc/tree-ssa-loop-niter.h
index dc11648..4454c1a 100644
--- a/gcc/tree-ssa-loop-niter.h
+++ b/gcc/tree-ssa-loop-niter.h
@@ -21,39 +21,39 @@ along with GCC; see the file COPYING3. If not see
#define GCC_TREE_SSA_LOOP_NITER_H
extern tree expand_simple_operations (tree, tree = NULL);
-extern tree simplify_using_initial_conditions (struct loop *, tree);
-extern bool loop_only_exit_p (const struct loop *, const_edge);
-extern bool number_of_iterations_exit (struct loop *, edge,
- struct tree_niter_desc *niter, bool,
+extern tree simplify_using_initial_conditions (class loop *, tree);
+extern bool loop_only_exit_p (const class loop *, const_edge);
+extern bool number_of_iterations_exit (class loop *, edge,
+ class tree_niter_desc *niter, bool,
bool every_iteration = true);
-extern bool number_of_iterations_exit_assumptions (struct loop *, edge,
- struct tree_niter_desc *,
+extern bool number_of_iterations_exit_assumptions (class loop *, edge,
+ class tree_niter_desc *,
gcond **, bool = true);
-extern tree find_loop_niter (struct loop *, edge *);
-extern bool finite_loop_p (struct loop *);
-extern tree loop_niter_by_eval (struct loop *, edge);
-extern tree find_loop_niter_by_eval (struct loop *, edge *);
-extern bool estimated_loop_iterations (struct loop *, widest_int *);
-extern HOST_WIDE_INT estimated_loop_iterations_int (struct loop *);
-extern bool max_loop_iterations (struct loop *, widest_int *);
-extern HOST_WIDE_INT max_loop_iterations_int (struct loop *);
-extern bool likely_max_loop_iterations (struct loop *, widest_int *);
-extern HOST_WIDE_INT likely_max_loop_iterations_int (struct loop *);
-extern HOST_WIDE_INT max_stmt_executions_int (struct loop *);
-extern HOST_WIDE_INT likely_max_stmt_executions_int (struct loop *);
-extern HOST_WIDE_INT estimated_stmt_executions_int (struct loop *);
-extern bool max_stmt_executions (struct loop *, widest_int *);
-extern bool likely_max_stmt_executions (struct loop *, widest_int *);
-extern bool estimated_stmt_executions (struct loop *, widest_int *);
+extern tree find_loop_niter (class loop *, edge *);
+extern bool finite_loop_p (class loop *);
+extern tree loop_niter_by_eval (class loop *, edge);
+extern tree find_loop_niter_by_eval (class loop *, edge *);
+extern bool estimated_loop_iterations (class loop *, widest_int *);
+extern HOST_WIDE_INT estimated_loop_iterations_int (class loop *);
+extern bool max_loop_iterations (class loop *, widest_int *);
+extern HOST_WIDE_INT max_loop_iterations_int (class loop *);
+extern bool likely_max_loop_iterations (class loop *, widest_int *);
+extern HOST_WIDE_INT likely_max_loop_iterations_int (class loop *);
+extern HOST_WIDE_INT max_stmt_executions_int (class loop *);
+extern HOST_WIDE_INT likely_max_stmt_executions_int (class loop *);
+extern HOST_WIDE_INT estimated_stmt_executions_int (class loop *);
+extern bool max_stmt_executions (class loop *, widest_int *);
+extern bool likely_max_stmt_executions (class loop *, widest_int *);
+extern bool estimated_stmt_executions (class loop *, widest_int *);
extern void estimate_numbers_of_iterations (function *);
-extern void estimate_numbers_of_iterations (struct loop *);
+extern void estimate_numbers_of_iterations (class loop *);
extern bool stmt_dominates_stmt_p (gimple *, gimple *);
extern bool nowrap_type_p (tree);
extern bool scev_probably_wraps_p (tree, tree, tree, gimple *,
- struct loop *, bool);
-extern void free_numbers_of_iterations_estimates (struct loop *);
+ class loop *, bool);
+extern void free_numbers_of_iterations_estimates (class loop *);
extern void free_numbers_of_iterations_estimates (function *);
extern tree simplify_replace_tree (tree, tree, tree, tree (*)(tree) = NULL);
-extern void substitute_in_loop_info (struct loop *, tree, tree);
+extern void substitute_in_loop_info (class loop *, tree, tree);
#endif /* GCC_TREE_SSA_LOOP_NITER_H */
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index 7afd85f..04ff524 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -421,7 +421,7 @@ release_mem_refs (struct mem_ref_group *groups)
struct ar_data
{
- struct loop *loop; /* Loop of the reference. */
+ class loop *loop; /* Loop of the reference. */
gimple *stmt; /* Statement of the reference. */
tree *step; /* Step of the memory reference. */
HOST_WIDE_INT *delta; /* Offset of the memory reference. */
@@ -486,7 +486,7 @@ idx_analyze_ref (tree base, tree *index, void *data)
references from REF_P. */
static bool
-analyze_ref (struct loop *loop, tree *ref_p, tree *base,
+analyze_ref (class loop *loop, tree *ref_p, tree *base,
tree *step, HOST_WIDE_INT *delta,
gimple *stmt)
{
@@ -535,7 +535,7 @@ analyze_ref (struct loop *loop, tree *ref_p, tree *base,
reference was recorded, false otherwise. */
static bool
-gather_memory_references_ref (struct loop *loop, struct mem_ref_group **refs,
+gather_memory_references_ref (class loop *loop, struct mem_ref_group **refs,
tree ref, bool write_p, gimple *stmt)
{
tree base, step;
@@ -606,7 +606,7 @@ gather_memory_references_ref (struct loop *loop, struct mem_ref_group **refs,
true if there are no other memory references inside the loop. */
static struct mem_ref_group *
-gather_memory_references (struct loop *loop, bool *no_other_refs, unsigned *ref_count)
+gather_memory_references (class loop *loop, bool *no_other_refs, unsigned *ref_count)
{
basic_block *body = get_loop_body_in_dom_order (loop);
basic_block bb;
@@ -1286,7 +1286,7 @@ mark_nontemporal_store (struct mem_ref *ref)
/* Issue a memory fence instruction after LOOP. */
static void
-emit_mfence_after_loop (struct loop *loop)
+emit_mfence_after_loop (class loop *loop)
{
vec<edge> exits = get_loop_exit_edges (loop);
edge exit;
@@ -1315,7 +1315,7 @@ emit_mfence_after_loop (struct loop *loop)
/* Returns true if we can use storent in loop, false otherwise. */
static bool
-may_use_storent_in_loop_p (struct loop *loop)
+may_use_storent_in_loop_p (class loop *loop)
{
bool ret = true;
@@ -1345,7 +1345,7 @@ may_use_storent_in_loop_p (struct loop *loop)
references in the loop. */
static void
-mark_nontemporal_stores (struct loop *loop, struct mem_ref_group *groups)
+mark_nontemporal_stores (class loop *loop, struct mem_ref_group *groups)
{
struct mem_ref *ref;
bool any = false;
@@ -1366,7 +1366,7 @@ mark_nontemporal_stores (struct loop *loop, struct mem_ref_group *groups)
iterations. */
static bool
-should_unroll_loop_p (struct loop *loop, struct tree_niter_desc *desc,
+should_unroll_loop_p (class loop *loop, class tree_niter_desc *desc,
unsigned factor)
{
if (!can_unroll_loop_p (loop, factor, desc))
@@ -1390,8 +1390,8 @@ should_unroll_loop_p (struct loop *loop, struct tree_niter_desc *desc,
the loop, or -1 if no estimate is available. */
static unsigned
-determine_unroll_factor (struct loop *loop, struct mem_ref_group *refs,
- unsigned ninsns, struct tree_niter_desc *desc,
+determine_unroll_factor (class loop *loop, struct mem_ref_group *refs,
+ unsigned ninsns, class tree_niter_desc *desc,
HOST_WIDE_INT est_niter)
{
unsigned upper_bound;
@@ -1493,9 +1493,9 @@ volume_of_dist_vector (lambda_vector vec, unsigned *loop_sizes, unsigned n)
static void
add_subscript_strides (tree access_fn, unsigned stride,
- HOST_WIDE_INT *strides, unsigned n, struct loop *loop)
+ HOST_WIDE_INT *strides, unsigned n, class loop *loop)
{
- struct loop *aloop;
+ class loop *aloop;
tree step;
HOST_WIDE_INT astep;
unsigned min_depth = loop_depth (loop) - n;
@@ -1526,7 +1526,7 @@ add_subscript_strides (tree access_fn, unsigned stride,
static unsigned
self_reuse_distance (data_reference_p dr, unsigned *loop_sizes, unsigned n,
- struct loop *loop)
+ class loop *loop)
{
tree stride, access_fn;
HOST_WIDE_INT *strides, astride;
@@ -1596,10 +1596,10 @@ self_reuse_distance (data_reference_p dr, unsigned *loop_sizes, unsigned n,
memory references in the loop. Return false if the analysis fails. */
static bool
-determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
+determine_loop_nest_reuse (class loop *loop, struct mem_ref_group *refs,
bool no_other_refs)
{
- struct loop *nest, *aloop;
+ class loop *nest, *aloop;
vec<data_reference_p> datarefs = vNULL;
vec<ddr_p> dependences = vNULL;
struct mem_ref_group *gr;
@@ -1879,12 +1879,12 @@ insn_to_prefetch_ratio_too_small_p (unsigned ninsns, unsigned prefetch_count,
true if the LOOP was unrolled. */
static bool
-loop_prefetch_arrays (struct loop *loop)
+loop_prefetch_arrays (class loop *loop)
{
struct mem_ref_group *refs;
unsigned ahead, ninsns, time, unroll_factor;
HOST_WIDE_INT est_niter;
- struct tree_niter_desc desc;
+ class tree_niter_desc desc;
bool unrolled = false, no_other_refs;
unsigned prefetch_count;
unsigned mem_ref_count;
@@ -1982,7 +1982,7 @@ fail:
unsigned int
tree_ssa_prefetch_arrays (void)
{
- struct loop *loop;
+ class loop *loop;
bool unrolled = false;
int todo_flags = 0;
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index 999c9a3..f5f0833 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -70,7 +70,7 @@ along with GCC; see the file COPYING3. If not see
point in *BORDER and the comparison induction variable in IV. */
static tree
-split_at_bb_p (struct loop *loop, basic_block bb, tree *border, affine_iv *iv)
+split_at_bb_p (class loop *loop, basic_block bb, tree *border, affine_iv *iv)
{
gimple *last;
gcond *stmt;
@@ -102,7 +102,7 @@ split_at_bb_p (struct loop *loop, basic_block bb, tree *border, affine_iv *iv)
tree op0 = gimple_cond_lhs (stmt);
tree op1 = gimple_cond_rhs (stmt);
- struct loop *useloop = loop_containing_stmt (stmt);
+ class loop *useloop = loop_containing_stmt (stmt);
if (!simple_iv (loop, useloop, op0, iv, false))
return NULL_TREE;
@@ -150,7 +150,7 @@ split_at_bb_p (struct loop *loop, basic_block bb, tree *border, affine_iv *iv)
also be true/false in the next iteration. */
static void
-patch_loop_exit (struct loop *loop, gcond *guard, tree nextval, tree newbound,
+patch_loop_exit (class loop *loop, gcond *guard, tree nextval, tree newbound,
bool initial_true)
{
edge exit = single_exit (loop);
@@ -181,7 +181,7 @@ patch_loop_exit (struct loop *loop, gcond *guard, tree nextval, tree newbound,
such phi node. Return that phi node. */
static gphi *
-find_or_create_guard_phi (struct loop *loop, tree guard_iv, affine_iv * /*iv*/)
+find_or_create_guard_phi (class loop *loop, tree guard_iv, affine_iv * /*iv*/)
{
gimple *def = SSA_NAME_DEF_STMT (guard_iv);
gphi *phi;
@@ -197,7 +197,7 @@ find_or_create_guard_phi (struct loop *loop, tree guard_iv, affine_iv * /*iv*/)
determined easily (i.e. that connect_loop_phis can determine them). */
static bool
-easy_exit_values (struct loop *loop)
+easy_exit_values (class loop *loop)
{
edge exit = single_exit (loop);
edge latch = loop_latch_edge (loop);
@@ -229,7 +229,7 @@ easy_exit_values (struct loop *loop)
this. The loops need to fulfill easy_exit_values(). */
static void
-connect_loop_phis (struct loop *loop1, struct loop *loop2, edge new_e)
+connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e)
{
basic_block rest = loop_preheader_edge (loop2)->src;
gcc_assert (new_e->dest == rest);
@@ -323,7 +323,7 @@ connect_loop_phis (struct loop *loop1, struct loop *loop2, edge new_e)
This doesn't update the SSA form, see connect_loop_phis for that. */
static edge
-connect_loops (struct loop *loop1, struct loop *loop2)
+connect_loops (class loop *loop1, class loop *loop2)
{
edge exit = single_exit (loop1);
basic_block skip_bb = split_edge (exit);
@@ -387,7 +387,7 @@ connect_loops (struct loop *loop1, struct loop *loop2)
and add or subtract 1. This routine computes newend above. */
static tree
-compute_new_first_bound (gimple_seq *stmts, struct tree_niter_desc *niter,
+compute_new_first_bound (gimple_seq *stmts, class tree_niter_desc *niter,
tree border,
enum tree_code guard_code, tree guard_init)
{
@@ -487,7 +487,7 @@ compute_new_first_bound (gimple_seq *stmts, struct tree_niter_desc *niter,
single exit of LOOP. */
static bool
-split_loop (struct loop *loop1, struct tree_niter_desc *niter)
+split_loop (class loop *loop1, class tree_niter_desc *niter)
{
basic_block *bbs;
unsigned i;
@@ -557,7 +557,7 @@ split_loop (struct loop *loop1, struct tree_niter_desc *niter)
initialize_original_copy_tables ();
basic_block cond_bb;
- struct loop *loop2 = loop_version (loop1, cond, &cond_bb,
+ class loop *loop2 = loop_version (loop1, cond, &cond_bb,
profile_probability::always (),
profile_probability::always (),
profile_probability::always (),
@@ -617,7 +617,7 @@ split_loop (struct loop *loop1, struct tree_niter_desc *niter)
static unsigned int
tree_ssa_split_loops (void)
{
- struct loop *loop;
+ class loop *loop;
bool changed = false;
gcc_assert (scev_initialized_p ());
@@ -627,7 +627,7 @@ tree_ssa_split_loops (void)
/* Go through all loops starting from innermost. */
FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
{
- struct tree_niter_desc niter;
+ class tree_niter_desc niter;
if (loop->aux)
{
/* If any of our inner loops was split, don't split us,
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index 30a2a9d..e60019d 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -75,23 +75,23 @@ along with GCC; see the file COPYING3. If not see
tree-ssa-loop-im.c ensures that all the suitable conditions are in this
shape. */
-static struct loop *tree_unswitch_loop (struct loop *, basic_block, tree);
-static bool tree_unswitch_single_loop (struct loop *, int);
-static tree tree_may_unswitch_on (basic_block, struct loop *);
-static bool tree_unswitch_outer_loop (struct loop *);
-static edge find_loop_guard (struct loop *);
-static bool empty_bb_without_guard_p (struct loop *, basic_block);
-static bool used_outside_loop_p (struct loop *, tree);
-static void hoist_guard (struct loop *, edge);
-static bool check_exit_phi (struct loop *);
-static tree get_vop_from_header (struct loop *);
+static class loop *tree_unswitch_loop (class loop *, basic_block, tree);
+static bool tree_unswitch_single_loop (class loop *, int);
+static tree tree_may_unswitch_on (basic_block, class loop *);
+static bool tree_unswitch_outer_loop (class loop *);
+static edge find_loop_guard (class loop *);
+static bool empty_bb_without_guard_p (class loop *, basic_block);
+static bool used_outside_loop_p (class loop *, tree);
+static void hoist_guard (class loop *, edge);
+static bool check_exit_phi (class loop *);
+static tree get_vop_from_header (class loop *);
/* Main entry point. Perform loop unswitching on all suitable loops. */
unsigned int
tree_ssa_unswitch_loops (void)
{
- struct loop *loop;
+ class loop *loop;
bool changed = false;
/* Go through all loops starting from innermost. */
@@ -114,7 +114,7 @@ tree_ssa_unswitch_loops (void)
considering for unswitching and LOOP is the loop it appears in. */
static bool
-is_maybe_undefined (const tree name, gimple *stmt, struct loop *loop)
+is_maybe_undefined (const tree name, gimple *stmt, class loop *loop)
{
/* The loop header is the only block we can trivially determine that
will always be executed. If the comparison is in the loop
@@ -187,7 +187,7 @@ is_maybe_undefined (const tree name, gimple *stmt, struct loop *loop)
basic blocks (for what it means see comments below). */
static tree
-tree_may_unswitch_on (basic_block bb, struct loop *loop)
+tree_may_unswitch_on (basic_block bb, class loop *loop)
{
gimple *last, *def;
gcond *stmt;
@@ -232,7 +232,7 @@ tree_may_unswitch_on (basic_block bb, struct loop *loop)
unnecessarily). */
static tree
-simplify_using_entry_checks (struct loop *loop, tree cond)
+simplify_using_entry_checks (class loop *loop, tree cond)
{
edge e = loop_preheader_edge (loop);
gimple *stmt;
@@ -265,10 +265,10 @@ simplify_using_entry_checks (struct loop *loop, tree cond)
grow exponentially. */
static bool
-tree_unswitch_single_loop (struct loop *loop, int num)
+tree_unswitch_single_loop (class loop *loop, int num)
{
basic_block *bbs;
- struct loop *nloop;
+ class loop *nloop;
unsigned i, found;
tree cond = NULL_TREE;
gimple *stmt;
@@ -476,8 +476,8 @@ tree_unswitch_single_loop (struct loop *loop, int num)
loop is entered -- the new loop is entered if COND is true. Returns NULL
if impossible, new loop otherwise. */
-static struct loop *
-tree_unswitch_loop (struct loop *loop,
+static class loop *
+tree_unswitch_loop (class loop *loop,
basic_block unswitch_on, tree cond)
{
profile_probability prob_true;
@@ -500,7 +500,7 @@ tree_unswitch_loop (struct loop *loop,
/* Unswitch outer loops by hoisting invariant guard on
inner loop without code duplication. */
static bool
-tree_unswitch_outer_loop (struct loop *loop)
+tree_unswitch_outer_loop (class loop *loop)
{
edge exit, guard;
HOST_WIDE_INT iterations;
@@ -544,7 +544,7 @@ tree_unswitch_outer_loop (struct loop *loop)
otherwise returns NULL. */
static edge
-find_loop_guard (struct loop *loop)
+find_loop_guard (class loop *loop)
{
basic_block header = loop->header;
edge guard_edge, te, fe;
@@ -701,7 +701,7 @@ end:
are invariant or not. */
static bool
-empty_bb_without_guard_p (struct loop *loop, basic_block bb)
+empty_bb_without_guard_p (class loop *loop, basic_block bb)
{
basic_block exit_bb = single_exit (loop)->src;
bool may_be_used_outside = (bb == exit_bb
@@ -749,7 +749,7 @@ empty_bb_without_guard_p (struct loop *loop, basic_block bb)
/* Return true if NAME is used outside of LOOP. */
static bool
-used_outside_loop_p (struct loop *loop, tree name)
+used_outside_loop_p (class loop *loop, tree name)
{
imm_use_iterator it;
use_operand_p use;
@@ -767,7 +767,7 @@ used_outside_loop_p (struct loop *loop, tree name)
/* Return argument for loop preheader edge in header virtual phi if any. */
static tree
-get_vop_from_header (struct loop *loop)
+get_vop_from_header (class loop *loop)
{
for (gphi_iterator gsi = gsi_start_phis (loop->header);
!gsi_end_p (gsi); gsi_next (&gsi))
@@ -783,7 +783,7 @@ get_vop_from_header (struct loop *loop)
/* Move the check of GUARD outside of LOOP. */
static void
-hoist_guard (struct loop *loop, edge guard)
+hoist_guard (class loop *loop, edge guard)
{
edge exit = single_exit (loop);
edge preh = loop_preheader_edge (loop);
@@ -934,7 +934,7 @@ hoist_guard (struct loop *loop, edge guard)
for edge around loop. */
static bool
-check_exit_phi (struct loop *loop)
+check_exit_phi (class loop *loop)
{
edge exit = single_exit (loop);
basic_block pre_header = loop_preheader_edge (loop)->src;
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 208c583..fc9f083 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -157,7 +157,7 @@ gate_oacc_kernels (function *fn)
if (!lookup_attribute ("oacc kernels", DECL_ATTRIBUTES (fn->decl)))
return false;
- struct loop *loop;
+ class loop *loop;
FOR_EACH_LOOP (loop, 0)
if (loop->in_oacc_kernels_region)
return true;
@@ -455,7 +455,7 @@ public:
unsigned
pass_scev_cprop::execute (function *)
{
- struct loop *loop;
+ class loop *loop;
bool any = false;
/* Perform final value replacement in loops, in case the replacement
@@ -776,7 +776,7 @@ get_lsm_tmp_name (tree ref, unsigned n, const char *suffix)
/* Computes an estimated number of insns in LOOP, weighted by WEIGHTS. */
unsigned
-tree_num_loop_insns (struct loop *loop, eni_weights *weights)
+tree_num_loop_insns (class loop *loop, eni_weights *weights)
{
basic_block *body = get_loop_body (loop);
gimple_stmt_iterator gsi;
diff --git a/gcc/tree-ssa-loop.h b/gcc/tree-ssa-loop.h
index 2fc9e8c..e523de2 100644
--- a/gcc/tree-ssa-loop.h
+++ b/gcc/tree-ssa-loop.h
@@ -36,8 +36,9 @@ struct affine_iv
the structure can be evaluated at the end of the loop's preheader
(and due to ssa form, also anywhere inside the body of the loop). */
-struct tree_niter_desc
+class tree_niter_desc
{
+public:
tree assumptions; /* The boolean expression. If this expression evaluates
to false, then the other fields in this structure
should not be used; there is no guarantee that they
@@ -65,11 +66,11 @@ struct tree_niter_desc
extern bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *);
extern char *get_lsm_tmp_name (tree ref, unsigned n, const char *suffix = NULL);
-extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights *);
+extern unsigned tree_num_loop_insns (class loop *, struct eni_weights *);
/* Returns the loop of the statement STMT. */
-static inline struct loop *
+static inline class loop *
loop_containing_stmt (gimple *stmt)
{
basic_block bb = gimple_bb (stmt);
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 7088ff9..b64bde6 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -2196,7 +2196,8 @@ get_non_trapping (void)
We check that MIDDLE_BB contains only one store, that that store
doesn't trap (not via NOTRAP, but via checking if an access to the same
- memory location dominates us) and that the store has a "simple" RHS. */
+ memory location dominates us, or the store is to a local addressable
+ object) and that the store has a "simple" RHS. */
static bool
cond_store_replacement (basic_block middle_bb, basic_block join_bb,
@@ -2215,11 +2216,17 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
|| gimple_has_volatile_ops (assign))
return false;
+ /* And no PHI nodes so all uses in the single stmt are also
+ available where we insert to. */
+ if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
+ return false;
+
locus = gimple_location (assign);
lhs = gimple_assign_lhs (assign);
rhs = gimple_assign_rhs1 (assign);
- if (TREE_CODE (lhs) != MEM_REF
- || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME
+ if ((TREE_CODE (lhs) != MEM_REF
+ && TREE_CODE (lhs) != ARRAY_REF
+ && TREE_CODE (lhs) != COMPONENT_REF)
|| !is_gimple_reg_type (TREE_TYPE (lhs)))
return false;
@@ -2227,7 +2234,13 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
TREE_THIS_NOTRAP here, but in that case we also could move stores,
whose value is not available readily, which we want to avoid. */
if (!nontrap->contains (lhs))
- return false;
+ {
+ /* If LHS is a local variable without address-taken, we could
+ always safely move down the store. */
+ tree base = get_base_address (lhs);
+ if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
+ return false;
+ }
/* Now we've checked the constraints, so do the transformation:
1) Remove the single store. */
@@ -2280,6 +2293,14 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
else
gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "\nConditional store replacement happened!");
+ fprintf (dump_file, "\nReplaced the store with a load.");
+ fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
+ print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
+ }
+
return true;
}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 086f8c3..36da4c6a 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -428,8 +428,9 @@ get_or_alloc_expr_for_name (tree name)
/* An unordered bitmap set. One bitmap tracks values, the other,
expressions. */
-typedef struct bitmap_set
+typedef class bitmap_set
{
+public:
bitmap_head expressions;
bitmap_head values;
} *bitmap_set_t;
@@ -1185,8 +1186,8 @@ translate_vuse_through_block (vec<vn_reference_op_s> operands,
bitmap visited = NULL;
/* Try to find a vuse that dominates this phi node by skipping
non-clobbering statements. */
- vuse = get_continuation_for_phi (phi, &ref, cnt, &visited, false,
- NULL, NULL);
+ vuse = get_continuation_for_phi (phi, &ref, true,
+ cnt, &visited, false, NULL, NULL);
if (visited)
BITMAP_FREE (visited);
}
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 9c1a9a6..df76e66 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -270,7 +270,7 @@ static long
phi_rank (gimple *stmt)
{
basic_block bb = gimple_bb (stmt);
- struct loop *father = bb->loop_father;
+ class loop *father = bb->loop_father;
tree res;
unsigned i;
use_operand_p use;
@@ -603,7 +603,7 @@ add_repeat_to_ops_vec (vec<operand_entry *> *ops, tree op,
operation with tree code CODE, and is inside LOOP. */
static bool
-is_reassociable_op (gimple *stmt, enum tree_code code, struct loop *loop)
+is_reassociable_op (gimple *stmt, enum tree_code code, class loop *loop)
{
basic_block bb = gimple_bb (stmt);
@@ -1560,7 +1560,7 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode)
static bool
undistribute_ops_list (enum tree_code opcode,
- vec<operand_entry *> *ops, struct loop *loop)
+ vec<operand_entry *> *ops, class loop *loop)
{
unsigned int length = ops->length ();
operand_entry *oe1;
@@ -1772,6 +1772,274 @@ undistribute_ops_list (enum tree_code opcode,
return changed;
}
+/* Pair to hold the information of one specific VECTOR_TYPE SSA_NAME:
+ first: element index for each relevant BIT_FIELD_REF.
+ second: the index of vec ops* for each relevant BIT_FIELD_REF. */
+typedef std::pair<unsigned, unsigned> v_info_elem;
+typedef auto_vec<v_info_elem, 32> v_info;
+typedef v_info *v_info_ptr;
+
+/* Comparison function for qsort on VECTOR SSA_NAME trees by machine mode. */
+static int
+sort_by_mach_mode (const void *p_i, const void *p_j)
+{
+ const tree tr1 = *((const tree *) p_i);
+ const tree tr2 = *((const tree *) p_j);
+ unsigned int mode1 = TYPE_MODE (TREE_TYPE (tr1));
+ unsigned int mode2 = TYPE_MODE (TREE_TYPE (tr2));
+ if (mode1 > mode2)
+ return 1;
+ else if (mode1 < mode2)
+ return -1;
+ else
+ return 0;
+}
+
+/* Cleanup hash map for VECTOR information. */
+static void
+cleanup_vinfo_map (hash_map<tree, v_info_ptr> &info_map)
+{
+ for (hash_map<tree, v_info_ptr>::iterator it = info_map.begin ();
+ it != info_map.end (); ++it)
+ {
+ v_info_ptr info = (*it).second;
+ delete info;
+ (*it).second = NULL;
+ }
+}
+
+/* Perform un-distribution of BIT_FIELD_REF on VECTOR_TYPE.
+ V1[0] + V1[1] + ... + V1[k] + V2[0] + V2[1] + ... + V2[k] + ... Vn[k]
+ is transformed to
+ Vs = (V1 + V2 + ... + Vn)
+ Vs[0] + Vs[1] + ... + Vs[k]
+
+ The basic steps are listed below:
+
+ 1) Check the addition chain *OPS by looking those summands coming from
+ VECTOR bit_field_ref on VECTOR type. Put the information into
+ v_info_map for each satisfied summand, using VECTOR SSA_NAME as key.
+
+ 2) For each key (VECTOR SSA_NAME), validate all its BIT_FIELD_REFs are
+ continuous, they can cover the whole VECTOR perfectly without any holes.
+ Obtain one VECTOR list which contain candidates to be transformed.
+
+ 3) Sort the VECTOR list by machine mode of VECTOR type, for each group of
+ candidates with same mode, build the addition statements for them and
+ generate BIT_FIELD_REFs accordingly.
+
+ TODO:
+ The current implementation requires the whole VECTORs should be fully
+ covered, but it can be extended to support partial, checking adjacent
+ but not fill the whole, it may need some cost model to define the
+ boundary to do or not.
+*/
+static bool
+undistribute_bitref_for_vector (enum tree_code opcode,
+ vec<operand_entry *> *ops, struct loop *loop)
+{
+ if (ops->length () <= 1)
+ return false;
+
+ if (opcode != PLUS_EXPR && opcode != MULT_EXPR && opcode != BIT_XOR_EXPR
+ && opcode != BIT_IOR_EXPR && opcode != BIT_AND_EXPR)
+ return false;
+
+ hash_map<tree, v_info_ptr> v_info_map;
+ operand_entry *oe1;
+ unsigned i;
+
+ /* Find those summands from VECTOR BIT_FIELD_REF in addition chain, put the
+ information into map. */
+ FOR_EACH_VEC_ELT (*ops, i, oe1)
+ {
+ enum tree_code dcode;
+ gimple *oe1def;
+
+ if (TREE_CODE (oe1->op) != SSA_NAME)
+ continue;
+ oe1def = SSA_NAME_DEF_STMT (oe1->op);
+ if (!is_gimple_assign (oe1def))
+ continue;
+ dcode = gimple_assign_rhs_code (oe1def);
+ if (dcode != BIT_FIELD_REF || !is_reassociable_op (oe1def, dcode, loop))
+ continue;
+
+ tree rhs = gimple_assign_rhs1 (oe1def);
+ tree vec = TREE_OPERAND (rhs, 0);
+ tree vec_type = TREE_TYPE (vec);
+
+ if (TREE_CODE (vec) != SSA_NAME || !VECTOR_TYPE_P (vec_type))
+ continue;
+
+ /* Ignore it if target machine can't support this VECTOR type. */
+ if (!VECTOR_MODE_P (TYPE_MODE (vec_type)))
+ continue;
+
+ /* Check const vector type, constrain BIT_FIELD_REF offset and size. */
+ if (!TYPE_VECTOR_SUBPARTS (vec_type).is_constant ())
+ continue;
+
+ tree elem_type = TREE_TYPE (vec_type);
+ unsigned HOST_WIDE_INT elem_size
+ = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
+ if (maybe_ne (bit_field_size (rhs), elem_size))
+ continue;
+
+ unsigned idx;
+ if (!constant_multiple_p (bit_field_offset (rhs), elem_size, &idx))
+ continue;
+
+ /* Ignore it if target machine can't support this type of VECTOR
+ operation. */
+ optab op_tab = optab_for_tree_code (opcode, vec_type, optab_vector);
+ if (optab_handler (op_tab, TYPE_MODE (vec_type)) == CODE_FOR_nothing)
+ continue;
+
+ bool existed;
+ v_info_ptr &info = v_info_map.get_or_insert (vec, &existed);
+ if (!existed)
+ info = new v_info;
+ info->safe_push (std::make_pair (idx, i));
+ }
+
+ /* At least two VECTOR to combine. */
+ if (v_info_map.elements () <= 1)
+ {
+ cleanup_vinfo_map (v_info_map);
+ return false;
+ }
+
+ /* Verify all VECTOR candidates by checking two conditions:
+ 1) sorted offsets are adjacent, no holes.
+ 2) can fill the whole VECTOR perfectly.
+ And add the valid candidates to a vector for further handling. */
+ auto_vec<tree> valid_vecs (v_info_map.elements ());
+ for (hash_map<tree, v_info_ptr>::iterator it = v_info_map.begin ();
+ it != v_info_map.end (); ++it)
+ {
+ tree cand_vec = (*it).first;
+ v_info_ptr cand_info = (*it).second;
+ unsigned int num_elems = VECTOR_CST_NELTS (cand_vec).to_constant ();
+ if (cand_info->length () != num_elems)
+ continue;
+ sbitmap holes = sbitmap_alloc (num_elems);
+ bitmap_ones (holes);
+ bool valid = true;
+ v_info_elem *curr;
+ FOR_EACH_VEC_ELT (*cand_info, i, curr)
+ {
+ if (!bitmap_bit_p (holes, curr->first))
+ {
+ valid = false;
+ break;
+ }
+ else
+ bitmap_clear_bit (holes, curr->first);
+ }
+ if (valid && bitmap_empty_p (holes))
+ valid_vecs.quick_push (cand_vec);
+ sbitmap_free (holes);
+ }
+
+ /* At least two VECTOR to combine. */
+ if (valid_vecs.length () <= 1)
+ {
+ cleanup_vinfo_map (v_info_map);
+ return false;
+ }
+
+ valid_vecs.qsort (sort_by_mach_mode);
+ /* Go through all candidates by machine mode order, query the mode_to_total
+ to get the total number for each mode and skip the single one. */
+ for (unsigned i = 0; i < valid_vecs.length () - 1; ++i)
+ {
+ tree tvec = valid_vecs[i];
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (tvec));
+
+ /* Skip modes with only a single candidate. */
+ if (TYPE_MODE (TREE_TYPE (valid_vecs[i + 1])) != mode)
+ continue;
+
+ unsigned int idx, j;
+ gimple *sum = NULL;
+ v_info_ptr info_ptr;
+ tree sum_vec = tvec;
+ v_info_elem *elem;
+
+ /* Build the sum for all candidates with same mode. */
+ do
+ {
+ sum = build_and_add_sum (TREE_TYPE (sum_vec), sum_vec,
+ valid_vecs[i + 1], opcode);
+ sum_vec = gimple_get_lhs (sum);
+ info_ptr = *(v_info_map.get (valid_vecs[i + 1]));
+ /* Update those related ops of current candidate VECTOR. */
+ FOR_EACH_VEC_ELT (*info_ptr, j, elem)
+ {
+ idx = elem->second;
+ gimple *def = SSA_NAME_DEF_STMT ((*ops)[idx]->op);
+ /* Set this then op definition will get DCEd later. */
+ gimple_set_visited (def, true);
+ if (opcode == PLUS_EXPR || opcode == BIT_XOR_EXPR
+ || opcode == BIT_IOR_EXPR)
+ (*ops)[idx]->op = build_zero_cst (TREE_TYPE ((*ops)[idx]->op));
+ else if (opcode == MULT_EXPR)
+ (*ops)[idx]->op = build_one_cst (TREE_TYPE ((*ops)[idx]->op));
+ else
+ {
+ gcc_assert (opcode == BIT_AND_EXPR);
+ (*ops)[idx]->op
+ = build_all_ones_cst (TREE_TYPE ((*ops)[idx]->op));
+ }
+ (*ops)[idx]->rank = 0;
+ }
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Generating addition -> ");
+ print_gimple_stmt (dump_file, sum, 0);
+ }
+ i++;
+ }
+ while ((i < valid_vecs.length () - 1)
+ && TYPE_MODE (TREE_TYPE (valid_vecs[i + 1])) == mode);
+
+ /* Referring to first valid VECTOR with this mode, generate the
+ BIT_FIELD_REF statements accordingly. */
+ info_ptr = *(v_info_map.get (tvec));
+ gcc_assert (sum);
+ tree elem_type = TREE_TYPE (TREE_TYPE (tvec));
+ FOR_EACH_VEC_ELT (*info_ptr, j, elem)
+ {
+ idx = elem->second;
+ tree dst = make_ssa_name (elem_type);
+ gimple *gs = gimple_build_assign (
+ dst, BIT_FIELD_REF,
+ build3 (BIT_FIELD_REF, elem_type, sum_vec, TYPE_SIZE (elem_type),
+ bitsize_int (elem->first
+ * tree_to_uhwi (TYPE_SIZE (elem_type)))));
+ insert_stmt_after (gs, sum);
+ gimple *def = SSA_NAME_DEF_STMT ((*ops)[idx]->op);
+ /* Set this then op definition will get DCEd later. */
+ gimple_set_visited (def, true);
+ (*ops)[idx]->op = gimple_assign_lhs (gs);
+ (*ops)[idx]->rank = get_rank ((*ops)[idx]->op);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Generating bit_field_ref -> ");
+ print_gimple_stmt (dump_file, gs, 0);
+ }
+ }
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "undistributiong bit_field_ref for vector done.\n");
+
+ cleanup_vinfo_map (v_info_map);
+
+ return true;
+}
+
/* If OPCODE is BIT_IOR_EXPR or BIT_AND_EXPR and CURR is a comparison
expression, examine the other OPS to see if any of them are comparisons
of the same values, which we may be able to combine or eliminate.
@@ -3861,7 +4129,7 @@ no_side_effect_bb (basic_block bb)
static bool
get_ops (tree var, enum tree_code code, vec<operand_entry *> *ops,
- struct loop *loop)
+ class loop *loop)
{
gimple *stmt = SSA_NAME_DEF_STMT (var);
tree rhs[2];
@@ -3896,7 +4164,7 @@ get_ops (tree var, enum tree_code code, vec<operand_entry *> *ops,
static tree
update_ops (tree var, enum tree_code code, vec<operand_entry *> ops,
- unsigned int *pidx, struct loop *loop)
+ unsigned int *pidx, class loop *loop)
{
gimple *stmt = SSA_NAME_DEF_STMT (var);
tree rhs[4];
@@ -4834,7 +5102,7 @@ linearize_expr (gimple *stmt)
gimple *oldbinrhs = binrhs;
enum tree_code rhscode = gimple_assign_rhs_code (stmt);
gimple *newbinrhs = NULL;
- struct loop *loop = loop_containing_stmt (stmt);
+ class loop *loop = loop_containing_stmt (stmt);
tree lhs = gimple_assign_lhs (stmt);
gcc_assert (is_reassociable_op (binlhs, rhscode, loop)
@@ -4968,7 +5236,7 @@ should_break_up_subtract (gimple *stmt)
tree binlhs = gimple_assign_rhs1 (stmt);
tree binrhs = gimple_assign_rhs2 (stmt);
gimple *immusestmt;
- struct loop *loop = loop_containing_stmt (stmt);
+ class loop *loop = loop_containing_stmt (stmt);
if (TREE_CODE (binlhs) == SSA_NAME
&& is_reassociable_op (SSA_NAME_DEF_STMT (binlhs), PLUS_EXPR, loop))
@@ -5123,7 +5391,7 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt,
bool binlhsisreassoc = false;
bool binrhsisreassoc = false;
enum tree_code rhscode = gimple_assign_rhs_code (stmt);
- struct loop *loop = loop_containing_stmt (stmt);
+ class loop *loop = loop_containing_stmt (stmt);
if (set_visited)
gimple_set_visited (stmt, true);
@@ -5879,11 +6147,6 @@ reassociate_bb (basic_block bb)
tree lhs, rhs1, rhs2;
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
- /* If this is not a gimple binary expression, there is
- nothing for us to do with it. */
- if (get_gimple_rhs_class (rhs_code) != GIMPLE_BINARY_RHS)
- continue;
-
/* If this was part of an already processed statement,
we don't need to touch it again. */
if (gimple_visited_p (stmt))
@@ -5910,6 +6173,11 @@ reassociate_bb (basic_block bb)
continue;
}
+ /* If this is not a gimple binary expression, there is
+ nothing for us to do with it. */
+ if (get_gimple_rhs_class (rhs_code) != GIMPLE_BINARY_RHS)
+ continue;
+
lhs = gimple_assign_lhs (stmt);
rhs1 = gimple_assign_rhs1 (stmt);
rhs2 = gimple_assign_rhs2 (stmt);
@@ -5948,7 +6216,12 @@ reassociate_bb (basic_block bb)
ops.qsort (sort_by_operand_rank);
optimize_ops_list (rhs_code, &ops);
}
-
+ if (undistribute_bitref_for_vector (rhs_code, &ops,
+ loop_containing_stmt (stmt)))
+ {
+ ops.qsort (sort_by_operand_rank);
+ optimize_ops_list (rhs_code, &ops);
+ }
if (rhs_code == PLUS_EXPR
&& transform_add_to_multiply (&ops))
ops.qsort (sort_by_operand_rank);
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 6b39d63..9369c36 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "splay-tree.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
@@ -69,6 +70,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-loop-niter.h"
+#include "builtins.h"
#include "tree-ssa-sccvn.h"
/* This algorithm is based on the SCC algorithm presented by Keith
@@ -131,8 +133,6 @@ along with GCC; see the file COPYING3. If not see
/* There's no BB_EXECUTABLE but we can use BB_VISITED. */
#define BB_EXECUTABLE BB_VISITED
-static tree *last_vuse_ptr;
-static vn_lookup_kind vn_walk_kind;
static vn_lookup_kind default_vn_walk_kind;
/* vn_nary_op hashtable helpers. */
@@ -362,6 +362,8 @@ static void init_vn_nary_op_from_stmt (vn_nary_op_t, gimple *);
static void init_vn_nary_op_from_pieces (vn_nary_op_t, unsigned int,
enum tree_code, tree, tree *);
static tree vn_lookup_simplify_result (gimple_match_op *);
+static vn_reference_t vn_reference_lookup_or_insert_for_pieces
+ (tree, alias_set_type, tree, vec<vn_reference_op_s, va_heap>, tree);
/* Return whether there is value numbering information for a given SSA name. */
@@ -1648,18 +1650,253 @@ vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
return NULL_TREE;
}
+
+/* Partial definition tracking support. */
+
+struct pd_range
+{
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT size;
+};
+
+struct pd_data
+{
+ tree rhs;
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT size;
+};
+
+/* Context for alias walking. */
+
+struct vn_walk_cb_data
+{
+ vn_walk_cb_data (vn_reference_t vr_, tree orig_ref_, tree *last_vuse_ptr_,
+ vn_lookup_kind vn_walk_kind_, bool tbaa_p_)
+ : vr (vr_), last_vuse_ptr (last_vuse_ptr_),
+ vn_walk_kind (vn_walk_kind_), tbaa_p (tbaa_p_), known_ranges (NULL)
+ {
+ ao_ref_init (&orig_ref, orig_ref_);
+ }
+ ~vn_walk_cb_data ();
+ void *push_partial_def (const pd_data& pd, tree, HOST_WIDE_INT);
+
+ vn_reference_t vr;
+ ao_ref orig_ref;
+ tree *last_vuse_ptr;
+ vn_lookup_kind vn_walk_kind;
+ bool tbaa_p;
+
+ /* The VDEFs of partial defs we come along. */
+ auto_vec<pd_data, 2> partial_defs;
+ /* The first defs range to avoid splay tree setup in most cases. */
+ pd_range first_range;
+ tree first_vuse;
+ splay_tree known_ranges;
+ obstack ranges_obstack;
+};
+
+vn_walk_cb_data::~vn_walk_cb_data ()
+{
+ if (known_ranges)
+ {
+ splay_tree_delete (known_ranges);
+ obstack_free (&ranges_obstack, NULL);
+ }
+}
+
+/* pd_range splay-tree helpers. */
+
+static int
+pd_range_compare (splay_tree_key offset1p, splay_tree_key offset2p)
+{
+ HOST_WIDE_INT offset1 = *(HOST_WIDE_INT *)offset1p;
+ HOST_WIDE_INT offset2 = *(HOST_WIDE_INT *)offset2p;
+ if (offset1 < offset2)
+ return -1;
+ else if (offset1 > offset2)
+ return 1;
+ return 0;
+}
+
+static void *
+pd_tree_alloc (int size, void *data_)
+{
+ vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
+ return obstack_alloc (&data->ranges_obstack, size);
+}
+
+static void
+pd_tree_dealloc (void *, void *)
+{
+}
+
+/* Push PD to the vector of partial definitions returning a
+ value when we are ready to combine things with VUSE and MAXSIZEI,
+ NULL when we want to continue looking for partial defs or -1
+ on failure. */
+
+void *
+vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse,
+ HOST_WIDE_INT maxsizei)
+{
+ if (partial_defs.is_empty ())
+ {
+ partial_defs.safe_push (pd);
+ first_range.offset = pd.offset;
+ first_range.size = pd.size;
+ first_vuse = vuse;
+ last_vuse_ptr = NULL;
+ /* Continue looking for partial defs. */
+ return NULL;
+ }
+
+ if (!known_ranges)
+ {
+ /* ??? Optimize the case where the 2nd partial def completes things. */
+ gcc_obstack_init (&ranges_obstack);
+ known_ranges = splay_tree_new_with_allocator (pd_range_compare, 0, 0,
+ pd_tree_alloc,
+ pd_tree_dealloc, this);
+ splay_tree_insert (known_ranges,
+ (splay_tree_key)&first_range.offset,
+ (splay_tree_value)&first_range);
+ }
+
+ pd_range newr = { pd.offset, pd.size };
+ splay_tree_node n;
+ pd_range *r;
+ /* Lookup the predecessor of offset + 1 and see if we need to merge. */
+ HOST_WIDE_INT loffset = newr.offset + 1;
+ if ((n = splay_tree_predecessor (known_ranges, (splay_tree_key)&loffset))
+ && ((r = (pd_range *)n->value), true)
+ && ranges_known_overlap_p (r->offset, r->size + 1,
+ newr.offset, newr.size))
+ {
+ /* Ignore partial defs already covered. */
+ if (known_subrange_p (newr.offset, newr.size, r->offset, r->size))
+ return NULL;
+ r->size = MAX (r->offset + r->size, newr.offset + newr.size) - r->offset;
+ }
+ else
+ {
+ /* newr.offset wasn't covered yet, insert the range. */
+ r = XOBNEW (&ranges_obstack, pd_range);
+ *r = newr;
+ splay_tree_insert (known_ranges, (splay_tree_key)&r->offset,
+ (splay_tree_value)r);
+ }
+ /* Merge r which now contains newr and is a member of the splay tree with
+ adjacent overlapping ranges. */
+ pd_range *rafter;
+ while ((n = splay_tree_successor (known_ranges, (splay_tree_key)&r->offset))
+ && ((rafter = (pd_range *)n->value), true)
+ && ranges_known_overlap_p (r->offset, r->size + 1,
+ rafter->offset, rafter->size))
+ {
+ r->size = MAX (r->offset + r->size,
+ rafter->offset + rafter->size) - r->offset;
+ splay_tree_remove (known_ranges, (splay_tree_key)&rafter->offset);
+ }
+ partial_defs.safe_push (pd);
+
+ /* Now we have merged newr into the range tree. When we have covered
+ [offseti, sizei] then the tree will contain exactly one node which has
+ the desired properties and it will be 'r'. */
+ if (!known_subrange_p (0, maxsizei / BITS_PER_UNIT, r->offset, r->size))
+ /* Continue looking for partial defs. */
+ return NULL;
+
+ /* Now simply native encode all partial defs in reverse order. */
+ unsigned ndefs = partial_defs.length ();
+ /* We support up to 512-bit values (for V8DFmode). */
+ unsigned char buffer[64];
+ int len;
+
+ while (!partial_defs.is_empty ())
+ {
+ pd_data pd = partial_defs.pop ();
+ if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
+ /* Empty CONSTRUCTOR. */
+ memset (buffer + MAX (0, pd.offset),
+ 0, MIN ((HOST_WIDE_INT)sizeof (buffer),
+ pd.size + MIN (0, pd.offset)));
+ else
+ {
+ unsigned pad = 0;
+ if (BYTES_BIG_ENDIAN
+ && is_a <scalar_mode> (TYPE_MODE (TREE_TYPE (pd.rhs))))
+ {
+ /* On big-endian the padding is at the 'front' so just skip
+ the initial bytes. */
+ fixed_size_mode mode
+ = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (pd.rhs)));
+ pad = GET_MODE_SIZE (mode) - pd.size;
+ }
+ len = native_encode_expr (pd.rhs, buffer + MAX (0, pd.offset),
+ sizeof (buffer - MAX (0, pd.offset)),
+ MAX (0, -pd.offset) + pad);
+ if (len <= 0 || len < (pd.size - MAX (0, -pd.offset)))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Failed to encode %u "
+ "partial definitions\n", ndefs);
+ return (void *)-1;
+ }
+ }
+ }
+
+ tree type = vr->type;
+ /* Make sure to interpret in a type that has a range covering the whole
+ access size. */
+ if (INTEGRAL_TYPE_P (vr->type) && maxsizei != TYPE_PRECISION (vr->type))
+ type = build_nonstandard_integer_type (maxsizei, TYPE_UNSIGNED (type));
+ tree val = native_interpret_expr (type, buffer, maxsizei / BITS_PER_UNIT);
+ /* If we chop off bits because the types precision doesn't match the memory
+ access size this is ok when optimizing reads but not when called from
+ the DSE code during elimination. */
+ if (val && type != vr->type)
+ {
+ if (! int_fits_type_p (val, vr->type))
+ val = NULL_TREE;
+ else
+ val = fold_convert (vr->type, val);
+ }
+
+ if (val)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Successfully combined %u partial definitions\n", ndefs);
+ return vn_reference_lookup_or_insert_for_pieces
+ (first_vuse, vr->set, vr->type, vr->operands, val);
+ }
+ else
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "Failed to interpret %u encoded partial definitions\n", ndefs);
+ return (void *)-1;
+ }
+}
+
/* Callback for walk_non_aliased_vuses. Adjusts the vn_reference_t VR_
with the current VUSE and performs the expression lookup. */
static void *
-vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse, void *vr_)
+vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse, void *data_)
{
- vn_reference_t vr = (vn_reference_t)vr_;
+ vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
+ vn_reference_t vr = data->vr;
vn_reference_s **slot;
hashval_t hash;
- if (last_vuse_ptr)
- *last_vuse_ptr = vuse;
+ /* If we have partial definitions recorded we have to go through
+ vn_reference_lookup_3. */
+ if (!data->partial_defs.is_empty ())
+ return NULL;
+
+ if (data->last_vuse_ptr)
+ *data->last_vuse_ptr = vuse;
/* Fixup vuse and hash. */
if (vr->vuse)
@@ -1718,21 +1955,25 @@ vn_nary_build_or_lookup_1 (gimple_match_op *res_op, bool insert)
RCODE (OPS...).
So first simplify and lookup this expression to see if it
is already available. */
- mprts_hook = vn_lookup_simplify_result;
+ /* For simplification valueize. */
+ unsigned i;
+ for (i = 0; i < res_op->num_ops; ++i)
+ if (TREE_CODE (res_op->ops[i]) == SSA_NAME)
+ {
+ tree tem = vn_valueize (res_op->ops[i]);
+ if (!tem)
+ break;
+ res_op->ops[i] = tem;
+ }
+ /* If valueization of an operand fails (it is not available), skip
+ simplification. */
bool res = false;
- switch (TREE_CODE_LENGTH ((tree_code) res_op->code))
+ if (i == res_op->num_ops)
{
- case 1:
- res = gimple_resimplify1 (NULL, res_op, vn_valueize);
- break;
- case 2:
- res = gimple_resimplify2 (NULL, res_op, vn_valueize);
- break;
- case 3:
- res = gimple_resimplify3 (NULL, res_op, vn_valueize);
- break;
+ mprts_hook = vn_lookup_simplify_result;
+ res = res_op->resimplify (NULL, vn_valueize);
+ mprts_hook = NULL;
}
- mprts_hook = NULL;
gimple *new_stmt = NULL;
if (res
&& gimple_simplified_result_is_gimple_val (res_op))
@@ -1921,6 +2162,33 @@ public:
static rpo_elim *rpo_avail;
basic_block vn_context_bb;
+/* Return true if BASE1 and BASE2 can be adjusted so they have the
+ same address and adjust *OFFSET1 and *OFFSET2 accordingly.
+ Otherwise return false. */
+
+static bool
+adjust_offsets_for_equal_base_address (tree base1, poly_int64 *offset1,
+ tree base2, poly_int64 *offset2)
+{
+ poly_int64 soff;
+ if (TREE_CODE (base1) == MEM_REF
+ && TREE_CODE (base2) == MEM_REF)
+ {
+ if (mem_ref_offset (base1).to_shwi (&soff))
+ {
+ base1 = TREE_OPERAND (base1, 0);
+ *offset1 += soff * BITS_PER_UNIT;
+ }
+ if (mem_ref_offset (base2).to_shwi (&soff))
+ {
+ base2 = TREE_OPERAND (base2, 0);
+ *offset2 += soff * BITS_PER_UNIT;
+ }
+ return operand_equal_p (base1, base2, 0);
+ }
+ return operand_equal_p (base1, base2, OEP_ADDRESS_OF);
+}
+
/* Callback for walk_non_aliased_vuses. Tries to perform a lookup
from the statement defining VUSE and if not successful tries to
translate *REFP and VR_ through an aggregate copy at the definition
@@ -1929,10 +2197,11 @@ basic_block vn_context_bb;
*DISAMBIGUATE_ONLY is set to true. */
static void *
-vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
+vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
bool *disambiguate_only)
{
- vn_reference_t vr = (vn_reference_t)vr_;
+ vn_walk_cb_data *data = (vn_walk_cb_data *)data_;
+ vn_reference_t vr = data->vr;
gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
tree base = ao_ref_base (ref);
HOST_WIDE_INT offseti, maxsizei;
@@ -1959,7 +2228,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
get_alias_set (lhs),
TREE_TYPE (lhs), lhs_ops);
if (lhs_ref_ok
- && !refs_may_alias_p_1 (ref, &lhs_ref, true))
+ && !refs_may_alias_p_1 (ref, &lhs_ref, data->tbaa_p))
{
*disambiguate_only = true;
return NULL;
@@ -1971,43 +2240,61 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
lhs_ref_ok = true;
}
+ /* Besides valueizing the LHS we can also use access-path based
+ disambiguation on the original non-valueized ref. */
+ if (!ref->ref
+ && lhs_ref_ok
+ && data->orig_ref.ref)
+ {
+ /* We want to use the non-valueized LHS for this, but avoid redundant
+ work. */
+ ao_ref *lref = &lhs_ref;
+ ao_ref lref_alt;
+ if (valueized_anything)
+ {
+ ao_ref_init (&lref_alt, lhs);
+ lref = &lref_alt;
+ }
+ if (!refs_may_alias_p_1 (&data->orig_ref, lref, data->tbaa_p))
+ {
+ *disambiguate_only = true;
+ return NULL;
+ }
+ }
+
/* If we reach a clobbering statement try to skip it and see if
we find a VN result with exactly the same value as the
possible clobber. In this case we can ignore the clobber
- and return the found value.
- Note that we don't need to worry about partial overlapping
- accesses as we then can use TBAA to disambiguate against the
- clobbering statement when looking up a load (thus the
- VN_WALKREWRITE guard). */
- if (vn_walk_kind == VN_WALKREWRITE
- && is_gimple_reg_type (TREE_TYPE (lhs))
+ and return the found value. */
+ if (is_gimple_reg_type (TREE_TYPE (lhs))
&& types_compatible_p (TREE_TYPE (lhs), vr->type)
- /* The overlap restriction breaks down when either access
- alias-set is zero. Still for accesses of the size of
- an addressable unit there can be no overlaps. Overlaps
- between different union members are not an issue since
- activation of a union member via a store makes the
- values of untouched bytes unspecified. */
- && (known_eq (ref->size, BITS_PER_UNIT)
- || (get_alias_set (lhs) != 0
- && ao_ref_alias_set (ref) != 0)))
+ && ref->ref)
{
- tree *saved_last_vuse_ptr = last_vuse_ptr;
+ tree *saved_last_vuse_ptr = data->last_vuse_ptr;
/* Do not update last_vuse_ptr in vn_reference_lookup_2. */
- last_vuse_ptr = NULL;
+ data->last_vuse_ptr = NULL;
tree saved_vuse = vr->vuse;
hashval_t saved_hashcode = vr->hashcode;
- void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt), vr);
+ void *res = vn_reference_lookup_2 (ref, gimple_vuse (def_stmt), data);
/* Need to restore vr->vuse and vr->hashcode. */
vr->vuse = saved_vuse;
vr->hashcode = saved_hashcode;
- last_vuse_ptr = saved_last_vuse_ptr;
+ data->last_vuse_ptr = saved_last_vuse_ptr;
if (res && res != (void *)-1)
{
vn_reference_t vnresult = (vn_reference_t) res;
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ rhs = SSA_VAL (rhs);
if (vnresult->result
- && operand_equal_p (vnresult->result,
- gimple_assign_rhs1 (def_stmt), 0))
+ && operand_equal_p (vnresult->result, rhs, 0)
+ /* We have to honor our promise about union type punning
+ and also support arbitrary overlaps with
+ -fno-strict-aliasing. So simply resort to alignment to
+ rule out overlaps. Do this check last because it is
+ quite expensive compared to the hash-lookup above. */
+ && multiple_p (get_object_alignment (ref->ref), ref->size)
+ && multiple_p (get_object_alignment (lhs), ref->size))
return res;
}
}
@@ -2047,7 +2334,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
}
}
- if (*disambiguate_only)
+ /* If we are looking for redundant stores do not create new hashtable
+ entries from aliasing defs with made up alias-sets. */
+ if (*disambiguate_only || !data->tbaa_p)
return (void *)-1;
/* If we cannot constrain the size of the reference we cannot
@@ -2133,8 +2422,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
else
return (void *)-1;
tree len = gimple_call_arg (def_stmt, 2);
- if (known_subrange_p (offset, maxsize, offset2,
- wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
+ HOST_WIDE_INT leni, offset2i, offseti;
+ if (data->partial_defs.is_empty ()
+ && known_subrange_p (offset, maxsize, offset2,
+ wi::to_poly_offset (len) << LOG2_BITS_PER_UNIT))
{
tree val;
if (integer_zerop (gimple_call_arg (def_stmt, 1)))
@@ -2163,6 +2454,20 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
return vn_reference_lookup_or_insert_for_pieces
(vuse, vr->set, vr->type, vr->operands, val);
}
+ /* For now handle clearing memory with partial defs. */
+ else if (known_eq (ref->size, maxsize)
+ && integer_zerop (gimple_call_arg (def_stmt, 1))
+ && tree_to_poly_int64 (len).is_constant (&leni)
+ && offset.is_constant (&offseti)
+ && offset2.is_constant (&offset2i)
+ && maxsize.is_constant (&maxsizei))
+ {
+ pd_data pd;
+ pd.rhs = build_constructor (NULL_TREE, NULL);
+ pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
+ pd.size = leni;
+ return data->push_partial_def (pd, vuse, maxsizei);
+ }
}
/* 2) Assignment from an empty CONSTRUCTOR. */
@@ -2171,19 +2476,50 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
&& gimple_assign_rhs_code (def_stmt) == CONSTRUCTOR
&& CONSTRUCTOR_NELTS (gimple_assign_rhs1 (def_stmt)) == 0)
{
+ tree lhs = gimple_assign_lhs (def_stmt);
tree base2;
poly_int64 offset2, size2, maxsize2;
+ HOST_WIDE_INT offset2i, size2i;
bool reverse;
- base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
- &offset2, &size2, &maxsize2, &reverse);
+ if (lhs_ref_ok)
+ {
+ base2 = ao_ref_base (&lhs_ref);
+ offset2 = lhs_ref.offset;
+ size2 = lhs_ref.size;
+ maxsize2 = lhs_ref.max_size;
+ reverse = reverse_storage_order_for_component_p (lhs);
+ }
+ else
+ base2 = get_ref_base_and_extent (lhs,
+ &offset2, &size2, &maxsize2, &reverse);
if (known_size_p (maxsize2)
&& known_eq (maxsize2, size2)
- && operand_equal_p (base, base2, 0)
- && known_subrange_p (offset, maxsize, offset2, size2))
+ && adjust_offsets_for_equal_base_address (base, &offset,
+ base2, &offset2))
{
- tree val = build_zero_cst (vr->type);
- return vn_reference_lookup_or_insert_for_pieces
- (vuse, vr->set, vr->type, vr->operands, val);
+ if (data->partial_defs.is_empty ()
+ && known_subrange_p (offset, maxsize, offset2, size2))
+ {
+ tree val = build_zero_cst (vr->type);
+ return vn_reference_lookup_or_insert_for_pieces
+ (vuse, vr->set, vr->type, vr->operands, val);
+ }
+ else if (known_eq (ref->size, maxsize)
+ && maxsize.is_constant (&maxsizei)
+ && maxsizei % BITS_PER_UNIT == 0
+ && offset.is_constant (&offseti)
+ && offseti % BITS_PER_UNIT == 0
+ && offset2.is_constant (&offset2i)
+ && offset2i % BITS_PER_UNIT == 0
+ && size2.is_constant (&size2i)
+ && size2i % BITS_PER_UNIT == 0)
+ {
+ pd_data pd;
+ pd.rhs = gimple_assign_rhs1 (def_stmt);
+ pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
+ pd.size = size2i / BITS_PER_UNIT;
+ return data->push_partial_def (pd, vuse, maxsizei);
+ }
}
}
@@ -2204,55 +2540,96 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
|| (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
&& is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
{
+ tree lhs = gimple_assign_lhs (def_stmt);
tree base2;
- HOST_WIDE_INT offset2, size2;
+ poly_int64 offset2, size2, maxsize2;
+ HOST_WIDE_INT offset2i, size2i;
bool reverse;
- base2 = get_ref_base_and_extent_hwi (gimple_assign_lhs (def_stmt),
- &offset2, &size2, &reverse);
+ if (lhs_ref_ok)
+ {
+ base2 = ao_ref_base (&lhs_ref);
+ offset2 = lhs_ref.offset;
+ size2 = lhs_ref.size;
+ maxsize2 = lhs_ref.max_size;
+ reverse = reverse_storage_order_for_component_p (lhs);
+ }
+ else
+ base2 = get_ref_base_and_extent (lhs,
+ &offset2, &size2, &maxsize2, &reverse);
if (base2
&& !reverse
- && size2 % BITS_PER_UNIT == 0
- && offset2 % BITS_PER_UNIT == 0
- && operand_equal_p (base, base2, 0)
- && known_subrange_p (offseti, maxsizei, offset2, size2))
+ && known_eq (maxsize2, size2)
+ && multiple_p (size2, BITS_PER_UNIT)
+ && multiple_p (offset2, BITS_PER_UNIT)
+ && adjust_offsets_for_equal_base_address (base, &offset,
+ base2, &offset2)
+ && offset.is_constant (&offseti)
+ && offset2.is_constant (&offset2i)
+ && size2.is_constant (&size2i))
{
- /* We support up to 512-bit values (for V8DFmode). */
- unsigned char buffer[64];
- int len;
-
- tree rhs = gimple_assign_rhs1 (def_stmt);
- if (TREE_CODE (rhs) == SSA_NAME)
- rhs = SSA_VAL (rhs);
- len = native_encode_expr (rhs,
- buffer, sizeof (buffer),
- (offseti - offset2) / BITS_PER_UNIT);
- if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
+ if (data->partial_defs.is_empty ()
+ && known_subrange_p (offseti, maxsizei, offset2, size2))
{
- tree type = vr->type;
- /* Make sure to interpret in a type that has a range
- covering the whole access size. */
- if (INTEGRAL_TYPE_P (vr->type)
- && maxsizei != TYPE_PRECISION (vr->type))
- type = build_nonstandard_integer_type (maxsizei,
- TYPE_UNSIGNED (type));
- tree val = native_interpret_expr (type, buffer,
- maxsizei / BITS_PER_UNIT);
- /* If we chop off bits because the types precision doesn't
- match the memory access size this is ok when optimizing
- reads but not when called from the DSE code during
- elimination. */
- if (val
- && type != vr->type)
+ /* We support up to 512-bit values (for V8DFmode). */
+ unsigned char buffer[64];
+ int len;
+
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ rhs = SSA_VAL (rhs);
+ unsigned pad = 0;
+ if (BYTES_BIG_ENDIAN
+ && is_a <scalar_mode> (TYPE_MODE (TREE_TYPE (rhs))))
{
- if (! int_fits_type_p (val, vr->type))
- val = NULL_TREE;
- else
- val = fold_convert (vr->type, val);
+ /* On big-endian the padding is at the 'front' so
+ just skip the initial bytes. */
+ fixed_size_mode mode
+ = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (rhs)));
+ pad = GET_MODE_SIZE (mode) - size2i / BITS_PER_UNIT;
}
+ len = native_encode_expr (rhs,
+ buffer, sizeof (buffer),
+ ((offseti - offset2i) / BITS_PER_UNIT
+ + pad));
+ if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
+ {
+ tree type = vr->type;
+ /* Make sure to interpret in a type that has a range
+ covering the whole access size. */
+ if (INTEGRAL_TYPE_P (vr->type)
+ && maxsizei != TYPE_PRECISION (vr->type))
+ type = build_nonstandard_integer_type (maxsizei,
+ TYPE_UNSIGNED (type));
+ tree val = native_interpret_expr (type, buffer,
+ maxsizei / BITS_PER_UNIT);
+ /* If we chop off bits because the types precision doesn't
+ match the memory access size this is ok when optimizing
+ reads but not when called from the DSE code during
+ elimination. */
+ if (val
+ && type != vr->type)
+ {
+ if (! int_fits_type_p (val, vr->type))
+ val = NULL_TREE;
+ else
+ val = fold_convert (vr->type, val);
+ }
- if (val)
- return vn_reference_lookup_or_insert_for_pieces
- (vuse, vr->set, vr->type, vr->operands, val);
+ if (val)
+ return vn_reference_lookup_or_insert_for_pieces
+ (vuse, vr->set, vr->type, vr->operands, val);
+ }
+ }
+ else if (ranges_known_overlap_p (offseti, maxsizei, offset2i, size2i))
+ {
+ pd_data pd;
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ rhs = SSA_VAL (rhs);
+ pd.rhs = rhs;
+ pd.offset = (offset2i - offseti) / BITS_PER_UNIT;
+ pd.size = size2i / BITS_PER_UNIT;
+ return data->push_partial_def (pd, vuse, maxsizei);
}
}
}
@@ -2263,19 +2640,34 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
&& is_gimple_reg_type (vr->type)
&& !contains_storage_order_barrier_p (vr->operands)
&& gimple_assign_single_p (def_stmt)
- && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
+ && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
+ /* A subset of partial defs from non-constants can be handled
+ by for example inserting a CONSTRUCTOR, a COMPLEX_EXPR or
+ even a (series of) BIT_INSERT_EXPR hoping for simplifications
+ downstream, not so much for actually doing the insertion. */
+ && data->partial_defs.is_empty ())
{
+ tree lhs = gimple_assign_lhs (def_stmt);
tree base2;
poly_int64 offset2, size2, maxsize2;
bool reverse;
- base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
- &offset2, &size2, &maxsize2,
- &reverse);
+ if (lhs_ref_ok)
+ {
+ base2 = ao_ref_base (&lhs_ref);
+ offset2 = lhs_ref.offset;
+ size2 = lhs_ref.size;
+ maxsize2 = lhs_ref.max_size;
+ reverse = reverse_storage_order_for_component_p (lhs);
+ }
+ else
+ base2 = get_ref_base_and_extent (lhs,
+ &offset2, &size2, &maxsize2, &reverse);
tree def_rhs = gimple_assign_rhs1 (def_stmt);
if (!reverse
&& known_size_p (maxsize2)
&& known_eq (maxsize2, size2)
- && operand_equal_p (base, base2, 0)
+ && adjust_offsets_for_equal_base_address (base, &offset,
+ base2, &offset2)
&& known_subrange_p (offset, maxsize, offset2, size2)
/* ??? We can't handle bitfield precision extracts without
either using an alternate type for the BIT_FIELD_REF and
@@ -2306,7 +2698,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
/* 5) For aggregate copies translate the reference through them if
the copy kills ref. */
- else if (vn_walk_kind == VN_WALKREWRITE
+ else if (data->vn_walk_kind == VN_WALKREWRITE
&& gimple_assign_single_p (def_stmt)
&& (DECL_P (gimple_assign_rhs1 (def_stmt))
|| TREE_CODE (gimple_assign_rhs1 (def_stmt)) == MEM_REF
@@ -2414,8 +2806,30 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
/* Try folding the new reference to a constant. */
tree val = fully_constant_vn_reference_p (vr);
if (val)
- return vn_reference_lookup_or_insert_for_pieces
- (vuse, vr->set, vr->type, vr->operands, val);
+ {
+ if (data->partial_defs.is_empty ())
+ return vn_reference_lookup_or_insert_for_pieces
+ (vuse, vr->set, vr->type, vr->operands, val);
+ /* This is the only interesting case for partial-def handling
+ coming from targets that like to gimplify init-ctors as
+ aggregate copies from constant data like aarch64 for
+ PR83518. */
+ if (maxsize.is_constant (&maxsizei)
+ && known_eq (ref->size, maxsize))
+ {
+ pd_data pd;
+ pd.rhs = val;
+ pd.offset = 0;
+ pd.size = maxsizei / BITS_PER_UNIT;
+ return data->push_partial_def (pd, vuse, maxsizei);
+ }
+ }
+
+ /* Continuing with partial defs isn't easily possible here, we
+ have to find a full def from further lookups from here. Probably
+ not worth the special-casing everywhere. */
+ if (!data->partial_defs.is_empty ())
+ return (void *)-1;
/* Adjust *ref from the new operands. */
if (!ao_ref_init_from_vn_reference (&r, vr->set, vr->type, vr->operands))
@@ -2426,7 +2840,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
*ref = r;
/* Do not update last seen VUSE after translating. */
- last_vuse_ptr = NULL;
+ data->last_vuse_ptr = NULL;
+ /* Invalidate the original access path since it now contains
+ the wrong base. */
+ data->orig_ref.ref = NULL_TREE;
/* Keep looking for the adjusted *REF / VR pair. */
return NULL;
@@ -2434,7 +2851,7 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
/* 6) For memcpy copies translate the reference through them if
the copy kills ref. */
- else if (vn_walk_kind == VN_WALKREWRITE
+ else if (data->vn_walk_kind == VN_WALKREWRITE
&& is_gimple_reg_type (vr->type)
/* ??? Handle BCOPY as well. */
&& (gimple_call_builtin_p (def_stmt, BUILT_IN_MEMCPY)
@@ -2444,7 +2861,9 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
|| TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)
&& (TREE_CODE (gimple_call_arg (def_stmt, 1)) == ADDR_EXPR
|| TREE_CODE (gimple_call_arg (def_stmt, 1)) == SSA_NAME)
- && poly_int_tree_p (gimple_call_arg (def_stmt, 2), &copy_size))
+ && poly_int_tree_p (gimple_call_arg (def_stmt, 2), &copy_size)
+ /* Handling this is more complicated, give up for now. */
+ && data->partial_defs.is_empty ())
{
tree lhs, rhs;
ao_ref r;
@@ -2584,7 +3003,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
*ref = r;
/* Do not update last seen VUSE after translating. */
- last_vuse_ptr = NULL;
+ data->last_vuse_ptr = NULL;
+ /* Invalidate the original access path since it now contains
+ the wrong base. */
+ data->orig_ref.ref = NULL_TREE;
/* Keep looking for the adjusted *REF / VR pair. */
return NULL;
@@ -2645,13 +3067,13 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, tree type,
{
ao_ref r;
unsigned limit = PARAM_VALUE (PARAM_SCCVN_MAX_ALIAS_QUERIES_PER_ACCESS);
- vn_walk_kind = kind;
+ vn_walk_cb_data data (&vr1, NULL_TREE, NULL, kind, true);
if (ao_ref_init_from_vn_reference (&r, set, type, vr1.operands))
*vnresult =
- (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
+ (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, true,
vn_reference_lookup_2,
vn_reference_lookup_3,
- vuse_valueize, limit, &vr1);
+ vuse_valueize, limit, &data);
gcc_checking_assert (vr1.operands == shared_lookup_references);
}
@@ -2666,11 +3088,12 @@ vn_reference_lookup_pieces (tree vuse, alias_set_type set, tree type,
not exist in the hash table or if the result field of the structure
was NULL.. VNRESULT will be filled in with the vn_reference_t
stored in the hashtable if one exists. When TBAA_P is false assume
- we are looking up a store and treat it as having alias-set zero. */
+ we are looking up a store and treat it as having alias-set zero.
+ *LAST_VUSE_PTR will be updated with the VUSE the value lookup succeeded. */
tree
vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
- vn_reference_t *vnresult, bool tbaa_p)
+ vn_reference_t *vnresult, bool tbaa_p, tree *last_vuse_ptr)
{
vec<vn_reference_op_s> operands;
struct vn_reference_s vr1;
@@ -2684,7 +3107,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
vr1.operands = operands
= valueize_shared_reference_ops_from_ref (op, &valuezied_anything);
vr1.type = TREE_TYPE (op);
- vr1.set = tbaa_p ? get_alias_set (op) : 0;
+ vr1.set = get_alias_set (op);
vr1.hashcode = vn_reference_compute_hash (&vr1);
if ((cst = fully_constant_vn_reference_p (&vr1)))
return cst;
@@ -2701,14 +3124,13 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
|| !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type,
vr1.operands))
ao_ref_init (&r, op);
- if (! tbaa_p)
- r.ref_alias_set = r.base_alias_set = 0;
- vn_walk_kind = kind;
+ vn_walk_cb_data data (&vr1, r.ref ? NULL_TREE : op,
+ last_vuse_ptr, kind, tbaa_p);
wvnresult =
- (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
+ (vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse, tbaa_p,
vn_reference_lookup_2,
vn_reference_lookup_3,
- vuse_valueize, limit, &vr1);
+ vuse_valueize, limit, &data);
gcc_checking_assert (vr1.operands == shared_lookup_references);
if (wvnresult)
{
@@ -4063,10 +4485,8 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
tree result;
last_vuse = gimple_vuse (stmt);
- last_vuse_ptr = &last_vuse;
result = vn_reference_lookup (op, gimple_vuse (stmt),
- default_vn_walk_kind, NULL, true);
- last_vuse_ptr = NULL;
+ default_vn_walk_kind, NULL, true, &last_vuse);
/* We handle type-punning through unions by value-numbering based
on offset and size of the access. Be prepared to handle a
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index bd661bc..93718b2 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -234,7 +234,8 @@ vec<vn_reference_op_s> vn_reference_operands_for_lookup (tree);
tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
vec<vn_reference_op_s> ,
vn_reference_t *, vn_lookup_kind);
-tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *, bool);
+tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *, bool,
+ tree * = NULL);
void vn_reference_lookup_call (gcall *, vn_reference_t *, vn_reference_t);
vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
vec<vn_reference_op_s> ,
diff --git a/gcc/tree-ssa-scopedtables.c b/gcc/tree-ssa-scopedtables.c
index 50413eb..574bc30 100644
--- a/gcc/tree-ssa-scopedtables.c
+++ b/gcc/tree-ssa-scopedtables.c
@@ -298,7 +298,7 @@ avail_exprs_stack::lookup_avail_expr (gimple *stmt, bool insert, bool tbaa_p)
&& TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
&& (ao_ref_init (&ref, gimple_assign_rhs1 (stmt)),
ref.base_alias_set = ref.ref_alias_set = tbaa_p ? -1 : 0, true)
- && walk_non_aliased_vuses (&ref, vuse2, vuse_eq, NULL, NULL,
+ && walk_non_aliased_vuses (&ref, vuse2, true, vuse_eq, NULL, NULL,
limit, vuse1) != NULL))
{
if (insert)
@@ -1028,9 +1028,9 @@ bool
expr_elt_hasher::equal (const value_type &p1, const compare_type &p2)
{
const struct hashable_expr *expr1 = p1->expr ();
- const struct expr_hash_elt *stamp1 = p1->stamp ();
+ const class expr_hash_elt *stamp1 = p1->stamp ();
const struct hashable_expr *expr2 = p2->expr ();
- const struct expr_hash_elt *stamp2 = p2->stamp ();
+ const class expr_hash_elt *stamp2 = p2->stamp ();
/* This case should apply only when removing entries from the table. */
if (stamp1 == stamp2)
diff --git a/gcc/tree-ssa-scopedtables.h b/gcc/tree-ssa-scopedtables.h
index 2328d1c..4818500 100644
--- a/gcc/tree-ssa-scopedtables.h
+++ b/gcc/tree-ssa-scopedtables.h
@@ -96,7 +96,7 @@ class expr_hash_elt
/* A unique stamp, typically the address of the hash
element itself, used in removing entries from the table. */
- struct expr_hash_elt *m_stamp;
+ class expr_hash_elt *m_stamp;
/* We should never be making assignments between objects in this class.
Though it might allow us to exploit C++11 move semantics if we
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 74cd6c4..88b6bd7 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -3462,34 +3462,38 @@ handle_char_store (gimple_stmt_iterator *gsi)
return false;
}
}
- /* If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
- and if we aren't storing '\0', we know that the length of the
- string and any other zero terminated string in memory remains
- the same. In that case we move to the next gimple statement and
- return to signal the caller that it shouldn't invalidate anything.
-
- This is benefical for cases like:
-
- char p[20];
- void foo (char *q)
- {
- strcpy (p, "foobar");
- size_t len = strlen (p); // This can be optimized into 6
- size_t len2 = strlen (q); // This has to be computed
- p[0] = 'X';
- size_t len3 = strlen (p); // This can be optimized into 6
- size_t len4 = strlen (q); // This can be optimized into len2
- bar (len, len2, len3, len4);
- }
- */
- else if (storing_nonzero_p && cmp > 0)
+
+ if (cmp > 0
+ && storing_nonzero_p
+ && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)
{
+ /* Handle a single non-nul character store.
+ If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
+ and if we aren't storing '\0', we know that the length of the
+ string and any other zero terminated string in memory remains
+ the same. In that case we move to the next gimple statement and
+ return to signal the caller that it shouldn't invalidate anything.
+
+ This is benefical for cases like:
+
+ char p[20];
+ void foo (char *q)
+ {
+ strcpy (p, "foobar");
+ size_t len = strlen (p); // can be folded to 6
+ size_t len2 = strlen (q); // has to be computed
+ p[0] = 'X';
+ size_t len3 = strlen (p); // can be folded to 6
+ size_t len4 = strlen (q); // can be folded to len2
+ bar (len, len2, len3, len4);
+ } */
gsi_next (gsi);
return false;
}
- else if (storing_all_zeros_p
- || storing_nonzero_p
- || (offset != 0 && cmp > 0))
+
+ if (storing_all_zeros_p
+ || storing_nonzero_p
+ || (offset != 0 && cmp > 0))
{
/* When STORING_NONZERO_P, we know that the string will start
with at least OFFSET + 1 nonzero characters. If storing
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 29688d2..f8962d6 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -1393,8 +1393,9 @@ static bitmap changed;
/* Strongly Connected Component visitation info. */
-struct scc_info
+class scc_info
{
+public:
scc_info (size_t size);
~scc_info ();
@@ -1419,7 +1420,7 @@ struct scc_info
number 1, pages 9-14. */
static void
-scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
+scc_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
{
unsigned int i;
bitmap_iterator bi;
@@ -2022,7 +2023,7 @@ static int location_equiv_class;
and label it's nodes with DFS numbers. */
static void
-condense_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
+condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
{
unsigned int i;
bitmap_iterator bi;
@@ -2127,7 +2128,7 @@ condense_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
3. Hashable. */
static void
-label_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
+label_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
{
unsigned int i, first_pred;
bitmap_iterator bi;
@@ -2214,7 +2215,7 @@ label_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
/* Print the pred graph in dot format. */
static void
-dump_pred_graph (struct scc_info *si, FILE *file)
+dump_pred_graph (class scc_info *si, FILE *file)
{
unsigned int i;
@@ -2289,7 +2290,7 @@ dump_pred_graph (struct scc_info *si, FILE *file)
/* Perform offline variable substitution, discovering equivalence
classes, and eliminating non-pointer variables. */
-static struct scc_info *
+static class scc_info *
perform_var_substitution (constraint_graph_t graph)
{
unsigned int i;
@@ -2423,7 +2424,7 @@ perform_var_substitution (constraint_graph_t graph)
substitution. */
static void
-free_var_substitution_info (struct scc_info *si)
+free_var_substitution_info (class scc_info *si)
{
delete si;
free (graph->pointer_label);
@@ -2547,7 +2548,7 @@ move_complex_constraints (constraint_graph_t graph)
static void
rewrite_constraints (constraint_graph_t graph,
- struct scc_info *si)
+ class scc_info *si)
{
int i;
constraint_t c;
@@ -7183,7 +7184,7 @@ remove_preds_and_fake_succs (constraint_graph_t graph)
static void
solve_constraints (void)
{
- struct scc_info *si;
+ class scc_info *si;
/* Sort varinfos so that ones that cannot be pointed to are last.
This makes bitmaps more efficient. */
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index a56ccfb..51a316a 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -1556,7 +1556,7 @@ dbds_continue_enumeration_p (const_basic_block bb, const void *stop)
returns the state. */
enum bb_dom_status
-determine_bb_domination_status (struct loop *loop, basic_block bb)
+determine_bb_domination_status (class loop *loop, basic_block bb)
{
basic_block *bblocks;
unsigned nblocks, i;
@@ -1614,7 +1614,7 @@ determine_bb_domination_status (struct loop *loop, basic_block bb)
to the inside of the loop. */
static bool
-thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers)
+thread_through_loop_header (class loop *loop, bool may_peel_loop_headers)
{
basic_block header = loop->header;
edge e, tgt_edge, latch = loop_latch_edge (loop);
@@ -2317,7 +2317,7 @@ duplicate_thread_path (edge entry, edge exit, basic_block *region,
unsigned n_region, unsigned current_path_no)
{
unsigned i;
- struct loop *loop = entry->dest->loop_father;
+ class loop *loop = entry->dest->loop_father;
edge exit_copy;
edge redirected;
profile_count curr_count;
@@ -2517,7 +2517,7 @@ thread_through_all_blocks (bool may_peel_loop_headers)
{
bool retval = false;
unsigned int i;
- struct loop *loop;
+ class loop *loop;
auto_bitmap threaded_blocks;
hash_set<edge> visited_starting_edges;
diff --git a/gcc/tree-ssa-threadupdate.h b/gcc/tree-ssa-threadupdate.h
index d66e8e0..dc6de2f 100644
--- a/gcc/tree-ssa-threadupdate.h
+++ b/gcc/tree-ssa-threadupdate.h
@@ -59,6 +59,6 @@ enum bb_dom_status
DOMST_DOMINATING
};
-enum bb_dom_status determine_bb_domination_status (struct loop *, basic_block);
+enum bb_dom_status determine_bb_domination_status (class loop *, basic_block);
#endif
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 16eaa8e..b4b5c90 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -559,20 +559,25 @@ release_defs_bitset (bitmap toremove)
/* Performing a topological sort is probably overkill, this will
most likely run in slightly superlinear time, rather than the
- pathological quadratic worst case. */
+ pathological quadratic worst case.
+ But iterate from max SSA name version to min one because
+ that mimics allocation order during code generation behavior best.
+ Use an array for this which we compact on-the-fly with a NULL
+ marker moving towards the end of the vector. */
+ auto_vec<tree, 16> names;
+ names.reserve (bitmap_count_bits (toremove) + 1);
+ names.quick_push (NULL_TREE);
+ EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
+ names.quick_push (ssa_name (j));
+
+ bitmap_tree_view (toremove);
while (!bitmap_empty_p (toremove))
{
- unsigned to_remove_bit = -1U;
- EXECUTE_IF_SET_IN_BITMAP (toremove, 0, j, bi)
+ j = names.length () - 1;
+ for (unsigned i = names.length () - 1; names[i];)
{
- if (to_remove_bit != -1U)
- {
- bitmap_clear_bit (toremove, to_remove_bit);
- to_remove_bit = -1U;
- }
-
bool remove_now = true;
- tree var = ssa_name (j);
+ tree var = names[i];
gimple *stmt;
imm_use_iterator uit;
@@ -617,14 +622,15 @@ release_defs_bitset (bitmap toremove)
gsi_remove (&gsi, true);
release_defs (def);
}
-
- to_remove_bit = j;
+ bitmap_clear_bit (toremove, SSA_NAME_VERSION (var));
}
+ else
+ --i;
+ if (--j != i)
+ names[i] = names[j];
}
- if (to_remove_bit != -1U)
- bitmap_clear_bit (toremove, to_remove_bit);
}
-
+ bitmap_list_view (toremove);
}
/* Disable warnings about missing quoting in GCC diagnostics for
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index 35b3e98..dc8bbf8 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -41,7 +41,7 @@ along with GCC; see the file COPYING3. If not see
block IB. */
tree
-streamer_read_string_cst (struct data_in *data_in, struct lto_input_block *ib)
+streamer_read_string_cst (class data_in *data_in, class lto_input_block *ib)
{
unsigned int len;
const char * ptr;
@@ -57,7 +57,7 @@ streamer_read_string_cst (struct data_in *data_in, struct lto_input_block *ib)
block IB. */
static tree
-input_identifier (struct data_in *data_in, struct lto_input_block *ib)
+input_identifier (class data_in *data_in, class lto_input_block *ib)
{
unsigned int len;
const char *ptr;
@@ -73,7 +73,7 @@ input_identifier (struct data_in *data_in, struct lto_input_block *ib)
tables and descriptors for the file being read. */
tree
-streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in)
+streamer_read_chain (class lto_input_block *ib, class data_in *data_in)
{
tree first, prev, curr;
@@ -404,7 +404,7 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
of expression EXPR from bitpack BP. */
static void
-unpack_ts_block_value_fields (struct data_in *data_in,
+unpack_ts_block_value_fields (class data_in *data_in,
struct bitpack_d *bp, tree expr)
{
/* BLOCK_NUMBER is recomputed. */
@@ -415,7 +415,7 @@ unpack_ts_block_value_fields (struct data_in *data_in,
structure of expression EXPR from bitpack BP. */
static void
-unpack_ts_translation_unit_decl_value_fields (struct data_in *data_in,
+unpack_ts_translation_unit_decl_value_fields (class data_in *data_in,
struct bitpack_d *bp, tree expr)
{
TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (bp_unpack_string (data_in, bp));
@@ -427,7 +427,7 @@ unpack_ts_translation_unit_decl_value_fields (struct data_in *data_in,
structure of expression EXPR from bitpack BP. */
static void
-unpack_ts_omp_clause_value_fields (struct data_in *data_in,
+unpack_ts_omp_clause_value_fields (class data_in *data_in,
struct bitpack_d *bp, tree expr)
{
stream_input_location (&OMP_CLAUSE_LOCATION (expr), bp, data_in);
@@ -473,8 +473,8 @@ unpack_ts_omp_clause_value_fields (struct data_in *data_in,
bitfield values that the writer may have written. */
void
-streamer_read_tree_bitfields (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+streamer_read_tree_bitfields (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
enum tree_code code;
struct bitpack_d bp;
@@ -570,7 +570,7 @@ streamer_read_tree_bitfields (struct lto_input_block *ib,
*IX_P the index into the reader cache where the new tree is stored. */
tree
-streamer_alloc_tree (struct lto_input_block *ib, struct data_in *data_in,
+streamer_alloc_tree (class lto_input_block *ib, class data_in *data_in,
enum LTO_tags tag)
{
enum tree_code code;
@@ -640,8 +640,8 @@ streamer_alloc_tree (struct lto_input_block *ib, struct data_in *data_in,
static void
-lto_input_ts_common_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_common_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
if (TREE_CODE (expr) != IDENTIFIER_NODE)
TREE_TYPE (expr) = stream_read_tree (ib, data_in);
@@ -653,8 +653,8 @@ lto_input_ts_common_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_vector_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_vector_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
unsigned int count = vector_cst_encoded_nelts (expr);
for (unsigned int i = 0; i < count; ++i)
@@ -667,8 +667,8 @@ lto_input_ts_vector_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_poly_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_poly_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
POLY_INT_CST_COEFF (expr, i) = stream_read_tree (ib, data_in);
@@ -680,8 +680,8 @@ lto_input_ts_poly_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_complex_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_complex_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
TREE_REALPART (expr) = stream_read_tree (ib, data_in);
TREE_IMAGPART (expr) = stream_read_tree (ib, data_in);
@@ -693,8 +693,8 @@ lto_input_ts_complex_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_decl_minimal_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_decl_minimal_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
DECL_NAME (expr) = stream_read_tree (ib, data_in);
DECL_CONTEXT (expr) = stream_read_tree (ib, data_in);
@@ -706,8 +706,8 @@ lto_input_ts_decl_minimal_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_decl_common_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
DECL_SIZE (expr) = stream_read_tree (ib, data_in);
DECL_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
@@ -733,8 +733,8 @@ lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *,
- struct data_in *, tree)
+lto_input_ts_decl_non_common_tree_pointers (class lto_input_block *,
+ class data_in *, tree)
{
}
@@ -744,8 +744,8 @@ lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *,
file being read. */
static void
-lto_input_ts_decl_with_vis_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_decl_with_vis_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
tree id;
@@ -763,8 +763,8 @@ lto_input_ts_decl_with_vis_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_field_decl_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_field_decl_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
DECL_FIELD_OFFSET (expr) = stream_read_tree (ib, data_in);
DECL_BIT_FIELD_TYPE (expr) = stream_read_tree (ib, data_in);
@@ -778,8 +778,8 @@ lto_input_ts_field_decl_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_function_decl_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_function_decl_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
/* DECL_STRUCT_FUNCTION is loaded on demand by cgraph_get_body. */
DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
@@ -816,8 +816,8 @@ lto_input_ts_function_decl_tree_pointers (struct lto_input_block *ib,
being read. */
static void
-lto_input_ts_type_common_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_type_common_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
TYPE_SIZE (expr) = stream_read_tree (ib, data_in);
TYPE_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
@@ -838,8 +838,8 @@ lto_input_ts_type_common_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_type_non_common_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in,
+lto_input_ts_type_non_common_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in,
tree expr)
{
if (TREE_CODE (expr) == ENUMERAL_TYPE)
@@ -863,8 +863,8 @@ lto_input_ts_type_non_common_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_list_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_list_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
TREE_PURPOSE (expr) = stream_read_tree (ib, data_in);
TREE_VALUE (expr) = stream_read_tree (ib, data_in);
@@ -877,8 +877,8 @@ lto_input_ts_list_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_vec_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_vec_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
int i;
@@ -895,8 +895,8 @@ lto_input_ts_vec_tree_pointers (struct lto_input_block *ib,
static void
-lto_input_ts_exp_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_exp_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
int i;
tree block;
@@ -921,8 +921,8 @@ lto_input_ts_exp_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_block_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_block_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
BLOCK_VARS (expr) = streamer_read_chain (ib, data_in);
@@ -967,8 +967,8 @@ lto_input_ts_block_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_binfo_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
tree t;
@@ -999,8 +999,8 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_constructor_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_constructor_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
unsigned i;
@@ -1019,8 +1019,8 @@ lto_input_ts_constructor_tree_pointers (struct lto_input_block *ib,
file being read. */
static void
-lto_input_ts_omp_clause_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in, tree expr)
+lto_input_ts_omp_clause_tree_pointers (class lto_input_block *ib,
+ class data_in *data_in, tree expr)
{
int i;
@@ -1034,7 +1034,7 @@ lto_input_ts_omp_clause_tree_pointers (struct lto_input_block *ib,
contains tables and descriptors for the file being read. */
void
-streamer_read_tree_body (struct lto_input_block *ib, struct data_in *data_in,
+streamer_read_tree_body (class lto_input_block *ib, class data_in *data_in,
tree expr)
{
enum tree_code code;
@@ -1104,7 +1104,7 @@ streamer_read_tree_body (struct lto_input_block *ib, struct data_in *data_in,
DATA_IN->FILE_DATA->GLOBALS_INDEX[IX]. */
tree
-streamer_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in)
+streamer_get_pickled_tree (class lto_input_block *ib, class data_in *data_in)
{
unsigned HOST_WIDE_INT ix;
tree result;
diff --git a/gcc/tree-streamer.h b/gcc/tree-streamer.h
index 2972861..01ddd63 100644
--- a/gcc/tree-streamer.h
+++ b/gcc/tree-streamer.h
@@ -58,14 +58,14 @@ struct streamer_tree_cache_d
};
/* In tree-streamer-in.c. */
-tree streamer_read_string_cst (struct data_in *, struct lto_input_block *);
-tree streamer_read_chain (struct lto_input_block *, struct data_in *);
-tree streamer_alloc_tree (struct lto_input_block *, struct data_in *,
+tree streamer_read_string_cst (class data_in *, class lto_input_block *);
+tree streamer_read_chain (class lto_input_block *, class data_in *);
+tree streamer_alloc_tree (class lto_input_block *, class data_in *,
enum LTO_tags);
-void streamer_read_tree_body (struct lto_input_block *, struct data_in *, tree);
-tree streamer_get_pickled_tree (struct lto_input_block *, struct data_in *);
-void streamer_read_tree_bitfields (struct lto_input_block *,
- struct data_in *, tree);
+void streamer_read_tree_body (class lto_input_block *, class data_in *, tree);
+tree streamer_get_pickled_tree (class lto_input_block *, class data_in *);
+void streamer_read_tree_bitfields (class lto_input_block *,
+ class data_in *, tree);
/* In tree-streamer-out.c. */
void streamer_write_string_cst (struct output_block *,
@@ -117,7 +117,7 @@ static inline machine_mode
bp_unpack_machine_mode (struct bitpack_d *bp)
{
return (machine_mode)
- ((struct lto_input_block *)
+ ((class lto_input_block *)
bp->stream)->mode_table[bp_unpack_enum (bp, machine_mode, 1 << 8)];
}
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 5f8ed46..776db77 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1448,8 +1448,8 @@ bit_test_cluster::is_beneficial (const vec<cluster *> &clusters,
int
case_bit_test::cmp (const void *p1, const void *p2)
{
- const struct case_bit_test *const d1 = (const struct case_bit_test *) p1;
- const struct case_bit_test *const d2 = (const struct case_bit_test *) p2;
+ const case_bit_test *const d1 = (const case_bit_test *) p1;
+ const case_bit_test *const d2 = (const case_bit_test *) p2;
if (d2->bits != d1->bits)
return d2->bits - d1->bits;
@@ -1480,7 +1480,7 @@ void
bit_test_cluster::emit (tree index_expr, tree index_type,
tree, basic_block default_bb)
{
- struct case_bit_test test[m_max_case_bit_tests] = { {} };
+ case_bit_test test[m_max_case_bit_tests] = { {} };
unsigned int i, j, k;
unsigned int count;
diff --git a/gcc/tree-switch-conversion.h b/gcc/tree-switch-conversion.h
index a9a959c..653007f 100644
--- a/gcc/tree-switch-conversion.h
+++ b/gcc/tree-switch-conversion.h
@@ -44,8 +44,9 @@ enum cluster_type
|-jump_table_cluster (JUMP_TABLE)
`-bit_test_cluster (BIT_TEST). */
-struct cluster
+class cluster
{
+public:
/* Constructor. */
cluster (tree case_label_expr, basic_block case_bb, profile_probability prob,
profile_probability subtree_prob);
@@ -117,8 +118,9 @@ cluster::cluster (tree case_label_expr, basic_block case_bb,
/* Subclass of cluster representing a simple contiguous range
from [low..high]. */
-struct simple_cluster: public cluster
+class simple_cluster: public cluster
{
+public:
/* Constructor. */
simple_cluster (tree low, tree high, tree case_label_expr,
basic_block case_bb, profile_probability prob);
@@ -196,8 +198,9 @@ simple_cluster::simple_cluster (tree low, tree high, tree case_label_expr,
/* Abstract subclass of jump table and bit test cluster,
handling a collection of simple_cluster instances. */
-struct group_cluster: public cluster
+class group_cluster: public cluster
{
+public:
/* Constructor. */
group_cluster (vec<cluster *> &clusters, unsigned start, unsigned end);
@@ -233,8 +236,9 @@ struct group_cluster: public cluster
The "emit" vfunc gernerates a nested switch statement which
is later lowered to a jump table. */
-struct jump_table_cluster: public group_cluster
+class jump_table_cluster: public group_cluster
{
+public:
/* Constructor. */
jump_table_cluster (vec<cluster *> &clusters, unsigned start, unsigned end)
: group_cluster (clusters, start, end)
@@ -332,8 +336,9 @@ This transformation was contributed by Roger Sayle, see this e-mail:
http://gcc.gnu.org/ml/gcc-patches/2003-01/msg01950.html
*/
-struct bit_test_cluster: public group_cluster
+class bit_test_cluster: public group_cluster
{
+public:
/* Constructor. */
bit_test_cluster (vec<cluster *> &clusters, unsigned start, unsigned end,
bool handles_entire_switch)
@@ -417,8 +422,9 @@ struct bit_test_cluster: public group_cluster
/* Helper struct to find minimal clusters. */
-struct min_cluster_item
+class min_cluster_item
{
+public:
/* Constructor. */
min_cluster_item (unsigned count, unsigned start, unsigned non_jt_cases):
m_count (count), m_start (start), m_non_jt_cases (non_jt_cases)
@@ -436,8 +442,9 @@ struct min_cluster_item
/* Helper struct to represent switch decision tree. */
-struct case_tree_node
+class case_tree_node
{
+public:
/* Empty Constructor. */
case_tree_node ();
@@ -503,8 +510,9 @@ bool jump_table_cluster::is_enabled (void)
is used to quickly identify all cases in this set without
looking at label_to_block for every case label. */
-struct case_bit_test
+class case_bit_test
{
+public:
wide_int mask;
basic_block target_bb;
tree label;
@@ -515,8 +523,9 @@ struct case_bit_test
static int cmp (const void *p1, const void *p2);
};
-struct switch_decision_tree
+class switch_decision_tree
{
+public:
/* Constructor. */
switch_decision_tree (gswitch *swtch): m_switch (swtch), m_phi_mapping (),
m_case_bbs (), m_case_node_pool ("struct case_node pool"),
@@ -681,8 +690,9 @@ This transformation was contributed by Martin Jambor, see this e-mail:
http://gcc.gnu.org/ml/gcc-patches/2008-07/msg00011.html */
/* The main structure of the pass. */
-struct switch_conversion
+class switch_conversion
{
+public:
/* Constructor. */
switch_conversion ();
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index cf9cee5..6390b19 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -183,7 +183,7 @@ vect_get_smallest_scalar_type (stmt_vec_info stmt_info,
static opt_result
vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
if ((unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS) == 0)
return opt_result::failure_at (vect_location,
@@ -306,7 +306,7 @@ vect_analyze_possibly_independent_ddr (data_dependence_relation *ddr,
loop_vec_info loop_vinfo,
int loop_depth, unsigned int *max_vf)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
lambda_vector dist_v;
unsigned int i;
FOR_EACH_VEC_ELT (DDR_DIST_VECTS (ddr), i, dist_v)
@@ -363,7 +363,7 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
unsigned int *max_vf)
{
unsigned int i;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
struct data_reference *dra = DDR_A (ddr);
struct data_reference *drb = DDR_B (ddr);
dr_vec_info *dr_info_a = loop_vinfo->lookup_dr (dra);
@@ -867,7 +867,7 @@ void
vect_record_base_alignments (vec_info *vinfo)
{
loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
- struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
+ class loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
data_reference *dr;
unsigned int i;
FOR_EACH_VEC_ELT (vinfo->shared->datarefs, i, dr)
@@ -914,7 +914,7 @@ vect_compute_data_ref_alignment (dr_vec_info *dr_info)
stmt_vec_info stmt_info = dr_info->stmt;
vec_base_alignments *base_alignments = &stmt_info->vinfo->base_alignments;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = NULL;
+ class loop *loop = NULL;
tree ref = DR_REF (dr_info->dr);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
@@ -1659,7 +1659,7 @@ opt_result
vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
{
vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
enum dr_alignment_support supportable_dr_alignment;
dr_vec_info *first_store = NULL;
dr_vec_info *dr0_info = NULL;
@@ -1822,7 +1822,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
computation will be invariant in the outermost loop. */
else if (same_align_drs_max == same_align_drs)
{
- struct loop *ivloop0, *ivloop;
+ class loop *ivloop0, *ivloop;
ivloop0 = outermost_invariant_loop_for_expr
(loop, DR_BASE_ADDRESS (dr0_info->dr));
ivloop = outermost_invariant_loop_for_expr
@@ -2710,7 +2710,7 @@ vect_analyze_data_ref_access (dr_vec_info *dr_info)
tree scalar_type = TREE_TYPE (DR_REF (dr));
stmt_vec_info stmt_info = dr_info->stmt;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = NULL;
+ class loop *loop = NULL;
if (STMT_VINFO_GATHER_SCATTER_P (stmt_info))
return true;
@@ -3730,7 +3730,7 @@ vect_check_gather_scatter (stmt_vec_info stmt_info, loop_vec_info loop_vinfo,
{
HOST_WIDE_INT scale = 1;
poly_int64 pbitpos, pbitsize;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
tree offtype = NULL_TREE;
tree decl = NULL_TREE, base, off;
@@ -4162,7 +4162,7 @@ vect_find_stmt_data_reference (loop_p loop, gimple *stmt,
opt_result
vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf, bool *fatal)
{
- struct loop *loop = NULL;
+ class loop *loop = NULL;
unsigned int i;
struct data_reference *dr;
tree scalar_type;
@@ -4360,6 +4360,8 @@ vect_analyze_data_refs (vec_info *vinfo, poly_uint64 *min_vf, bool *fatal)
STMT_VINFO_VECTORIZABLE (stmt_info) = false;
continue;
}
+ if (fatal)
+ *fatal = false;
return opt_result::failure_at (stmt_info->stmt,
"not vectorized:"
" no vectype for stmt: %G"
@@ -4671,16 +4673,16 @@ vect_create_addr_base_for_vector_ref (stmt_vec_info stmt_info,
tree
vect_create_data_ref_ptr (stmt_vec_info stmt_info, tree aggr_type,
- struct loop *at_loop, tree offset,
+ class loop *at_loop, tree offset,
tree *initial_address, gimple_stmt_iterator *gsi,
gimple **ptr_incr, bool only_init,
tree byte_offset, tree iv_step)
{
const char *base_name;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = NULL;
+ class loop *loop = NULL;
bool nested_in_vect_loop = false;
- struct loop *containing_loop = NULL;
+ class loop *containing_loop = NULL;
tree aggr_ptr_type;
tree aggr_ptr;
tree new_temp;
@@ -5425,13 +5427,13 @@ vect_setup_realignment (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
tree *realignment_token,
enum dr_alignment_support alignment_support_scheme,
tree init_addr,
- struct loop **at_loop)
+ class loop **at_loop)
{
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
dr_vec_info *dr_info = STMT_VINFO_DR_INFO (stmt_info);
struct data_reference *dr = dr_info->dr;
- struct loop *loop = NULL;
+ class loop *loop = NULL;
edge pe = NULL;
tree scalar_dest = gimple_assign_lhs (stmt_info->stmt);
tree vec_dest;
@@ -5446,8 +5448,8 @@ vect_setup_realignment (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
gimple_seq stmts = NULL;
bool compute_in_loop = false;
bool nested_in_vect_loop = false;
- struct loop *containing_loop = (gimple_bb (stmt_info->stmt))->loop_father;
- struct loop *loop_for_initial_load = NULL;
+ class loop *containing_loop = (gimple_bb (stmt_info->stmt))->loop_father;
+ class loop *loop_for_initial_load = NULL;
if (loop_vinfo)
{
@@ -6457,7 +6459,7 @@ vect_supportable_dr_alignment (dr_vec_info *dr_info,
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
machine_mode mode = TYPE_MODE (vectype);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *vect_loop = NULL;
+ class loop *vect_loop = NULL;
bool nested_in_vect_loop = false;
if (aligned_access_p (dr_info) && !check_aligned_accesses)
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 8389f55..5855653 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -382,8 +382,47 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0,
tree t;
if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
&& !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
- t = expand_vector_piecewise (gsi, do_compare, type,
- TREE_TYPE (TREE_TYPE (op0)), op0, op1, code);
+ {
+ if (VECTOR_BOOLEAN_TYPE_P (type)
+ && SCALAR_INT_MODE_P (TYPE_MODE (type))
+ && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)),
+ TYPE_VECTOR_SUBPARTS (type)
+ * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
+ (TREE_TYPE (type)))))
+ {
+ tree inner_type = TREE_TYPE (TREE_TYPE (op0));
+ tree part_width = TYPE_SIZE (inner_type);
+ tree index = bitsize_int (0);
+ int nunits = nunits_for_known_piecewise_op (TREE_TYPE (op0));
+ int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (type));
+ tree ret_type = build_nonstandard_integer_type (prec, 1);
+ tree ret_inner_type = boolean_type_node;
+ int i;
+ location_t loc = gimple_location (gsi_stmt (*gsi));
+ t = build_zero_cst (ret_type);
+
+ if (TYPE_PRECISION (ret_inner_type) != 1)
+ ret_inner_type = build_nonstandard_integer_type (1, 1);
+ warning_at (loc, OPT_Wvector_operation_performance,
+ "vector operation will be expanded piecewise");
+ for (i = 0; i < nunits;
+ i++, index = int_const_binop (PLUS_EXPR, index, part_width))
+ {
+ tree a = tree_vec_extract (gsi, inner_type, op0, part_width,
+ index);
+ tree b = tree_vec_extract (gsi, inner_type, op1, part_width,
+ index);
+ tree result = gimplify_build2 (gsi, code, ret_inner_type, a, b);
+ t = gimplify_build3 (gsi, BIT_INSERT_EXPR, ret_type, t, result,
+ bitsize_int (i));
+ }
+ t = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
+ }
+ else
+ t = expand_vector_piecewise (gsi, do_compare, type,
+ TREE_TYPE (TREE_TYPE (op0)), op0, op1,
+ code);
+ }
else
t = NULL_TREE;
@@ -879,6 +918,7 @@ expand_vector_condition (gimple_stmt_iterator *gsi)
tree a1 = a;
tree a2 = NULL_TREE;
bool a_is_comparison = false;
+ bool a_is_scalar_bitmask = false;
tree b = gimple_assign_rhs2 (stmt);
tree c = gimple_assign_rhs3 (stmt);
vec<constructor_elt, va_gc> *v;
@@ -942,6 +982,20 @@ expand_vector_condition (gimple_stmt_iterator *gsi)
warning_at (loc, OPT_Wvector_operation_performance,
"vector condition will be expanded piecewise");
+ if (!a_is_comparison
+ && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a))
+ && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (a)))
+ && known_lt (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (a))),
+ TYPE_VECTOR_SUBPARTS (TREE_TYPE (a))
+ * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
+ (TREE_TYPE (TREE_TYPE (a))))))
+ {
+ a_is_scalar_bitmask = true;
+ int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (a)));
+ tree atype = build_nonstandard_integer_type (prec, 1);
+ a = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, atype, a);
+ }
+
int nunits = nunits_for_known_piecewise_op (type);
vec_alloc (v, nunits);
for (i = 0; i < nunits; i++)
@@ -957,6 +1011,14 @@ expand_vector_condition (gimple_stmt_iterator *gsi)
comp_width, comp_index);
aa = fold_build2 (TREE_CODE (a), cond_type, aa1, aa2);
}
+ else if (a_is_scalar_bitmask)
+ {
+ wide_int w = wi::set_bit_in_zero (i, TYPE_PRECISION (TREE_TYPE (a)));
+ result = gimplify_build2 (gsi, BIT_AND_EXPR, TREE_TYPE (a),
+ a, wide_int_to_tree (TREE_TYPE (a), w));
+ aa = fold_build2 (NE_EXPR, boolean_type_node, result,
+ build_zero_cst (TREE_TYPE (a)));
+ }
else
aa = tree_vec_extract (gsi, cond_type, a, width, index);
result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc);
@@ -1941,7 +2003,11 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
/* A scalar operation pretending to be a vector one. */
if (VECTOR_BOOLEAN_TYPE_P (type)
&& !VECTOR_MODE_P (TYPE_MODE (type))
- && TYPE_MODE (type) != BLKmode)
+ && TYPE_MODE (type) != BLKmode
+ && (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) != tcc_comparison
+ || (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1))
+ && !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs1)))
+ && TYPE_MODE (TREE_TYPE (rhs1)) != BLKmode)))
return;
/* If the vector operation is operating on all same vector elements
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index c5cabc8..5c25441 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -89,8 +89,8 @@ rename_variables_in_bb (basic_block bb, bool rename_from_outer_loop)
ssa_op_iter iter;
edge e;
edge_iterator ei;
- struct loop *loop = bb->loop_father;
- struct loop *outer_loop = NULL;
+ class loop *loop = bb->loop_father;
+ class loop *outer_loop = NULL;
if (rename_from_outer_loop)
{
@@ -258,7 +258,7 @@ adjust_phi_and_debug_stmts (gimple *update_phi, edge e, tree new_def)
value that it should have on subsequent iterations. */
static void
-vect_set_loop_mask (struct loop *loop, tree mask, tree init_mask,
+vect_set_loop_mask (class loop *loop, tree mask, tree init_mask,
tree next_mask)
{
gphi *phi = create_phi_node (mask, loop->header);
@@ -269,7 +269,7 @@ vect_set_loop_mask (struct loop *loop, tree mask, tree init_mask,
/* Add SEQ to the end of LOOP's preheader block. */
static void
-add_preheader_seq (struct loop *loop, gimple_seq seq)
+add_preheader_seq (class loop *loop, gimple_seq seq)
{
if (seq)
{
@@ -282,7 +282,7 @@ add_preheader_seq (struct loop *loop, gimple_seq seq)
/* Add SEQ to the beginning of LOOP's header block. */
static void
-add_header_seq (struct loop *loop, gimple_seq seq)
+add_header_seq (class loop *loop, gimple_seq seq)
{
if (seq)
{
@@ -406,7 +406,7 @@ vect_maybe_permute_loop_masks (gimple_seq *seq, rgroup_masks *dest_rgm,
would ever hit a value that produces a set of all-false masks for RGM. */
static tree
-vect_set_loop_masks_directly (struct loop *loop, loop_vec_info loop_vinfo,
+vect_set_loop_masks_directly (class loop *loop, loop_vec_info loop_vinfo,
gimple_seq *preheader_seq,
gimple_stmt_iterator loop_cond_gsi,
rgroup_masks *rgm, tree niters, tree niters_skip,
@@ -635,7 +635,7 @@ vect_set_loop_masks_directly (struct loop *loop, loop_vec_info loop_vinfo,
final gcond. */
static gcond *
-vect_set_loop_condition_masked (struct loop *loop, loop_vec_info loop_vinfo,
+vect_set_loop_condition_masked (class loop *loop, loop_vec_info loop_vinfo,
tree niters, tree final_iv,
bool niters_maybe_zero,
gimple_stmt_iterator loop_cond_gsi)
@@ -743,7 +743,7 @@ vect_set_loop_condition_masked (struct loop *loop, loop_vec_info loop_vinfo,
are no loop masks. */
static gcond *
-vect_set_loop_condition_unmasked (struct loop *loop, tree niters,
+vect_set_loop_condition_unmasked (class loop *loop, tree niters,
tree step, tree final_iv,
bool niters_maybe_zero,
gimple_stmt_iterator loop_cond_gsi)
@@ -896,7 +896,7 @@ vect_set_loop_condition_unmasked (struct loop *loop, tree niters,
Assumption: the exit-condition of LOOP is the last stmt in the loop. */
void
-vect_set_loop_condition (struct loop *loop, loop_vec_info loop_vinfo,
+vect_set_loop_condition (class loop *loop, loop_vec_info loop_vinfo,
tree niters, tree step, tree final_iv,
bool niters_maybe_zero)
{
@@ -985,11 +985,11 @@ slpeel_duplicate_current_defs_from_edges (edge from, edge to)
basic blocks from SCALAR_LOOP instead of LOOP, but to either the
entry or exit of LOOP. */
-struct loop *
-slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop,
- struct loop *scalar_loop, edge e)
+class loop *
+slpeel_tree_duplicate_loop_to_edge_cfg (class loop *loop,
+ class loop *scalar_loop, edge e)
{
- struct loop *new_loop;
+ class loop *new_loop;
basic_block *new_bbs, *bbs, *pbbs;
bool at_exit;
bool was_imm_dom;
@@ -1214,7 +1214,7 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond,
*/
bool
-slpeel_can_duplicate_loop_p (const struct loop *loop, const_edge e)
+slpeel_can_duplicate_loop_p (const class loop *loop, const_edge e)
{
edge exit_e = single_exit (loop);
edge entry_e = loop_preheader_edge (loop);
@@ -1244,7 +1244,7 @@ slpeel_can_duplicate_loop_p (const struct loop *loop, const_edge e)
uses should be renamed. */
static void
-create_lcssa_for_virtual_phi (struct loop *loop)
+create_lcssa_for_virtual_phi (class loop *loop)
{
gphi_iterator gsi;
edge exit_e = single_exit (loop);
@@ -1289,7 +1289,7 @@ create_lcssa_for_virtual_phi (struct loop *loop)
Return the loop location if succeed and NULL if not. */
dump_user_location_t
-find_loop_location (struct loop *loop)
+find_loop_location (class loop *loop)
{
gimple *stmt = NULL;
basic_block bb;
@@ -1351,7 +1351,7 @@ iv_phi_p (stmt_vec_info stmt_info)
bool
vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block bb = loop->header;
gphi_iterator gsi;
@@ -1465,7 +1465,7 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo,
tree niters, edge update_e)
{
gphi_iterator gsi, gsi1;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block update_bb = update_e->dest;
basic_block exit_bb = single_exit (loop)->dest;
@@ -1991,7 +1991,7 @@ vect_gen_vector_loop_niters_mult_vf (loop_vec_info loop_vinfo,
{
/* We should be using a step_vector of VF if VF is variable. */
int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo).to_constant ();
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree type = TREE_TYPE (niters_vector);
tree log_vf = build_int_cst (type, exact_log2 (vf));
basic_block exit_bb = single_exit (loop)->dest;
@@ -2059,11 +2059,11 @@ vect_gen_vector_loop_niters_mult_vf (loop_vec_info loop_vinfo,
static void
slpeel_update_phi_nodes_for_loops (loop_vec_info loop_vinfo,
- struct loop *first, struct loop *second,
+ class loop *first, class loop *second,
bool create_lcssa_for_iv_phis)
{
gphi_iterator gsi_update, gsi_orig;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
edge first_latch_e = EDGE_SUCC (first->latch, 0);
edge second_preheader_e = loop_preheader_edge (second);
@@ -2147,8 +2147,8 @@ slpeel_update_phi_nodes_for_loops (loop_vec_info loop_vinfo,
in the update_loop's PHI node with the result of new PHI result. */
static void
-slpeel_update_phi_nodes_for_guard1 (struct loop *skip_loop,
- struct loop *update_loop,
+slpeel_update_phi_nodes_for_guard1 (class loop *skip_loop,
+ class loop *update_loop,
edge guard_edge, edge merge_edge)
{
location_t merge_loc, guard_loc;
@@ -2188,7 +2188,7 @@ slpeel_update_phi_nodes_for_guard1 (struct loop *skip_loop,
NULL. */
static tree
-find_guard_arg (struct loop *loop, struct loop *epilog ATTRIBUTE_UNUSED,
+find_guard_arg (class loop *loop, class loop *epilog ATTRIBUTE_UNUSED,
gphi *lcssa_phi)
{
gphi_iterator gsi;
@@ -2259,7 +2259,7 @@ find_guard_arg (struct loop *loop, struct loop *epilog ATTRIBUTE_UNUSED,
in exit_bb will also be updated. */
static void
-slpeel_update_phi_nodes_for_guard2 (struct loop *loop, struct loop *epilog,
+slpeel_update_phi_nodes_for_guard2 (class loop *loop, class loop *epilog,
edge guard_edge, edge merge_edge)
{
gphi_iterator gsi;
@@ -2308,7 +2308,7 @@ slpeel_update_phi_nodes_for_guard2 (struct loop *loop, struct loop *epilog,
the arg of its loop closed ssa PHI needs to be updated. */
static void
-slpeel_update_phi_nodes_for_lcssa (struct loop *epilog)
+slpeel_update_phi_nodes_for_lcssa (class loop *epilog)
{
gphi_iterator gsi;
basic_block exit_bb = single_exit (epilog)->dest;
@@ -2397,7 +2397,7 @@ slpeel_update_phi_nodes_for_lcssa (struct loop *epilog)
versioning conditions if loop versioning is needed. */
-struct loop *
+class loop *
vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
tree *niters_vector, tree *step_vector,
tree *niters_vector_mult_vf_var, int th,
@@ -2439,8 +2439,8 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
prob_prolog = prob_epilog = profile_probability::guessed_always ()
.apply_scale (estimated_vf - 1, estimated_vf);
- struct loop *prolog, *epilog = NULL, *loop = LOOP_VINFO_LOOP (loop_vinfo);
- struct loop *first_loop = loop;
+ class loop *prolog, *epilog = NULL, *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *first_loop = loop;
bool irred_flag = loop_preheader_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP;
create_lcssa_for_virtual_phi (loop);
update_ssa (TODO_update_ssa_only_virtuals);
@@ -2503,7 +2503,7 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
}
dump_user_location_t loop_loc = find_loop_location (loop);
- struct loop *scalar_loop = LOOP_VINFO_SCALAR_LOOP (loop_vinfo);
+ class loop *scalar_loop = LOOP_VINFO_SCALAR_LOOP (loop_vinfo);
if (prolog_peeling)
{
e = loop_preheader_edge (loop);
@@ -2965,13 +2965,13 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo, tree * cond_expr)
The versioning precondition(s) are placed in *COND_EXPR and
*COND_EXPR_STMT_LIST. */
-struct loop *
+class loop *
vect_loop_versioning (loop_vec_info loop_vinfo,
unsigned int th, bool check_profitability,
poly_uint64 versioning_threshold)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *nloop;
- struct loop *scalar_loop = LOOP_VINFO_SCALAR_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *nloop;
+ class loop *scalar_loop = LOOP_VINFO_SCALAR_LOOP (loop_vinfo);
basic_block condition_bb;
gphi_iterator gsi;
gimple_stmt_iterator cond_exp_gsi;
@@ -3058,7 +3058,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
/* Compute the outermost loop cond_expr and cond_expr_stmt_list are
invariant in. */
- struct loop *outermost = outermost_invariant_loop_for_expr (loop, cond_expr);
+ class loop *outermost = outermost_invariant_loop_for_expr (loop, cond_expr);
for (gimple_stmt_iterator gsi = gsi_start (cond_expr_stmt_list);
!gsi_end_p (gsi); gsi_next (&gsi))
{
@@ -3075,7 +3075,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
/* Search for the outermost loop we can version. Avoid versioning of
non-perfect nests but allow if-conversion versioned loops inside. */
- struct loop *loop_to_version = loop;
+ class loop *loop_to_version = loop;
if (flow_loop_nested_p (outermost, loop))
{
if (dump_enabled_p ())
@@ -3114,8 +3114,17 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
GSI_SAME_STMT);
}
- /* ??? if-conversion uses profile_probability::always () but
- prob below is profile_probability::likely (). */
+ /* if-conversion uses profile_probability::always () for both paths,
+ reset the paths probabilities appropriately. */
+ edge te, fe;
+ extract_true_false_edges_from_block (condition_bb, &te, &fe);
+ te->probability = prob;
+ fe->probability = prob.invert ();
+ /* We can scale loops counts immediately but have to postpone
+ scaling the scalar loop because we re-use it during peeling. */
+ scale_loop_frequencies (loop_to_version, te->probability);
+ LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo) = fe->probability;
+
nloop = scalar_loop;
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
@@ -3139,7 +3148,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
/* Kill off IFN_LOOP_VECTORIZED_CALL in the copy, nobody will
reap those otherwise; they also refer to the original
loops. */
- struct loop *l = loop;
+ class loop *l = loop;
while (gimple *call = vect_loop_vectorized_call (l))
{
call = SSA_NAME_DEF_STMT (get_current_def (gimple_call_lhs (call)));
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index c46cd9d..b0cbbac 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -286,7 +286,7 @@ vect_determine_vf_for_stmt (stmt_vec_info stmt_info, poly_uint64 *vf,
static opt_result
vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
unsigned nbbs = loop->num_nodes;
poly_uint64 vectorization_factor = 1;
@@ -481,7 +481,7 @@ vect_inner_phi_in_double_reduction_p (stmt_vec_info stmt_info, gphi *phi)
enclosing LOOP). */
static void
-vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
+vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, class loop *loop)
{
basic_block bb = loop->header;
tree init, step;
@@ -633,7 +633,7 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
static void
vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
vect_analyze_scalar_cycles_1 (loop_vinfo, loop);
@@ -714,11 +714,11 @@ vect_fixup_scalar_cycles_with_patterns (loop_vec_info loop_vinfo)
static gcond *
-vect_get_loop_niters (struct loop *loop, tree *assumptions,
+vect_get_loop_niters (class loop *loop, tree *assumptions,
tree *number_of_iterations, tree *number_of_iterationsm1)
{
edge exit = single_exit (loop);
- struct tree_niter_desc niter_desc;
+ class tree_niter_desc niter_desc;
tree niter_assumptions, niter, may_be_zero;
gcond *cond = get_loop_exit_condition (loop);
@@ -793,7 +793,7 @@ vect_get_loop_niters (struct loop *loop, tree *assumptions,
static bool
bb_in_loop_p (const_basic_block bb, const void *data)
{
- const struct loop *const loop = (const struct loop *)data;
+ const class loop *const loop = (const class loop *)data;
if (flow_bb_inside_loop_p (loop, bb))
return true;
return false;
@@ -803,7 +803,7 @@ bb_in_loop_p (const_basic_block bb, const void *data)
/* Create and initialize a new loop_vec_info struct for LOOP_IN, as well as
stmt_vec_info structs for all the stmts in LOOP_IN. */
-_loop_vec_info::_loop_vec_info (struct loop *loop_in, vec_info_shared *shared)
+_loop_vec_info::_loop_vec_info (class loop *loop_in, vec_info_shared *shared)
: vec_info (vec_info::loop, init_cost (loop_in), shared),
loop (loop_in),
bbs (XCNEWVEC (basic_block, loop->num_nodes)),
@@ -833,6 +833,7 @@ _loop_vec_info::_loop_vec_info (struct loop *loop_in, vec_info_shared *shared)
operands_swapped (false),
no_data_dependencies (false),
has_mask_store (false),
+ scalar_loop_scaling (profile_probability::uninitialized ()),
scalar_loop (NULL),
orig_loop_info (NULL)
{
@@ -1028,7 +1029,7 @@ vect_get_max_nscalars_per_iter (loop_vec_info loop_vinfo)
static bool
vect_verify_full_masking (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
unsigned int min_ni_width;
unsigned int max_nscalars_per_iter
= vect_get_max_nscalars_per_iter (loop_vinfo);
@@ -1121,7 +1122,7 @@ vect_verify_full_masking (loop_vec_info loop_vinfo)
static void
vect_compute_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes, factor;
int innerloop_iters, i;
@@ -1203,7 +1204,7 @@ vect_compute_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
niter could be analyzed under some assumptions. */
opt_result
-vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
+vect_analyze_loop_form_1 (class loop *loop, gcond **loop_cond,
tree *assumptions, tree *number_of_iterationsm1,
tree *number_of_iterations, gcond **inner_loop_cond)
{
@@ -1238,7 +1239,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
}
else
{
- struct loop *innerloop = loop->inner;
+ class loop *innerloop = loop->inner;
edge entryedge;
/* Nested loop. We currently require that the loop is doubly-nested,
@@ -1355,7 +1356,7 @@ vect_analyze_loop_form_1 (struct loop *loop, gcond **loop_cond,
/* Analyze LOOP form and return a loop_vec_info if it is of suitable form. */
opt_loop_vec_info
-vect_analyze_loop_form (struct loop *loop, vec_info_shared *shared)
+vect_analyze_loop_form (class loop *loop, vec_info_shared *shared)
{
tree assumptions, number_of_iterations, number_of_iterationsm1;
gcond *loop_cond, *inner_loop_cond = NULL;
@@ -1418,7 +1419,7 @@ vect_analyze_loop_form (struct loop *loop, vec_info_shared *shared)
static void
vect_update_vf_for_slp (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
poly_uint64 vectorization_factor;
@@ -1514,7 +1515,7 @@ vect_active_double_reduction_p (stmt_vec_info stmt_info)
static opt_result
vect_analyze_loop_operations (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
int i;
@@ -1660,7 +1661,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo)
static int
vect_analyze_loop_costing (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
unsigned int assumed_vf = vect_vf_for_cost (loop_vinfo);
/* Only fully-masked loops can have iteration counts less than the
@@ -2327,7 +2328,7 @@ again:
loop_vec_info struct. If ORIG_LOOP_VINFO is not NULL epilogue must
be vectorized. */
opt_loop_vec_info
-vect_analyze_loop (struct loop *loop, loop_vec_info orig_loop_vinfo,
+vect_analyze_loop (class loop *loop, loop_vec_info orig_loop_vinfo,
vec_info_shared *shared)
{
auto_vector_sizes vector_sizes;
@@ -2531,7 +2532,7 @@ neutral_op_for_slp_reduction (slp_tree slp_node, tree_code code,
stmt_vec_info stmt_vinfo = stmts[0];
tree vector_type = STMT_VINFO_VECTYPE (stmt_vinfo);
tree scalar_type = TREE_TYPE (vector_type);
- struct loop *loop = gimple_bb (stmt_vinfo->stmt)->loop_father;
+ class loop *loop = gimple_bb (stmt_vinfo->stmt)->loop_father;
gcc_assert (loop);
switch (code)
@@ -2610,8 +2611,8 @@ static bool
vect_is_slp_reduction (loop_vec_info loop_info, gimple *phi,
gimple *first_stmt)
{
- struct loop *loop = (gimple_bb (phi))->loop_father;
- struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
+ class loop *loop = (gimple_bb (phi))->loop_father;
+ class loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
enum tree_code code;
gimple *loop_use_stmt = NULL;
stmt_vec_info use_stmt_info;
@@ -2950,8 +2951,8 @@ vect_is_simple_reduction (loop_vec_info loop_info, stmt_vec_info phi_info,
enum vect_reduction_type *v_reduc_type)
{
gphi *phi = as_a <gphi *> (phi_info->stmt);
- struct loop *loop = (gimple_bb (phi))->loop_father;
- struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
+ class loop *loop = (gimple_bb (phi))->loop_father;
+ class loop *vect_loop = LOOP_VINFO_LOOP (loop_info);
bool nested_in_vect_loop = flow_loop_nested_p (vect_loop, loop);
gimple *phi_use_stmt = NULL;
enum tree_code orig_code, code;
@@ -3976,7 +3977,7 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, internal_fn reduc_fn,
tree vectype;
machine_mode mode;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = NULL;
+ class loop *loop = NULL;
if (loop_vinfo)
loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -4207,7 +4208,7 @@ get_initial_def_for_reduction (stmt_vec_info stmt_vinfo, tree init_val,
tree *adjustment_def)
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree scalar_type = TREE_TYPE (init_val);
tree vectype = get_vectype_for_scalar_type (scalar_type);
enum tree_code code = gimple_assign_rhs_code (stmt_vinfo->stmt);
@@ -4328,7 +4329,7 @@ get_initial_defs_for_reduction (slp_tree slp_node,
tree vector_type;
unsigned int group_size = stmts.length ();
unsigned int i;
- struct loop *loop;
+ class loop *loop;
vector_type = STMT_VINFO_VECTYPE (stmt_vinfo);
@@ -4516,7 +4517,7 @@ vect_create_epilog_for_reduction (vec<tree> vect_defs,
tree vectype;
machine_mode mode;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *outer_loop = NULL;
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *outer_loop = NULL;
basic_block exit_bb;
tree scalar_dest;
tree scalar_type;
@@ -5954,7 +5955,7 @@ vectorize_fold_left_reduction (stmt_vec_info stmt_info,
int reduc_index, vec_loop_masks *masks)
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree vectype_out = STMT_VINFO_VECTYPE (stmt_info);
stmt_vec_info new_stmt_info = NULL;
internal_fn mask_reduc_fn = get_masked_reduction_fn (reduc_fn, vectype_in);
@@ -6097,7 +6098,7 @@ vectorize_fold_left_reduction (stmt_vec_info stmt_info,
does not cause overflow. */
static bool
-is_nonwrapping_integer_induction (stmt_vec_info stmt_vinfo, struct loop *loop)
+is_nonwrapping_integer_induction (stmt_vec_info stmt_vinfo, class loop *loop)
{
gphi *phi = as_a <gphi *> (stmt_vinfo->stmt);
tree base = STMT_VINFO_LOOP_PHI_EVOLUTION_BASE_UNCHANGED (stmt_vinfo);
@@ -6255,7 +6256,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
tree vectype_out = STMT_VINFO_VECTYPE (stmt_info);
tree vectype_in = NULL_TREE;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
enum tree_code code, orig_code;
internal_fn reduc_fn;
machine_mode vec_mode;
@@ -6279,7 +6280,7 @@ vectorizable_reduction (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
bool nested_cycle = false, found_nested_cycle_def = false;
bool double_reduc = false;
basic_block def_bb;
- struct loop * def_stmt_loop;
+ class loop * def_stmt_loop;
tree def_arg;
auto_vec<tree> vec_oprnds0;
auto_vec<tree> vec_oprnds1;
@@ -7467,10 +7468,10 @@ vectorizable_induction (stmt_vec_info stmt_info,
stmt_vector_for_cost *cost_vec)
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
unsigned ncopies;
bool nested_in_vect_loop = false;
- struct loop *iv_loop;
+ class loop *iv_loop;
tree vec_def;
edge pe = loop_preheader_edge (loop);
basic_block new_bb;
@@ -8011,7 +8012,7 @@ vectorizable_live_operation (stmt_vec_info stmt_info,
stmt_vector_for_cost *)
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
imm_use_iterator imm_iter;
tree lhs, lhs_type, bitsize, vec_bitsize;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
@@ -8219,7 +8220,7 @@ vectorizable_live_operation (stmt_vec_info stmt_info,
/* Kill any debug uses outside LOOP of SSA names defined in STMT_INFO. */
static void
-vect_loop_kill_debug_uses (struct loop *loop, stmt_vec_info stmt_info)
+vect_loop_kill_debug_uses (class loop *loop, stmt_vec_info stmt_info)
{
ssa_op_iter op_iter;
imm_use_iterator imm_iter;
@@ -8275,7 +8276,7 @@ loop_niters_no_overflow (loop_vec_info loop_vinfo)
}
widest_int max;
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
/* Check the upper bound of loop niters. */
if (get_max_loop_iterations (loop, &max))
{
@@ -8383,7 +8384,7 @@ vect_get_loop_mask (gimple_stmt_iterator *gsi, vec_loop_masks *masks,
by factor VF. */
static void
-scale_profile_for_vect_loop (struct loop *loop, unsigned vf)
+scale_profile_for_vect_loop (class loop *loop, unsigned vf)
{
edge preheader = loop_preheader_edge (loop);
/* Reduce loop iterations by the vectorization factor. */
@@ -8421,7 +8422,7 @@ static void
vect_transform_loop_stmt (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
gimple_stmt_iterator *gsi, stmt_vec_info *seen_store)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
if (dump_enabled_p ())
@@ -8466,11 +8467,11 @@ vect_transform_loop_stmt (loop_vec_info loop_vinfo, stmt_vec_info stmt_info,
stmts in the loop, and update the loop exit condition.
Returns scalar epilogue loop if any. */
-struct loop *
+class loop *
vect_transform_loop (loop_vec_info loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- struct loop *epilogue = NULL;
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *epilogue = NULL;
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
int i;
@@ -8527,7 +8528,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
versioning_threshold);
check_profitability = false;
}
- struct loop *sloop
+ class loop *sloop
= vect_loop_versioning (loop_vinfo, th, check_profitability,
versioning_threshold);
sloop->force_vectorize = false;
@@ -8557,6 +8558,10 @@ vect_transform_loop (loop_vec_info loop_vinfo)
epilogue = vect_do_peeling (loop_vinfo, niters, nitersm1, &niters_vector,
&step_vector, &niters_vector_mult_vf, th,
check_profitability, niters_no_overflow);
+ if (LOOP_VINFO_SCALAR_LOOP (loop_vinfo)
+ && LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo).initialized_p ())
+ scale_loop_frequencies (LOOP_VINFO_SCALAR_LOOP (loop_vinfo),
+ LOOP_VINFO_SCALAR_LOOP_SCALING (loop_vinfo));
if (niters_vector == NULL_TREE)
{
@@ -8889,13 +8894,13 @@ vect_transform_loop (loop_vec_info loop_vinfo)
*/
void
-optimize_mask_stores (struct loop *loop)
+optimize_mask_stores (class loop *loop)
{
basic_block *bbs = get_loop_body (loop);
unsigned nbbs = loop->num_nodes;
unsigned i;
basic_block bb;
- struct loop *bb_loop;
+ class loop *bb_loop;
gimple_stmt_iterator gsi;
gimple *stmt;
auto_vec<gimple *> worklist;
@@ -9084,7 +9089,7 @@ widest_int
vect_iv_limit_for_full_masking (loop_vec_info loop_vinfo)
{
tree niters_skip = LOOP_VINFO_MASK_SKIP_NITERS (loop_vinfo);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
unsigned HOST_WIDE_INT max_vf = vect_max_vf (loop_vinfo);
/* Calculate the value that the induction variable must be able
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index ff952d6..8430c98 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -286,7 +286,8 @@ type_conversion_p (tree name, stmt_vec_info stmt_vinfo, bool check_sign,
/* Holds information about an input operand after some sign changes
and type promotions have been peeled away. */
-struct vect_unpromoted_value {
+class vect_unpromoted_value {
+public:
vect_unpromoted_value ();
void set_op (tree, vect_def_type, stmt_vec_info = NULL);
@@ -858,7 +859,7 @@ vect_reassociating_reduction_p (stmt_vec_info stmt_info, tree_code code,
/* We don't allow changing the order of the computation in the inner-loop
when doing outer-loop vectorization. */
- struct loop *loop = LOOP_VINFO_LOOP (loop_info);
+ class loop *loop = LOOP_VINFO_LOOP (loop_info);
if (loop && nested_in_vect_loop_p (loop, stmt_info))
return false;
@@ -4663,7 +4664,7 @@ vect_determine_precisions (vec_info *vinfo)
if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
unsigned int nbbs = loop->num_nodes;
@@ -4953,7 +4954,7 @@ vect_pattern_recog_1 (vect_recog_func *recog_func, stmt_vec_info stmt_info)
void
vect_pattern_recog (vec_info *vinfo)
{
- struct loop *loop;
+ class loop *loop;
basic_block *bbs;
unsigned int nbbs;
gimple_stmt_iterator si;
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 1aaf10e..0220b18 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -857,7 +857,7 @@ vect_build_slp_tree_1 (unsigned char *swap,
continue;
}
- if (rhs_code == CALL_EXPR)
+ if (!load_p && rhs_code == CALL_EXPR)
{
if (!compatible_calls_p (as_a <gcall *> (stmts[0]->stmt),
as_a <gcall *> (stmt)))
@@ -1140,7 +1140,8 @@ vect_build_slp_tree_2 (vec_info *vinfo,
FOR_EACH_VEC_ELT (stmts, i, other_info)
{
/* But for reduction chains only check on the first stmt. */
- if (REDUC_GROUP_FIRST_ELEMENT (other_info)
+ if (!STMT_VINFO_DATA_REF (other_info)
+ && REDUC_GROUP_FIRST_ELEMENT (other_info)
&& REDUC_GROUP_FIRST_ELEMENT (other_info) != stmt_info)
continue;
if (STMT_VINFO_DEF_TYPE (other_info) != def_type)
@@ -2019,7 +2020,7 @@ vect_analyze_slp_instance (vec_info *vinfo,
else
{
/* Create a new SLP instance. */
- new_instance = XNEW (struct _slp_instance);
+ new_instance = XNEW (class _slp_instance);
SLP_INSTANCE_TREE (new_instance) = node;
SLP_INSTANCE_GROUP_SIZE (new_instance) = group_size;
SLP_INSTANCE_UNROLLING_FACTOR (new_instance) = unrolling_factor;
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 313b1b9..601a6f5 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -62,7 +62,7 @@ along with GCC; see the file COPYING3. If not see
/* Return the vectorized type for the given statement. */
tree
-stmt_vectype (struct _stmt_vec_info *stmt_info)
+stmt_vectype (class _stmt_vec_info *stmt_info)
{
return STMT_VINFO_VECTYPE (stmt_info);
}
@@ -70,12 +70,12 @@ stmt_vectype (struct _stmt_vec_info *stmt_info)
/* Return TRUE iff the given statement is in an inner loop relative to
the loop being vectorized. */
bool
-stmt_in_inner_loop_p (struct _stmt_vec_info *stmt_info)
+stmt_in_inner_loop_p (class _stmt_vec_info *stmt_info)
{
gimple *stmt = STMT_VINFO_STMT (stmt_info);
basic_block bb = gimple_bb (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop* loop;
+ class loop* loop;
if (!loop_vinfo)
return false;
@@ -297,7 +297,7 @@ static bool
vect_stmt_relevant_p (stmt_vec_info stmt_info, loop_vec_info loop_vinfo,
enum vect_relevant *relevant, bool *live_p)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
ssa_op_iter op_iter;
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -610,7 +610,7 @@ process_use (stmt_vec_info stmt_vinfo, tree use, loop_vec_info loop_vinfo,
opt_result
vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo, bool *fatal)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
unsigned int nbbs = loop->num_nodes;
gimple_stmt_iterator si;
@@ -1415,7 +1415,7 @@ vect_init_vector_1 (stmt_vec_info stmt_vinfo, gimple *new_stmt,
if (loop_vinfo)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
basic_block new_bb;
edge pe;
@@ -1496,15 +1496,19 @@ vect_init_vector (stmt_vec_info stmt_info, tree val, tree type,
promotion of invariant/external defs. */
val = gimple_convert (&stmts, TREE_TYPE (type), val);
for (gimple_stmt_iterator gsi2 = gsi_start (stmts);
- !gsi_end_p (gsi2); gsi_next (&gsi2))
- vect_init_vector_1 (stmt_info, gsi_stmt (gsi2), gsi);
+ !gsi_end_p (gsi2); )
+ {
+ init_stmt = gsi_stmt (gsi2);
+ gsi_remove (&gsi2, false);
+ vect_init_vector_1 (stmt_info, init_stmt, gsi);
+ }
}
}
val = build_vector_from_val (type, val);
}
new_temp = vect_get_new_ssa_name (type, vect_simple_var, "cst_");
- init_stmt = gimple_build_assign (new_temp, val);
+ init_stmt = gimple_build_assign (new_temp, val);
vect_init_vector_1 (stmt_info, init_stmt, gsi);
return new_temp;
}
@@ -2037,7 +2041,7 @@ vect_truncate_gather_scatter_offset (stmt_vec_info stmt_info,
unsigned HOST_WIDE_INT count = vect_max_vf (loop_vinfo) - 1;
/* Try lowering COUNT to the number of scalar latch iterations. */
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
widest_int max_iters;
if (max_loop_iterations (loop, &max_iters)
&& max_iters < count)
@@ -2205,7 +2209,7 @@ get_group_load_store_type (stmt_vec_info stmt_info, tree vectype, bool slp,
{
vec_info *vinfo = stmt_info->vinfo;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
+ class loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
stmt_vec_info first_stmt_info = DR_GROUP_FIRST_ELEMENT (stmt_info);
dr_vec_info *first_dr_info = STMT_VINFO_DR_INFO (first_stmt_info);
unsigned int group_size = DR_GROUP_SIZE (first_stmt_info);
@@ -2723,7 +2727,7 @@ vect_build_gather_load_calls (stmt_vec_info stmt_info,
tree mask)
{
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = vect_get_num_copies (loop_vinfo, vectype);
@@ -2965,7 +2969,7 @@ vect_build_gather_load_calls (stmt_vec_info stmt_info,
containing loop. */
static void
-vect_get_gather_scatter_ops (struct loop *loop, stmt_vec_info stmt_info,
+vect_get_gather_scatter_ops (class loop *loop, stmt_vec_info stmt_info,
gather_scatter_info *gs_info,
tree *dataref_ptr, tree *vec_offset)
{
@@ -3000,7 +3004,7 @@ vect_get_strided_load_store_ops (stmt_vec_info stmt_info,
tree *dataref_bump, tree *vec_offset)
{
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
gimple_seq stmts;
@@ -3755,7 +3759,7 @@ struct simd_call_arg_info
*ARGINFO. */
static void
-vect_simd_lane_linear (tree op, struct loop *loop,
+vect_simd_lane_linear (tree op, class loop *loop,
struct simd_call_arg_info *arginfo)
{
gimple *def_stmt = SSA_NAME_DEF_STMT (op);
@@ -3852,7 +3856,7 @@ vectorizable_simd_clone_call (stmt_vec_info stmt_info,
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_info);
vec_info *vinfo = stmt_info->vinfo;
- struct loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
+ class loop *loop = loop_vinfo ? LOOP_VINFO_LOOP (loop_vinfo) : NULL;
tree fndecl, new_temp;
int ncopies, j;
auto_vec<simd_call_arg_info> arginfo;
@@ -6330,30 +6334,88 @@ get_group_alias_ptr_type (stmt_vec_info first_stmt_info)
static bool
scan_operand_equal_p (tree ref1, tree ref2)
{
- machine_mode mode1, mode2;
- poly_int64 bitsize1, bitsize2, bitpos1, bitpos2;
- tree offset1, offset2;
- int unsignedp1, unsignedp2, reversep1, reversep2;
- int volatilep1 = 0, volatilep2 = 0;
- tree base1 = get_inner_reference (ref1, &bitsize1, &bitpos1, &offset1,
- &mode1, &unsignedp1, &reversep1,
- &volatilep1);
- tree base2 = get_inner_reference (ref2, &bitsize2, &bitpos2, &offset2,
- &mode2, &unsignedp2, &reversep2,
- &volatilep2);
- if (reversep1 || reversep2 || volatilep1 || volatilep2)
- return false;
- if (!operand_equal_p (base1, base2, 0))
- return false;
- if (maybe_ne (bitpos1, 0) || maybe_ne (bitpos2, 0))
- return false;
- if (maybe_ne (bitsize1, bitsize2))
+ tree ref[2] = { ref1, ref2 };
+ poly_int64 bitsize[2], bitpos[2];
+ tree offset[2], base[2];
+ for (int i = 0; i < 2; ++i)
+ {
+ machine_mode mode;
+ int unsignedp, reversep, volatilep = 0;
+ base[i] = get_inner_reference (ref[i], &bitsize[i], &bitpos[i],
+ &offset[i], &mode, &unsignedp,
+ &reversep, &volatilep);
+ if (reversep || volatilep || maybe_ne (bitpos[i], 0))
+ return false;
+ if (TREE_CODE (base[i]) == MEM_REF
+ && offset[i] == NULL_TREE
+ && TREE_CODE (TREE_OPERAND (base[i], 0)) == SSA_NAME)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (base[i], 0));
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == POINTER_PLUS_EXPR
+ && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == ADDR_EXPR
+ && TREE_CODE (gimple_assign_rhs2 (def_stmt)) == SSA_NAME)
+ {
+ if (maybe_ne (mem_ref_offset (base[i]), 0))
+ return false;
+ base[i] = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
+ offset[i] = gimple_assign_rhs2 (def_stmt);
+ }
+ }
+ }
+
+ if (!operand_equal_p (base[0], base[1], 0))
return false;
- if (offset1 != offset2
- && (!offset1
- || !offset2
- || !operand_equal_p (offset1, offset2, 0)))
+ if (maybe_ne (bitsize[0], bitsize[1]))
return false;
+ if (offset[0] != offset[1])
+ {
+ if (!offset[0] || !offset[1])
+ return false;
+ if (!operand_equal_p (offset[0], offset[1], 0))
+ {
+ tree step[2];
+ for (int i = 0; i < 2; ++i)
+ {
+ step[i] = integer_one_node;
+ if (TREE_CODE (offset[i]) == SSA_NAME)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (offset[i]);
+ if (is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == MULT_EXPR
+ && (TREE_CODE (gimple_assign_rhs2 (def_stmt))
+ == INTEGER_CST))
+ {
+ step[i] = gimple_assign_rhs2 (def_stmt);
+ offset[i] = gimple_assign_rhs1 (def_stmt);
+ }
+ }
+ else if (TREE_CODE (offset[i]) == MULT_EXPR)
+ {
+ step[i] = TREE_OPERAND (offset[i], 1);
+ offset[i] = TREE_OPERAND (offset[i], 0);
+ }
+ tree rhs1 = NULL_TREE;
+ if (TREE_CODE (offset[i]) == SSA_NAME)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (offset[i]);
+ if (gimple_assign_cast_p (def_stmt))
+ rhs1 = gimple_assign_rhs1 (def_stmt);
+ }
+ else if (CONVERT_EXPR_P (offset[i]))
+ rhs1 = TREE_OPERAND (offset[i], 0);
+ if (rhs1
+ && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
+ && INTEGRAL_TYPE_P (TREE_TYPE (offset[i]))
+ && (TYPE_PRECISION (TREE_TYPE (offset[i]))
+ >= TYPE_PRECISION (TREE_TYPE (rhs1))))
+ offset[i] = rhs1;
+ }
+ if (!operand_equal_p (offset[0], offset[1], 0)
+ || !operand_equal_p (step[0], step[1], 0))
+ return false;
+ }
+ }
return true;
}
@@ -7138,7 +7200,7 @@ vectorizable_store (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
tree vec_oprnd = NULL_TREE;
tree elem_type;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = NULL;
+ class loop *loop = NULL;
machine_mode vec_mode;
tree dummy;
enum dr_alignment_support alignment_support_scheme;
@@ -8287,7 +8349,7 @@ permute_vec_elements (tree x, tree y, tree mask_vec, stmt_vec_info stmt_info,
otherwise returns false. */
static bool
-hoist_defs_of_uses (stmt_vec_info stmt_info, struct loop *loop)
+hoist_defs_of_uses (stmt_vec_info stmt_info, class loop *loop)
{
ssa_op_iter i;
tree op;
@@ -8355,8 +8417,8 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
tree data_ref = NULL;
stmt_vec_info prev_stmt_info;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *loop = NULL;
- struct loop *containing_loop = gimple_bb (stmt_info->stmt)->loop_father;
+ class loop *loop = NULL;
+ class loop *containing_loop = gimple_bb (stmt_info->stmt)->loop_father;
bool nested_in_vect_loop = false;
tree elem_type;
tree new_temp;
@@ -8380,7 +8442,7 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
stmt_vec_info first_stmt_info;
stmt_vec_info first_stmt_info_for_drptr = NULL;
bool compute_in_loop = false;
- struct loop *at_loop;
+ class loop *at_loop;
int vec_num;
bool slp = (slp_node != NULL);
bool slp_perm = false;
@@ -10307,7 +10369,7 @@ vectorizable_comparison (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
if (!slp_node)
{
- if (swap_p)
+ if (swap_p && j == 0)
std::swap (vec_rhs1, vec_rhs2);
vec_oprnds0.quick_push (vec_rhs1);
vec_oprnds1.quick_push (vec_rhs2);
@@ -10749,7 +10811,7 @@ vect_transform_stmt (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
|| STMT_VINFO_RELEVANT (stmt_info) ==
vect_used_in_outer_by_reduction))
{
- struct loop *innerloop = LOOP_VINFO_LOOP (
+ class loop *innerloop = LOOP_VINFO_LOOP (
STMT_VINFO_LOOP_VINFO (stmt_info))->inner;
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -11141,7 +11203,7 @@ supportable_widening_operation (enum tree_code code, stmt_vec_info stmt_info,
vec<tree> *interm_types)
{
loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_info);
- struct loop *vect_loop = NULL;
+ class loop *vect_loop = NULL;
machine_mode vec_mode;
enum insn_code icode1, icode2;
optab optab1, optab2;
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 325ef58..173e6b5 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -188,8 +188,9 @@ dump_stmt_cost (FILE *f, void *data, int count, enum vect_cost_for_stmt kind,
/* For mapping simduid to vectorization factor. */
-struct simduid_to_vf : free_ptr_hash<simduid_to_vf>
+class simduid_to_vf : public free_ptr_hash<simduid_to_vf>
{
+public:
unsigned int simduid;
poly_uint64 vf;
@@ -632,7 +633,7 @@ vec_info::replace_stmt (gimple_stmt_iterator *gsi, stmt_vec_info stmt_info,
stmt_vec_info
vec_info::new_stmt_vec_info (gimple *stmt)
{
- stmt_vec_info res = XCNEW (struct _stmt_vec_info);
+ stmt_vec_info res = XCNEW (class _stmt_vec_info);
res->vinfo = this;
res->stmt = stmt;
@@ -713,7 +714,7 @@ vec_info::free_stmt_vec_info (stmt_vec_info stmt_info)
clear loop constraint LOOP_C_FINITE. */
void
-vect_free_loop_info_assumptions (struct loop *loop)
+vect_free_loop_info_assumptions (class loop *loop)
{
scev_reset_htab ();
/* We need to explicitly reset upper bound information since they are
@@ -728,7 +729,7 @@ vect_free_loop_info_assumptions (struct loop *loop)
guarding it. */
gimple *
-vect_loop_vectorized_call (struct loop *loop, gcond **cond)
+vect_loop_vectorized_call (class loop *loop, gcond **cond)
{
basic_block bb = loop_preheader_edge (loop)->src;
gimple *g;
@@ -764,11 +765,11 @@ vect_loop_vectorized_call (struct loop *loop, gcond **cond)
internal call. */
static gimple *
-vect_loop_dist_alias_call (struct loop *loop)
+vect_loop_dist_alias_call (class loop *loop)
{
basic_block bb;
basic_block entry;
- struct loop *outer, *orig;
+ class loop *outer, *orig;
gimple_stmt_iterator gsi;
gimple *g;
@@ -823,7 +824,7 @@ set_uid_loop_bbs (loop_vec_info loop_vinfo, gimple *loop_vectorized_call)
tree arg = gimple_call_arg (loop_vectorized_call, 1);
basic_block *bbs;
unsigned int i;
- struct loop *scalar_loop = get_loop (cfun, tree_to_shwi (arg));
+ class loop *scalar_loop = get_loop (cfun, tree_to_shwi (arg));
LOOP_VINFO_SCALAR_LOOP (loop_vinfo) = scalar_loop;
gcc_checking_assert (vect_loop_vectorized_call (scalar_loop)
@@ -1046,7 +1047,7 @@ vectorize_loops (void)
unsigned int i;
unsigned int num_vectorized_loops = 0;
unsigned int vect_loops_num;
- struct loop *loop;
+ class loop *loop;
hash_table<simduid_to_vf> *simduid_to_vf_htab = NULL;
hash_table<simd_array_to_simduid> *simd_array_to_simduid_htab = NULL;
bool any_ifcvt_loops = false;
@@ -1097,7 +1098,7 @@ vectorize_loops (void)
&& vect_loop_vectorized_call (loop->inner))
{
tree arg = gimple_call_arg (loop_vectorized_call, 0);
- struct loop *vector_loop
+ class loop *vector_loop
= get_loop (cfun, tree_to_shwi (arg));
if (vector_loop && vector_loop != loop)
{
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 0dd29f8..1456cde 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_VECTORIZER_H
#define GCC_TREE_VECTORIZER_H
-typedef struct _stmt_vec_info *stmt_vec_info;
+typedef class _stmt_vec_info *stmt_vec_info;
#include "tree-data-ref.h"
#include "tree-hash-traits.h"
@@ -141,7 +141,8 @@ struct _slp_tree {
/* SLP instance is a sequence of stmts in a loop that can be packed into
SIMD stmts. */
-typedef struct _slp_instance {
+typedef class _slp_instance {
+public:
/* The root of SLP tree. */
slp_tree root;
@@ -181,7 +182,8 @@ typedef std::pair<tree, tree> vec_object_pair;
/* Records that vectorization is only possible if abs (EXPR) >= MIN_VALUE.
UNSIGNED_P is true if we can assume that abs (EXPR) == EXPR. */
-struct vec_lower_bound {
+class vec_lower_bound {
+public:
vec_lower_bound () {}
vec_lower_bound (tree e, bool u, poly_uint64 m)
: expr (e), unsigned_p (u), min_value (m) {}
@@ -193,7 +195,8 @@ struct vec_lower_bound {
/* Vectorizer state shared between different analyses like vector sizes
of the same CFG region. */
-struct vec_info_shared {
+class vec_info_shared {
+public:
vec_info_shared();
~vec_info_shared();
@@ -213,7 +216,8 @@ struct vec_info_shared {
};
/* Vectorizer state common between loop and basic-block vectorization. */
-struct vec_info {
+class vec_info {
+public:
enum vec_kind { bb, loop };
vec_info (vec_kind, void *, vec_info_shared *);
@@ -223,7 +227,7 @@ struct vec_info {
stmt_vec_info lookup_stmt (gimple *);
stmt_vec_info lookup_def (tree);
stmt_vec_info lookup_single_use (tree);
- struct dr_vec_info *lookup_dr (data_reference *);
+ class dr_vec_info *lookup_dr (data_reference *);
void move_dr (stmt_vec_info, stmt_vec_info);
void remove_stmt (stmt_vec_info);
void replace_stmt (gimple_stmt_iterator *, stmt_vec_info, gimple *);
@@ -258,8 +262,8 @@ private:
void free_stmt_vec_info (stmt_vec_info);
};
-struct _loop_vec_info;
-struct _bb_vec_info;
+class _loop_vec_info;
+class _bb_vec_info;
template<>
template<>
@@ -377,12 +381,13 @@ typedef auto_vec<rgroup_masks> vec_loop_masks;
/*-----------------------------------------------------------------*/
/* Info on vectorized loops. */
/*-----------------------------------------------------------------*/
-typedef struct _loop_vec_info : public vec_info {
- _loop_vec_info (struct loop *, vec_info_shared *);
+typedef class _loop_vec_info : public vec_info {
+public:
+ _loop_vec_info (class loop *, vec_info_shared *);
~_loop_vec_info ();
/* The loop to which this info struct refers to. */
- struct loop *loop;
+ class loop *loop;
/* The loop basic blocks. */
basic_block *bbs;
@@ -440,7 +445,7 @@ typedef struct _loop_vec_info : public vec_info {
tree iv_type;
/* Unknown DRs according to which loop was peeled. */
- struct dr_vec_info *unaligned_dr;
+ class dr_vec_info *unaligned_dr;
/* peeling_for_alignment indicates whether peeling for alignment will take
place, and what the peeling factor should be:
@@ -548,9 +553,12 @@ typedef struct _loop_vec_info : public vec_info {
/* Mark loops having masked stores. */
bool has_mask_store;
+ /* Queued scaling factor for the scalar loop. */
+ profile_probability scalar_loop_scaling;
+
/* If if-conversion versioned this loop before conversion, this is the
loop version without if-conversion. */
- struct loop *scalar_loop;
+ class loop *scalar_loop;
/* For loops being epilogues of already vectorized loops
this points to the original vectorized loop. Otherwise NULL. */
@@ -603,6 +611,7 @@ typedef struct _loop_vec_info : public vec_info {
#define LOOP_VINFO_PEELING_FOR_NITER(L) (L)->peeling_for_niter
#define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies
#define LOOP_VINFO_SCALAR_LOOP(L) (L)->scalar_loop
+#define LOOP_VINFO_SCALAR_LOOP_SCALING(L) (L)->scalar_loop_scaling
#define LOOP_VINFO_HAS_MASK_STORE(L) (L)->has_mask_store
#define LOOP_VINFO_SCALAR_ITERATION_COST(L) (L)->scalar_cost_vec
#define LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST(L) (L)->single_scalar_iteration_cost
@@ -641,13 +650,14 @@ typedef struct _loop_vec_info : public vec_info {
typedef opt_pointer_wrapper <loop_vec_info> opt_loop_vec_info;
static inline loop_vec_info
-loop_vec_info_for_loop (struct loop *loop)
+loop_vec_info_for_loop (class loop *loop)
{
return (loop_vec_info) loop->aux;
}
-typedef struct _bb_vec_info : public vec_info
+typedef class _bb_vec_info : public vec_info
{
+public:
_bb_vec_info (gimple_stmt_iterator, gimple_stmt_iterator, vec_info_shared *);
~_bb_vec_info ();
@@ -786,7 +796,8 @@ enum vect_memory_access_type {
VMAT_GATHER_SCATTER
};
-struct dr_vec_info {
+class dr_vec_info {
+public:
/* The data reference itself. */
data_reference *dr;
/* The statement that contains the data reference. */
@@ -803,7 +814,8 @@ struct dr_vec_info {
typedef struct data_reference *dr_p;
-struct _stmt_vec_info {
+class _stmt_vec_info {
+public:
enum stmt_vec_info_type type;
@@ -1100,7 +1112,7 @@ STMT_VINFO_BB_VINFO (stmt_vec_info stmt_vinfo)
&& TYPE_UNSIGNED (TYPE)))
static inline bool
-nested_in_vect_loop_p (struct loop *loop, stmt_vec_info stmt_info)
+nested_in_vect_loop_p (class loop *loop, stmt_vec_info stmt_info)
{
return (loop->inner
&& (loop->inner == (gimple_bb (stmt_info->stmt))->loop_father));
@@ -1194,7 +1206,7 @@ int vect_get_stmt_cost (enum vect_cost_for_stmt type_of_cost)
/* Alias targetm.vectorize.init_cost. */
static inline void *
-init_cost (struct loop *loop_info)
+init_cost (class loop *loop_info)
{
return targetm.vectorize.init_cost (loop_info);
}
@@ -1463,17 +1475,17 @@ class auto_purge_vect_location
/* Simple loop peeling and versioning utilities for vectorizer's purposes -
in tree-vect-loop-manip.c. */
-extern void vect_set_loop_condition (struct loop *, loop_vec_info,
+extern void vect_set_loop_condition (class loop *, loop_vec_info,
tree, tree, tree, bool);
-extern bool slpeel_can_duplicate_loop_p (const struct loop *, const_edge);
-struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *,
- struct loop *, edge);
-struct loop *vect_loop_versioning (loop_vec_info, unsigned int, bool,
+extern bool slpeel_can_duplicate_loop_p (const class loop *, const_edge);
+class loop *slpeel_tree_duplicate_loop_to_edge_cfg (class loop *,
+ class loop *, edge);
+class loop *vect_loop_versioning (loop_vec_info, unsigned int, bool,
poly_uint64);
-extern struct loop *vect_do_peeling (loop_vec_info, tree, tree,
+extern class loop *vect_do_peeling (loop_vec_info, tree, tree,
tree *, tree *, tree *, int, bool, bool);
extern void vect_prepare_for_masked_peels (loop_vec_info);
-extern dump_user_location_t find_loop_location (struct loop *);
+extern dump_user_location_t find_loop_location (class loop *);
extern bool vect_can_advance_ivs_p (loop_vec_info);
/* In tree-vect-stmts.c. */
@@ -1532,7 +1544,7 @@ extern void vect_get_store_cost (stmt_vec_info, int,
extern bool vect_supportable_shift (enum tree_code, tree);
extern tree vect_gen_perm_mask_any (tree, const vec_perm_indices &);
extern tree vect_gen_perm_mask_checked (tree, const vec_perm_indices &);
-extern void optimize_mask_stores (struct loop*);
+extern void optimize_mask_stores (class loop*);
extern gcall *vect_gen_while (tree, tree, tree);
extern tree vect_gen_while_not (gimple_seq *, tree, tree, tree);
extern opt_result vect_get_vector_types_for_stmt (stmt_vec_info, tree *,
@@ -1561,7 +1573,7 @@ extern opt_result vect_find_stmt_data_reference (loop_p, gimple *,
vec<data_reference_p> *);
extern opt_result vect_analyze_data_refs (vec_info *, poly_uint64 *, bool *);
extern void vect_record_base_alignments (vec_info *);
-extern tree vect_create_data_ref_ptr (stmt_vec_info, tree, struct loop *, tree,
+extern tree vect_create_data_ref_ptr (stmt_vec_info, tree, class loop *, tree,
tree *, gimple_stmt_iterator *,
gimple **, bool,
tree = NULL_TREE, tree = NULL_TREE);
@@ -1577,7 +1589,7 @@ extern void vect_permute_store_chain (vec<tree> ,unsigned int, stmt_vec_info,
gimple_stmt_iterator *, vec<tree> *);
extern tree vect_setup_realignment (stmt_vec_info, gimple_stmt_iterator *,
tree *, enum dr_alignment_support, tree,
- struct loop **);
+ class loop **);
extern void vect_transform_grouped_load (stmt_vec_info, vec<tree> , int,
gimple_stmt_iterator *);
extern void vect_record_grouped_load_vectors (stmt_vec_info, vec<tree>);
@@ -1596,7 +1608,7 @@ extern widest_int vect_iv_limit_for_full_masking (loop_vec_info loop_vinfo);
extern bool check_reduction_path (dump_user_location_t, loop_p, gphi *, tree,
enum tree_code);
/* Drive for loop analysis stage. */
-extern opt_loop_vec_info vect_analyze_loop (struct loop *,
+extern opt_loop_vec_info vect_analyze_loop (class loop *,
loop_vec_info,
vec_info_shared *);
extern tree vect_build_loop_niters (loop_vec_info, bool * = NULL);
@@ -1610,8 +1622,8 @@ extern tree vect_get_loop_mask (gimple_stmt_iterator *, vec_loop_masks *,
unsigned int, tree, unsigned int);
/* Drive for loop transformation stage. */
-extern struct loop *vect_transform_loop (loop_vec_info);
-extern opt_loop_vec_info vect_analyze_loop_form (struct loop *,
+extern class loop *vect_transform_loop (loop_vec_info);
+extern opt_loop_vec_info vect_analyze_loop_form (class loop *,
vec_info_shared *);
extern bool vectorizable_live_operation (stmt_vec_info, gimple_stmt_iterator *,
slp_tree, int, stmt_vec_info *,
@@ -1659,8 +1671,8 @@ void vect_pattern_recog (vec_info *);
/* In tree-vectorizer.c. */
unsigned vectorize_loops (void);
-void vect_free_loop_info_assumptions (struct loop *);
-gimple *vect_loop_vectorized_call (struct loop *, gcond **cond = NULL);
+void vect_free_loop_info_assumptions (class loop *);
+gimple *vect_loop_vectorized_call (class loop *, gcond **cond = NULL);
#endif /* GCC_TREE_VECTORIZER_H */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index dc7f825..b79dfb2 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4492,7 +4492,8 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
The loop computes the range of the final offset for expressions such
as (A + i0 + ... + iN)[CSTOFF] where i0 through iN are SSA_NAMEs in
some range. */
- while (TREE_CODE (arg) == SSA_NAME)
+ const unsigned limit = PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT);
+ for (unsigned n = 0; TREE_CODE (arg) == SSA_NAME && n < limit; ++n)
{
gimple *def = SSA_NAME_DEF_STMT (arg);
if (!is_gimple_assign (def))
@@ -5977,6 +5978,11 @@ intersect_ranges (enum value_range_kind *vr0type,
gcc_unreachable ();
}
+ /* If we know the intersection is empty, there's no need to
+ conservatively add anything else to the set. */
+ if (*vr0type == VR_UNDEFINED)
+ return;
+
/* As a fallback simply use { *VRTYPE, *VR0MIN, *VR0MAX } as
result for the intersection. That's always a conservative
correct estimate unless VR1 is a constant singleton range
diff --git a/gcc/tree.c b/gcc/tree.c
index 76d94c6..8cf75f2 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -342,7 +342,9 @@ unsigned const char omp_clause_num_ops[] =
0, /* OMP_CLAUSE_THREADS */
0, /* OMP_CLAUSE_SIMD */
1, /* OMP_CLAUSE_HINT */
- 0, /* OMP_CLAUSE_DEFALTMAP */
+ 0, /* OMP_CLAUSE_DEFAULTMAP */
+ 0, /* OMP_CLAUSE_ORDER */
+ 0, /* OMP_CLAUSE_BIND */
1, /* OMP_CLAUSE__SIMDUID_ */
0, /* OMP_CLAUSE__SIMT_ */
0, /* OMP_CLAUSE_INDEPENDENT */
@@ -424,6 +426,8 @@ const char * const omp_clause_code_name[] =
"simd",
"hint",
"defaultmap",
+ "order",
+ "bind",
"_simduid_",
"_simt_",
"independent",
@@ -5107,8 +5111,9 @@ protected_set_expr_location (tree t, location_t loc)
/* Data used when collecting DECLs and TYPEs for language data removal. */
-struct free_lang_data_d
+class free_lang_data_d
{
+public:
free_lang_data_d () : decls (100), types (100) {}
/* Worklist to avoid excessive recursion. */
@@ -5129,7 +5134,7 @@ struct free_lang_data_d
language data removed. The lists are held inside FLD. */
static void
-add_tree_to_fld_list (tree t, struct free_lang_data_d *fld)
+add_tree_to_fld_list (tree t, class free_lang_data_d *fld)
{
if (DECL_P (t))
fld->decls.safe_push (t);
@@ -5142,7 +5147,7 @@ add_tree_to_fld_list (tree t, struct free_lang_data_d *fld)
/* Push tree node T into FLD->WORKLIST. */
static inline void
-fld_worklist_push (tree t, struct free_lang_data_d *fld)
+fld_worklist_push (tree t, class free_lang_data_d *fld)
{
if (t && !is_lang_specific (t) && !fld->pset.contains (t))
fld->worklist.safe_push ((t));
@@ -5196,7 +5201,7 @@ fld_type_variant_equal_p (tree t, tree v, tree inner_type)
Set TREE_TYPE to INNER_TYPE if non-NULL. */
static tree
-fld_type_variant (tree first, tree t, struct free_lang_data_d *fld,
+fld_type_variant (tree first, tree t, class free_lang_data_d *fld,
tree inner_type = NULL)
{
if (first == TYPE_MAIN_VARIANT (t))
@@ -5241,7 +5246,7 @@ static hash_map<tree, tree> *fld_simplified_types;
static tree
fld_process_array_type (tree t, tree t2, hash_map<tree, tree> *map,
- struct free_lang_data_d *fld)
+ class free_lang_data_d *fld)
{
if (TREE_TYPE (t) == t2)
return t;
@@ -5290,7 +5295,7 @@ fld_decl_context (tree ctx)
Return T if no simplification is possible. */
static tree
-fld_incomplete_type_of (tree t, struct free_lang_data_d *fld)
+fld_incomplete_type_of (tree t, class free_lang_data_d *fld)
{
if (!t)
return NULL;
@@ -5382,7 +5387,7 @@ fld_incomplete_type_of (tree t, struct free_lang_data_d *fld)
types. */
static tree
-fld_simplified_type (tree t, struct free_lang_data_d *fld)
+fld_simplified_type (tree t, class free_lang_data_d *fld)
{
if (!t)
return t;
@@ -5440,7 +5445,7 @@ free_lang_data_in_binfo (tree binfo)
/* Reset all language specific information still present in TYPE. */
static void
-free_lang_data_in_type (tree type, struct free_lang_data_d *fld)
+free_lang_data_in_type (tree type, class free_lang_data_d *fld)
{
gcc_assert (TYPE_P (type));
@@ -5656,7 +5661,7 @@ need_assembler_name_p (tree decl)
DECL. */
static void
-free_lang_data_in_decl (tree decl, struct free_lang_data_d *fld)
+free_lang_data_in_decl (tree decl, class free_lang_data_d *fld)
{
gcc_assert (DECL_P (decl));
@@ -5820,7 +5825,7 @@ static tree
find_decls_types_r (tree *tp, int *ws, void *data)
{
tree t = *tp;
- struct free_lang_data_d *fld = (struct free_lang_data_d *) data;
+ class free_lang_data_d *fld = (class free_lang_data_d *) data;
if (TREE_CODE (t) == TREE_LIST)
return NULL_TREE;
@@ -5976,7 +5981,7 @@ find_decls_types_r (tree *tp, int *ws, void *data)
/* Find decls and types in T. */
static void
-find_decls_types (tree t, struct free_lang_data_d *fld)
+find_decls_types (tree t, class free_lang_data_d *fld)
{
while (1)
{
@@ -6018,7 +6023,7 @@ get_eh_types_for_runtime (tree list)
FLD->DECLS and FLD->TYPES. */
static void
-find_decls_types_in_eh_region (eh_region r, struct free_lang_data_d *fld)
+find_decls_types_in_eh_region (eh_region r, class free_lang_data_d *fld)
{
switch (r->type)
{
@@ -6061,7 +6066,7 @@ find_decls_types_in_eh_region (eh_region r, struct free_lang_data_d *fld)
NAMESPACE_DECLs, etc). */
static void
-find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
+find_decls_types_in_node (struct cgraph_node *n, class free_lang_data_d *fld)
{
basic_block bb;
struct function *fn;
@@ -6130,7 +6135,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld)
NAMESPACE_DECLs, etc). */
static void
-find_decls_types_in_var (varpool_node *v, struct free_lang_data_d *fld)
+find_decls_types_in_var (varpool_node *v, class free_lang_data_d *fld)
{
find_decls_types (v->decl, fld);
}
@@ -6181,7 +6186,7 @@ assign_assembler_name_if_needed (tree t)
been set up. */
static void
-free_lang_data_in_cgraph (struct free_lang_data_d *fld)
+free_lang_data_in_cgraph (class free_lang_data_d *fld)
{
struct cgraph_node *n;
varpool_node *v;
@@ -6222,7 +6227,7 @@ static unsigned
free_lang_data (void)
{
unsigned i;
- struct free_lang_data_d fld;
+ class free_lang_data_d fld;
/* If we are the LTO frontend we have freed lang-specific data already. */
if (in_lto_p
@@ -12339,6 +12344,8 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
+ case OMP_CLAUSE_ORDER:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_TILE:
@@ -13415,6 +13422,9 @@ block_may_fallthru (const_tree block)
return (block_may_fallthru (TREE_OPERAND (stmt, 0))
&& block_may_fallthru (TREE_OPERAND (stmt, 1)));
+ case EH_ELSE_EXPR:
+ return block_may_fallthru (TREE_OPERAND (stmt, 0));
+
case MODIFY_EXPR:
if (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR)
stmt = TREE_OPERAND (stmt, 1);
diff --git a/gcc/tree.def b/gcc/tree.def
index 10a14fc..4a22d94 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -908,7 +908,14 @@ DEFTREECODE (TRY_CATCH_EXPR, "try_catch_expr", tcc_statement, 2)
/* Evaluate the first operand.
The second operand is a cleanup expression which is evaluated
on any exit (normal, exception, or jump out) from this expression. */
-DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", tcc_statement, 2)
+DEFTREECODE (TRY_FINALLY_EXPR, "try_finally_expr", tcc_statement, 2)
+
+/* Evaluate either the normal or the exceptional cleanup. This must
+ only be present as the cleanup expression in a TRY_FINALLY_EXPR.
+ If the TRY_FINALLY_EXPR completes normally, the first operand of
+ EH_ELSE_EXPR is used as a cleanup, otherwise the second operand is
+ used. */
+DEFTREECODE (EH_ELSE_EXPR, "eh_else_expr", tcc_statement, 2)
/* These types of expressions have no useful value,
and always have side effects. */
@@ -1146,6 +1153,10 @@ DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 7)
Operands like for OMP_FOR. */
DEFTREECODE (OMP_TASKLOOP, "omp_taskloop", tcc_statement, 7)
+/* OpenMP - #pragma omp loop [clause1 ... clauseN]
+ Operands like for OMP_FOR. */
+DEFTREECODE (OMP_LOOP, "omp_loop", tcc_statement, 7)
+
/* OpenMP - #pragma acc loop [clause1 ... clauseN]
Operands like for OMP_FOR. */
DEFTREECODE (OACC_LOOP, "oacc_loop", tcc_statement, 7)
diff --git a/gcc/tree.h b/gcc/tree.h
index 3dce602..99d021e 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1387,14 +1387,14 @@ class auto_suppress_location_wrappers
#define OMP_TASKREG_BODY(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 0)
#define OMP_TASKREG_CLAUSES(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 1)
-#define OMP_LOOP_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_FOR, OACC_LOOP)
-#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 0)
-#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 1)
-#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 2)
-#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 3)
-#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 4)
-#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 5)
-#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 6)
+#define OMP_LOOPING_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_FOR, OACC_LOOP)
+#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 0)
+#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 1)
+#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 2)
+#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 3)
+#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 4)
+#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 5)
+#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 6)
#define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0)
#define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1)
@@ -1742,6 +1742,9 @@ class auto_suppress_location_wrappers
(OMP_CLAUSE_DEFAULTMAP_KIND (NODE) \
= (enum omp_clause_defaultmap_kind) (CATEGORY | BEHAVIOR))
+#define OMP_CLAUSE_BIND_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_BIND)->omp_clause.subcode.bind_kind)
+
#define OMP_CLAUSE_TILE_LIST(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_TILE), 0)
#define OMP_CLAUSE_TILE_ITERVAR(NODE) \
@@ -5984,8 +5987,9 @@ desired_pro_or_demotion_p (const_tree to_type, const_tree from_type)
/* Pointer type used to declare builtins before we have seen its real
declaration. */
-struct builtin_structptr_type
+class builtin_structptr_type
{
+public:
tree& node;
tree& base;
const char *str;
@@ -6069,8 +6073,9 @@ fndecl_built_in_p (const_tree node, built_in_function name)
where it is not. */
-struct op_location_t
+class op_location_t
{
+public:
location_t m_operator_loc;
location_t m_combined_loc;
diff --git a/gcc/unique-ptr-tests.cc b/gcc/unique-ptr-tests.cc
index 9e0f2a9..45c189b 100644
--- a/gcc/unique-ptr-tests.cc
+++ b/gcc/unique-ptr-tests.cc
@@ -31,8 +31,9 @@ namespace {
/* A class for counting ctor and dtor invocations. */
-struct stats
+class stats
{
+public:
stats () : ctor_count (0), dtor_count (0) {}
int ctor_count;
@@ -59,8 +60,9 @@ private:
/* A struct for testing unique_ptr<T[]>. */
-struct has_default_ctor
+class has_default_ctor
{
+public:
has_default_ctor () : m_field (42) {}
int m_field;
};
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 66c4bba..32e6ddd 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -345,7 +345,7 @@ stream_out_histogram_value (struct output_block *ob, histogram_value hist)
/* Dump information about HIST to DUMP_FILE. */
void
-stream_in_histogram_value (struct lto_input_block *ib, gimple *stmt)
+stream_in_histogram_value (class lto_input_block *ib, gimple *stmt)
{
enum hist_type type;
unsigned int ncounters = 0;
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index 9f69d7d..ca846d0 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -108,7 +108,7 @@ extern void gimple_gen_time_profiler (unsigned, unsigned);
extern void gimple_gen_average_profiler (histogram_value, unsigned, unsigned);
extern void gimple_gen_ior_profiler (histogram_value, unsigned, unsigned);
extern void stream_out_histogram_value (struct output_block *, histogram_value);
-extern void stream_in_histogram_value (struct lto_input_block *, gimple *);
+extern void stream_in_histogram_value (class lto_input_block *, gimple *);
extern struct cgraph_node* find_func_by_profile_id (int func_id);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index c2b4204..67f25c1 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -929,8 +929,9 @@ static poly_int64 hard_frame_pointer_adjustment = -1;
/* Data for adjust_mems callback. */
-struct adjust_mem_data
+class adjust_mem_data
{
+public:
bool store;
machine_mode mem_mode;
HOST_WIDE_INT stack_adjust;
@@ -1030,7 +1031,7 @@ use_narrower_mode (rtx x, scalar_int_mode mode, scalar_int_mode wmode)
static rtx
adjust_mems (rtx loc, const_rtx old_rtx, void *data)
{
- struct adjust_mem_data *amd = (struct adjust_mem_data *) data;
+ class adjust_mem_data *amd = (class adjust_mem_data *) data;
rtx mem, addr = loc, tem;
machine_mode mem_mode_save;
bool store_save;
@@ -6388,7 +6389,7 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
if (!frame_pointer_needed)
{
- struct adjust_mem_data amd;
+ class adjust_mem_data amd;
amd.mem_mode = VOIDmode;
amd.stack_adjust = -VTI (bb)->out.stack_adjust;
amd.store = true;
@@ -8061,8 +8062,9 @@ delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
/* Structure for passing some other parameters to function
vt_expand_loc_callback. */
-struct expand_loc_callback_data
+class expand_loc_callback_data
{
+public:
/* The variables and values active at this point. */
variable_table_type *vars;
@@ -8328,8 +8330,8 @@ static inline rtx
vt_expand_var_loc_chain (variable *var, bitmap regs, void *data,
bool *pendrecp)
{
- struct expand_loc_callback_data *elcd
- = (struct expand_loc_callback_data *) data;
+ class expand_loc_callback_data *elcd
+ = (class expand_loc_callback_data *) data;
location_chain *loc, *next;
rtx result = NULL;
int first_child, result_first_child, last_child;
@@ -8467,8 +8469,8 @@ vt_expand_loc_callback (rtx x, bitmap regs,
int max_depth ATTRIBUTE_UNUSED,
void *data)
{
- struct expand_loc_callback_data *elcd
- = (struct expand_loc_callback_data *) data;
+ class expand_loc_callback_data *elcd
+ = (class expand_loc_callback_data *) data;
decl_or_value dv;
variable *var;
rtx result, subreg;
@@ -8625,7 +8627,7 @@ resolve_expansions_pending_recursion (vec<rtx, va_heap> *pending)
static rtx
vt_expand_loc (rtx loc, variable_table_type *vars)
{
- struct expand_loc_callback_data data;
+ class expand_loc_callback_data data;
rtx result;
if (!MAY_HAVE_DEBUG_BIND_INSNS)
@@ -8647,7 +8649,7 @@ vt_expand_loc (rtx loc, variable_table_type *vars)
static rtx
vt_expand_1pvar (variable *var, variable_table_type *vars)
{
- struct expand_loc_callback_data data;
+ class expand_loc_callback_data data;
rtx loc;
gcc_checking_assert (var->onepart && var->n_var_parts == 1);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 626a4c9..e886cdc 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -68,8 +68,8 @@ extern GTY(()) const char *weak_global_object_name;
const char *first_global_object_name;
const char *weak_global_object_name;
-struct addr_const;
-struct constant_descriptor_rtx;
+class addr_const;
+class constant_descriptor_rtx;
struct rtx_constant_pool;
#define n_deferred_constants (crtl->varasm.deferred_constants)
@@ -105,7 +105,7 @@ static int contains_pointers_p (tree);
#ifdef ASM_OUTPUT_EXTERNAL
static bool incorporeal_function_p (tree);
#endif
-static void decode_addr_const (tree, struct addr_const *);
+static void decode_addr_const (tree, class addr_const *);
static hashval_t const_hash_1 (const tree);
static int compare_constant (const tree, const tree);
static void output_constant_def_contents (rtx);
@@ -2899,13 +2899,14 @@ assemble_real (REAL_VALUE_TYPE d, scalar_float_mode mode, unsigned int align,
Store them both in the structure *VALUE.
EXP must be reducible. */
-struct addr_const {
+class addr_const {
+public:
rtx base;
poly_int64 offset;
};
static void
-decode_addr_const (tree exp, struct addr_const *value)
+decode_addr_const (tree exp, class addr_const *value)
{
tree target = TREE_OPERAND (exp, 0);
poly_int64 offset = 0;
@@ -3075,7 +3076,7 @@ const_hash_1 (const tree exp)
/* Fallthru. */
case FDESC_EXPR:
{
- struct addr_const value;
+ class addr_const value;
decode_addr_const (exp, &value);
switch (GET_CODE (value.base))
@@ -3271,7 +3272,7 @@ compare_constant (const tree t1, const tree t2)
case ADDR_EXPR:
case FDESC_EXPR:
{
- struct addr_const value1, value2;
+ class addr_const value1, value2;
enum rtx_code code;
int ret;
@@ -3621,8 +3622,9 @@ tree_output_constant_def (tree exp)
return decl;
}
-struct GTY((chain_next ("%h.next"), for_user)) constant_descriptor_rtx {
- struct constant_descriptor_rtx *next;
+class GTY((chain_next ("%h.next"), for_user)) constant_descriptor_rtx {
+public:
+ class constant_descriptor_rtx *next;
rtx mem;
rtx sym;
rtx constant;
@@ -3649,8 +3651,8 @@ struct const_rtx_desc_hasher : ggc_ptr_hash<constant_descriptor_rtx>
struct GTY(()) rtx_constant_pool {
/* Pointers to first and last constant in pool, as ordered by offset. */
- struct constant_descriptor_rtx *first;
- struct constant_descriptor_rtx *last;
+ class constant_descriptor_rtx *first;
+ class constant_descriptor_rtx *last;
/* Hash facility for making memory-constants from constant rtl-expressions.
It is used on RISC machines where immediate integer arguments and
@@ -3810,7 +3812,7 @@ simplify_subtraction (rtx x)
rtx
force_const_mem (machine_mode in_mode, rtx x)
{
- struct constant_descriptor_rtx *desc, tmp;
+ class constant_descriptor_rtx *desc, tmp;
struct rtx_constant_pool *pool;
char label[256];
rtx def, symbol;
@@ -3918,7 +3920,7 @@ get_pool_constant (const_rtx addr)
rtx
get_pool_constant_mark (rtx addr, bool *pmarked)
{
- struct constant_descriptor_rtx *desc;
+ class constant_descriptor_rtx *desc;
desc = SYMBOL_REF_CONSTANT (addr);
*pmarked = (desc->mark != 0);
@@ -4026,7 +4028,7 @@ output_constant_pool_2 (fixed_size_mode mode, rtx x, unsigned int align)
giving it ALIGN bits of alignment. */
static void
-output_constant_pool_1 (struct constant_descriptor_rtx *desc,
+output_constant_pool_1 (class constant_descriptor_rtx *desc,
unsigned int align)
{
rtx x, tmp;
@@ -4103,7 +4105,7 @@ output_constant_pool_1 (struct constant_descriptor_rtx *desc,
static void
recompute_pool_offsets (struct rtx_constant_pool *pool)
{
- struct constant_descriptor_rtx *desc;
+ class constant_descriptor_rtx *desc;
pool->offset = 0;
for (desc = pool->first; desc ; desc = desc->next)
@@ -4132,7 +4134,7 @@ mark_constants_in_pattern (rtx insn)
{
if (CONSTANT_POOL_ADDRESS_P (x))
{
- struct constant_descriptor_rtx *desc = SYMBOL_REF_CONSTANT (x);
+ class constant_descriptor_rtx *desc = SYMBOL_REF_CONSTANT (x);
if (desc->mark == 0)
{
desc->mark = 1;
@@ -4201,7 +4203,7 @@ mark_constant_pool (void)
static void
output_constant_pool_contents (struct rtx_constant_pool *pool)
{
- struct constant_descriptor_rtx *desc;
+ class constant_descriptor_rtx *desc;
for (desc = pool->first; desc ; desc = desc->next)
if (desc->mark)
@@ -7450,7 +7452,7 @@ void
place_block_symbol (rtx symbol)
{
unsigned HOST_WIDE_INT size, mask, offset;
- struct constant_descriptor_rtx *desc;
+ class constant_descriptor_rtx *desc;
unsigned int alignment;
struct object_block *block;
tree decl;
@@ -7612,7 +7614,7 @@ get_section_anchor (struct object_block *block, HOST_WIDE_INT offset,
static void
output_object_block (struct object_block *block)
{
- struct constant_descriptor_rtx *desc;
+ class constant_descriptor_rtx *desc;
unsigned int i;
HOST_WIDE_INT offset;
tree decl;
diff --git a/gcc/vec.c b/gcc/vec.c
index f474922..cbd2db0 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -49,8 +49,9 @@ along with GCC; see the file COPYING3. If not see
vnull vNULL;
/* Vector memory usage. */
-struct vec_usage: public mem_usage
+class vec_usage: public mem_usage
{
+public:
/* Default constructor. */
vec_usage (): m_items (0), m_items_peak (0), m_element_size (0) {}
diff --git a/gcc/vector-builder.h b/gcc/vector-builder.h
index 9f95b01..aac8a87 100644
--- a/gcc/vector-builder.h
+++ b/gcc/vector-builder.h
@@ -199,14 +199,15 @@ template<typename T, typename Derived>
T
vector_builder<T, Derived>::elt (unsigned int i) const
{
- /* This only makes sense if the encoding has been fully populated. */
- gcc_checking_assert (encoded_nelts () <= this->length ());
-
/* First handle elements that are already present in the underlying
vector, regardless of whether they're part of the encoding or not. */
if (i < this->length ())
return (*this)[i];
+ /* Extrapolation is only possible if the encoding has been fully
+ populated. */
+ gcc_checking_assert (encoded_nelts () <= this->length ());
+
/* Identify the pattern that contains element I and work out the index of
the last encoded element for that pattern. */
unsigned int pattern = i % m_npatterns;
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 3f20c1a..9a4aea0 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -1711,7 +1711,7 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
for VAR. If so, update VR with the new limits. */
void
-vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
+vr_values::adjust_range_with_scev (value_range *vr, class loop *loop,
gimple *stmt, tree var)
{
tree init, step, chrec, tmin, tmax, min, max, type, tem;
@@ -2806,7 +2806,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
value_range *lhs_vr = get_value_range (lhs);
bool first = true;
int edges, old_edges;
- struct loop *l;
+ class loop *l;
if (dump_file && (dump_flags & TDF_DETAILS))
{
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index bd67f73..3856da1 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -46,7 +46,7 @@ class vr_values
void set_defs_to_varying (gimple *);
bool update_value_range (const_tree, value_range *);
tree op_with_constant_singleton_value_range (tree);
- void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
+ void adjust_range_with_scev (value_range *, class loop *, gimple *, tree);
tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
void dump_all_value_ranges (FILE *);
diff --git a/gcc/web.c b/gcc/web.c
index 4a9bec0..dcc15ca 100644
--- a/gcc/web.c
+++ b/gcc/web.c
@@ -74,7 +74,7 @@ unionfind_union (web_entry_base *first, web_entry_base *second)
return false;
}
-class web_entry : public web_entry_base
+struct web_entry : public web_entry_base
{
private:
rtx reg_pvt;
diff --git a/gcc/wide-int-bitmask.h b/gcc/wide-int-bitmask.h
index 529756f..e95e463 100644
--- a/gcc/wide-int-bitmask.h
+++ b/gcc/wide-int-bitmask.h
@@ -20,8 +20,9 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_WIDE_INT_BITMASK_H
#define GCC_WIDE_INT_BITMASK_H
-struct wide_int_bitmask
+class wide_int_bitmask
{
+public:
inline wide_int_bitmask ();
inline wide_int_bitmask (uint64_t l);
inline wide_int_bitmask (uint64_t l, uint64_t h);
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index 25ea054..6c816cc 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -329,7 +329,7 @@ typedef generic_wide_int < fixed_wide_int_storage <WIDE_INT_MAX_PRECISION * 2> >
/* wi::storage_ref can be a reference to a primitive type,
so this is the conservatively-correct setting. */
template <bool SE, bool HDP = true>
-struct wide_int_ref_storage;
+class wide_int_ref_storage;
typedef generic_wide_int <wide_int_ref_storage <false> > wide_int_ref;
@@ -642,8 +642,9 @@ namespace wi
{
/* Contains the components of a decomposed integer for easy, direct
access. */
- struct storage_ref
+ class storage_ref
{
+ public:
storage_ref () {}
storage_ref (const HOST_WIDE_INT *, unsigned int, unsigned int);
@@ -968,7 +969,7 @@ decompose (HOST_WIDE_INT *, unsigned int precision,
wide_int, with the optimization that VAL is normally a pointer to
another integer's storage, so that no array copy is needed. */
template <bool SE, bool HDP>
-struct wide_int_ref_storage : public wi::storage_ref
+class wide_int_ref_storage : public wi::storage_ref
{
private:
/* Scratch space that can be used when decomposing the original integer.
@@ -1357,7 +1358,7 @@ namespace wi
bytes beyond the sizeof need to be allocated. Use set_precision
to initialize the structure. */
template <int N>
-class GTY((user)) trailing_wide_ints
+struct GTY((user)) trailing_wide_ints
{
private:
/* The shared precision of each number. */
@@ -1554,8 +1555,9 @@ namespace wi
{
/* Stores HWI-sized integer VAL, treating it as having signedness SGN
and precision PRECISION. */
- struct hwi_with_prec
+ class hwi_with_prec
{
+ public:
hwi_with_prec () {}
hwi_with_prec (HOST_WIDE_INT, unsigned int, signop);
HOST_WIDE_INT val;
@@ -3032,8 +3034,7 @@ wi::lshift (const T1 &x, const T2 &y)
if (STATIC_CONSTANT_P (xi.precision > HOST_BITS_PER_WIDE_INT)
? (STATIC_CONSTANT_P (shift < HOST_BITS_PER_WIDE_INT - 1)
&& xi.len == 1
- && xi.val[0] <= (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT)
- HOST_WIDE_INT_MAX >> shift))
+ && IN_RANGE (xi.val[0], 0, HOST_WIDE_INT_MAX >> shift))
: precision <= HOST_BITS_PER_WIDE_INT)
{
val[0] = xi.ulow () << shift;
diff --git a/include/ChangeLog b/include/ChangeLog
index 6d09a8d..a4f3fe5 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2019-07-18 Eduard-Mihai Burtescu <eddyb@lyken.rs>
+
+ * demangle.h (rust_is_mangled): Move to libiberty/rust-demangle.h.
+ (rust_demangle_sym): Move to libiberty/rust-demangle.h.
+
2019-06-18 Thomas Schwinge <thomas@codesourcery.com>
* gomp-constants.h (enum gomp_map_kind): Fix description of
diff --git a/include/demangle.h b/include/demangle.h
index f5d9b9e..06c3257 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -159,24 +159,6 @@ ada_demangle (const char *mangled, int options);
extern char *
dlang_demangle (const char *mangled, int options);
-/* Returns non-zero iff MANGLED is a rust mangled symbol. MANGLED must
- already have been demangled through cplus_demangle_v3. If this function
- returns non-zero then MANGLED can be demangled (in-place) using
- RUST_DEMANGLE_SYM. */
-extern int
-rust_is_mangled (const char *mangled);
-
-/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
- If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
- replace characters that cannot be demangled with '?' and might truncate
- SYM. After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
- larger. */
-extern void
-rust_demangle_sym (char *sym);
-
-/* Demangles MANGLED if it was GNU_V3 and then RUST mangled, otherwise
- returns NULL. Uses CPLUS_DEMANGLE_V3, RUST_IS_MANGLED and
- RUST_DEMANGLE_SYM. Returns a new string that is owned by the caller. */
extern char *
rust_demangle (const char *mangled, int options);
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index ff5f0aa..c6e8e04 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,9 @@
+2019-07-09 Martin Sebor <msebor@redhat.com>
+
+ * include/line-map.h: Change class-key from class to struct and vice
+ versa to match convention and avoid -Wclass-is-pod and -Wstruct-no-pod.
+ * mkdeps.c: Same.
+
2019-07-03 Martin Liska <mliska@suse.cz>
* line-map.c (linemap_get_expansion_filename): Remove
diff --git a/libcpp/directives-only.c b/libcpp/directives-only.c
index ea9aa1d..847225a 100644
--- a/libcpp/directives-only.c
+++ b/libcpp/directives-only.c
@@ -88,7 +88,7 @@ _cpp_preprocess_dir_only (cpp_reader *pfile,
{
if (c != '#' && (flags & DO_BOL))
{
- struct line_maps *line_table;
+ class line_maps *line_table;
if (!pfile->state.skipping && next_line != base)
cb->print_lines (lines, base, next_line - base);
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 2fdfaf0..ddf8979 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -943,7 +943,7 @@ strtolinenum (const uchar *str, size_t len, linenum_type *nump, bool *wrapped)
static void
do_line (cpp_reader *pfile)
{
- struct line_maps *line_table = pfile->line_table;
+ class line_maps *line_table = pfile->line_table;
const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
/* skip_rest_of_line() may cause line table to be realloc()ed so note down
@@ -1006,7 +1006,7 @@ do_line (cpp_reader *pfile)
static void
do_linemarker (cpp_reader *pfile)
{
- struct line_maps *line_table = pfile->line_table;
+ class line_maps *line_table = pfile->line_table;
const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
const cpp_token *token;
const char *new_file = ORDINARY_MAP_FILE_NAME (map);
@@ -2544,7 +2544,7 @@ cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
}
/* The dependencies structure. (Creates one if it hasn't already been.) */
-struct mkdeps *
+class mkdeps *
cpp_get_deps (cpp_reader *pfile)
{
if (!pfile->deps)
diff --git a/libcpp/files.c b/libcpp/files.c
index 3255cbf..6ef6d07 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -1369,7 +1369,7 @@ void
cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
{
int flags = 0;
- const struct line_maps *line_table = pfile->line_table;
+ const class line_maps *line_table = pfile->line_table;
const line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (line_table);
/* 1 = system header, 2 = system header to be treated as C. */
if (syshdr)
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 91d97f9..a645f81 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -935,11 +935,11 @@ class cpp_substring_ranges
that cpplib will share; this technique is used by the C front
ends. */
extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *,
- struct line_maps *);
+ class line_maps *);
/* Reset the cpp_reader's line_map. This is only used after reading a
PCH file. */
-extern void cpp_set_line_map (cpp_reader *, struct line_maps *);
+extern void cpp_set_line_map (cpp_reader *, class line_maps *);
/* Call this to change the selected language standard (e.g. because of
command line options). */
@@ -956,7 +956,7 @@ extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int);
extern cpp_options *cpp_get_options (cpp_reader *);
extern cpp_callbacks *cpp_get_callbacks (cpp_reader *);
extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
-extern struct mkdeps *cpp_get_deps (cpp_reader *);
+extern class mkdeps *cpp_get_deps (cpp_reader *);
/* This function reads the file, but does not start preprocessing. It
returns the name of the original file; this is the same as the
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 7649700..bde5e53 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -592,14 +592,14 @@ MAP_ORDINARY_P (const line_map *map)
/* Return TRUE if MAP encodes locations coming from a macro
replacement-list at macro expansion point. */
bool
-linemap_macro_expansion_map_p (const struct line_map *);
+linemap_macro_expansion_map_p (const line_map *);
/* Assert that MAP encodes locations of tokens that are not part of
the replacement-list of a macro expansion, downcasting from
line_map * to line_map_ordinary *. */
inline line_map_ordinary *
-linemap_check_ordinary (struct line_map *map)
+linemap_check_ordinary (line_map *map)
{
linemap_assert (MAP_ORDINARY_P (map));
return (line_map_ordinary *)map;
@@ -610,7 +610,7 @@ linemap_check_ordinary (struct line_map *map)
const line_map * to const line_map_ordinary *. */
inline const line_map_ordinary *
-linemap_check_ordinary (const struct line_map *map)
+linemap_check_ordinary (const line_map *map)
{
linemap_assert (MAP_ORDINARY_P (map));
return (const line_map_ordinary *)map;
@@ -770,7 +770,8 @@ struct GTY(()) location_adhoc_data_map {
};
/* A set of chronological line_map structures. */
-struct GTY(()) line_maps {
+class GTY(()) line_maps {
+public:
~line_maps ();
@@ -1050,12 +1051,12 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
return (line_map_macro *)LINEMAPS_LAST_ALLOCATED_MAP (set, true);
}
-extern location_t get_combined_adhoc_loc (struct line_maps *,
+extern location_t get_combined_adhoc_loc (class line_maps *,
location_t,
source_range,
void *);
-extern void *get_data_from_adhoc_loc (const struct line_maps *, location_t);
-extern location_t get_location_from_adhoc_loc (const struct line_maps *,
+extern void *get_data_from_adhoc_loc (const line_maps *, location_t);
+extern location_t get_location_from_adhoc_loc (const line_maps *,
location_t);
extern source_range get_range_from_loc (line_maps *set, location_t loc);
@@ -1075,7 +1076,7 @@ extern location_t get_pure_location (line_maps *set,
/* Combine LOC and BLOCK, giving a combined adhoc location. */
inline location_t
-COMBINE_LOCATION_DATA (struct line_maps *set,
+COMBINE_LOCATION_DATA (class line_maps *set,
location_t loc,
source_range src_range,
void *block)
@@ -1083,18 +1084,18 @@ COMBINE_LOCATION_DATA (struct line_maps *set,
return get_combined_adhoc_loc (set, loc, src_range, block);
}
-extern void rebuild_location_adhoc_htab (struct line_maps *);
+extern void rebuild_location_adhoc_htab (class line_maps *);
/* Initialize a line map set. SET is the line map set to initialize
and BUILTIN_LOCATION is the special location value to be used as
spelling location for built-in tokens. This BUILTIN_LOCATION has
to be strictly less than RESERVED_LOCATION_COUNT. */
-extern void linemap_init (struct line_maps *set,
+extern void linemap_init (class line_maps *set,
location_t builtin_location);
/* Check for and warn about line_maps entered but not exited. */
-extern void linemap_check_files_exited (struct line_maps *);
+extern void linemap_check_files_exited (class line_maps *);
/* Return a location_t for the start (i.e. column==0) of
(physical) line TO_LINE in the current source file (as in the
@@ -1103,7 +1104,7 @@ extern void linemap_check_files_exited (struct line_maps *);
the highest_location). */
extern location_t linemap_line_start
-(struct line_maps *set, linenum_type to_line, unsigned int max_column_hint);
+(class line_maps *set, linenum_type to_line, unsigned int max_column_hint);
/* Add a mapping of logical source line to physical source file and
line number. This function creates an "ordinary map", which is a
@@ -1118,8 +1119,8 @@ extern location_t linemap_line_start
A call to this function can relocate the previous set of
maps, so any stored line_map pointers should not be used. */
-extern const struct line_map *linemap_add
- (struct line_maps *, enum lc_reason, unsigned int sysp,
+extern const line_map *linemap_add
+ (class line_maps *, enum lc_reason, unsigned int sysp,
const char *to_file, linenum_type to_line);
/* Given a logical source location, returns the map which the
@@ -1128,12 +1129,12 @@ extern const struct line_map *linemap_add
monotonic increasing, and so the list is sorted and we can use a
binary search. If no line map have been allocated yet, this
function returns NULL. */
-extern const struct line_map *linemap_lookup
- (struct line_maps *, location_t);
+extern const line_map *linemap_lookup
+ (class line_maps *, location_t);
/* Returns TRUE if the line table set tracks token locations across
macro expansion, FALSE otherwise. */
-bool linemap_tracks_macro_expansion_locs_p (struct line_maps *);
+bool linemap_tracks_macro_expansion_locs_p (class line_maps *);
/* Return the name of the macro associated to MACRO_MAP. */
const char* linemap_map_get_macro_name (const line_map_macro *);
@@ -1147,17 +1148,17 @@ const char* linemap_map_get_macro_name (const line_map_macro *);
Note that this function returns 1 if LOCATION belongs to a token
that is part of a macro replacement-list defined in a system
header, but expanded in a non-system file. */
-int linemap_location_in_system_header_p (struct line_maps *,
+int linemap_location_in_system_header_p (class line_maps *,
location_t);
/* Return TRUE if LOCATION is a source code location of a token that is part of
a macro expansion, FALSE otherwise. */
-bool linemap_location_from_macro_expansion_p (const struct line_maps *,
+bool linemap_location_from_macro_expansion_p (const line_maps *,
location_t);
/* TRUE if LOCATION is a source code location of a token that is part of the
definition of a macro, FALSE otherwise. */
-bool linemap_location_from_macro_definition_p (struct line_maps *,
+bool linemap_location_from_macro_definition_p (class line_maps *,
location_t);
/* With the precondition that LOCATION is the locus of a token that is
@@ -1213,7 +1214,7 @@ MAIN_FILE_P (const line_map_ordinary *ord_map)
linemap_line_start, i.e, the last source line which a location was
encoded from. */
extern location_t
-linemap_position_for_column (struct line_maps *, unsigned int);
+linemap_position_for_column (class line_maps *, unsigned int);
/* Encode and return a source location from a given line and
column. */
@@ -1226,7 +1227,7 @@ linemap_position_for_line_and_column (line_maps *set,
shifting it by OFFSET columns. This function does not support
virtual locations. */
location_t
-linemap_position_for_loc_and_offset (struct line_maps *set,
+linemap_position_for_loc_and_offset (class line_maps *set,
location_t loc,
unsigned int offset);
@@ -1258,7 +1259,7 @@ LINEMAP_SYSP (const line_map_ordinary *ord_map)
comes before the token of POST, 0 if PRE denotes the location of
the same token as the token for POST, and a negative value
otherwise. */
-int linemap_compare_locations (struct line_maps *set,
+int linemap_compare_locations (class line_maps *set,
location_t pre,
location_t post);
@@ -1266,7 +1267,7 @@ int linemap_compare_locations (struct line_maps *set,
topogically before the token denoted by location LOC_B, or if they
are equal. */
inline bool
-linemap_location_before_p (struct line_maps *set,
+linemap_location_before_p (class line_maps *set,
location_t loc_a,
location_t loc_b)
{
@@ -1783,8 +1784,9 @@ protected:
of localized text, and a flag to determine if the caller should "free" the
buffer. */
-struct label_text
+class label_text
{
+public:
label_text ()
: m_buffer (NULL), m_caller_owned (false)
{}
@@ -1935,7 +1937,7 @@ enum location_resolution_kind
resolves to a location reserved for the client code, like
UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
-location_t linemap_resolve_location (struct line_maps *,
+location_t linemap_resolve_location (class line_maps *,
location_t loc,
enum location_resolution_kind lrk,
const line_map_ordinary **loc_map);
@@ -1947,9 +1949,9 @@ location_t linemap_resolve_location (struct line_maps *,
the point where M' was expanded. LOC_MAP is an output parameter.
When non-NULL, *LOC_MAP is set to the map of the returned
location. */
-location_t linemap_unwind_toward_expansion (struct line_maps *,
+location_t linemap_unwind_toward_expansion (class line_maps *,
location_t loc,
- const struct line_map **loc_map);
+ const line_map **loc_map);
/* If LOC is the virtual location of a token coming from the expansion
of a macro M and if its spelling location is reserved (e.g, a
@@ -1965,16 +1967,16 @@ location_t linemap_unwind_toward_expansion (struct line_maps *,
*MAP is set to the map of the returned location if the later is
different from LOC. */
-location_t linemap_unwind_to_first_non_reserved_loc (struct line_maps *,
+location_t linemap_unwind_to_first_non_reserved_loc (class line_maps *,
location_t loc,
- const struct line_map **map);
+ const line_map **map);
/* Expand source code location LOC and return a user readable source
code location. LOC must be a spelling (non-virtual) location. If
it's a location < RESERVED_LOCATION_COUNT a zeroed expanded source
location is returned. */
-expanded_location linemap_expand_location (struct line_maps *,
- const struct line_map *,
+expanded_location linemap_expand_location (class line_maps *,
+ const line_map *,
location_t loc);
/* Statistics about maps allocation and usage as returned by
@@ -2000,27 +2002,27 @@ struct linemap_stats
there is a line map in SET. FILE_NAME is the file name to
consider. If the function returns TRUE, *LOC is set to the highest
location emitted for that file. */
-bool linemap_get_file_highest_location (struct line_maps * set,
+bool linemap_get_file_highest_location (class line_maps * set,
const char *file_name,
location_t *loc);
/* Compute and return statistics about the memory consumption of some
parts of the line table SET. */
-void linemap_get_statistics (struct line_maps *, struct linemap_stats *);
+void linemap_get_statistics (line_maps *, struct linemap_stats *);
/* Dump debugging information about source location LOC into the file
stream STREAM. SET is the line map set LOC comes from. */
-void linemap_dump_location (struct line_maps *, location_t, FILE *);
+void linemap_dump_location (line_maps *, location_t, FILE *);
/* Dump line map at index IX in line table SET to STREAM. If STREAM
is NULL, use stderr. IS_MACRO is true if the caller wants to
dump a macro map, false otherwise. */
-void linemap_dump (FILE *, struct line_maps *, unsigned, bool);
+void linemap_dump (FILE *, line_maps *, unsigned, bool);
/* Dump line table SET to STREAM. If STREAM is NULL, stderr is used.
NUM_ORDINARY specifies how many ordinary maps to dump. NUM_MACRO
specifies how many macro maps to dump. */
-void line_table_dump (FILE *, struct line_maps *, unsigned int, unsigned int);
+void line_table_dump (FILE *, line_maps *, unsigned int, unsigned int);
/* An enum for distinguishing the various parts within a location_t. */
diff --git a/libcpp/include/mkdeps.h b/libcpp/include/mkdeps.h
index e0ac21f..c6eb24f 100644
--- a/libcpp/include/mkdeps.h
+++ b/libcpp/include/mkdeps.h
@@ -26,48 +26,48 @@ along with this program; see the file COPYING3. If not see
/* This is the data structure used by all the functions in mkdeps.c.
It's quite straightforward, but should be treated as opaque. */
-struct mkdeps;
+class mkdeps;
/* Create a deps buffer. */
-extern struct mkdeps *deps_init (void);
+extern class mkdeps *deps_init (void);
/* Destroy a deps buffer. */
-extern void deps_free (struct mkdeps *);
+extern void deps_free (class mkdeps *);
/* Add a set of "vpath" directories. The second argument is a colon-
separated list of pathnames, like you would set Make's VPATH
variable to. If a dependency or target name begins with any of
these pathnames (and the next path element is not "..") that
pathname is stripped off. */
-extern void deps_add_vpath (struct mkdeps *, const char *);
+extern void deps_add_vpath (class mkdeps *, const char *);
/* Add a target (appears on left side of the colon) to the deps list. Takes
a boolean indicating whether to quote the target for MAKE. */
-extern void deps_add_target (struct mkdeps *, const char *, int);
+extern void deps_add_target (class mkdeps *, const char *, int);
/* Sets the default target if none has been given already. An empty
string as the default target is interpreted as stdin. */
-extern void deps_add_default_target (struct mkdeps *, const char *);
+extern void deps_add_default_target (class mkdeps *, const char *);
/* Add a dependency (appears on the right side of the colon) to the
deps list. Dependencies will be printed in the order that they
were entered with this function. By convention, the first
dependency entered should be the primary source file. */
-extern void deps_add_dep (struct mkdeps *, const char *);
+extern void deps_add_dep (class mkdeps *, const char *);
/* Write out a deps buffer to a specified file. The third argument
is the number of columns to word-wrap at (0 means don't wrap). */
-extern void deps_write (const struct mkdeps *, FILE *, bool, unsigned int);
+extern void deps_write (const class mkdeps *, FILE *, bool, unsigned int);
/* Write out a deps buffer to a file, in a form that can be read back
with deps_restore. Returns nonzero on error, in which case the
error number will be in errno. */
-extern int deps_save (struct mkdeps *, FILE *);
+extern int deps_save (class mkdeps *, FILE *);
/* Read back dependency information written with deps_save into
the deps buffer. The third argument may be NULL, in which case
the dependency information is just skipped, or it may be a filename,
in which case that filename is skipped. */
-extern int deps_restore (struct mkdeps *, FILE *, const char *);
+extern int deps_restore (class mkdeps *, FILE *, const char *);
#endif /* ! LIBCPP_MKDEPS_H */
diff --git a/libcpp/init.c b/libcpp/init.c
index d06f95e..472f104 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -171,7 +171,7 @@ init_library (void)
/* Initialize a cpp_reader structure. */
cpp_reader *
cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
- struct line_maps *line_table)
+ class line_maps *line_table)
{
cpp_reader *pfile;
@@ -286,7 +286,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,
/* Set the line_table entry in PFILE. This is called after reading a
PCH file, as the old line_table will be incorrect. */
void
-cpp_set_line_map (cpp_reader *pfile, struct line_maps *line_table)
+cpp_set_line_map (cpp_reader *pfile, class line_maps *line_table)
{
pfile->line_table = line_table;
}
diff --git a/libcpp/internal.h b/libcpp/internal.h
index 0ab4470..45167a9 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -67,7 +67,7 @@ struct cset_converter
#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
#define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \
- const struct line_maps *line_table = PFILE->line_table; \
+ const class line_maps *line_table = PFILE->line_table; \
const struct line_map_ordinary *map = \
LINEMAPS_LAST_ORDINARY_MAP (line_table); \
linenum_type line = SOURCE_LINE (map, line_table->highest_line); \
@@ -393,7 +393,7 @@ struct cpp_reader
struct lexer_state state;
/* Source line tracking. */
- struct line_maps *line_table;
+ class line_maps *line_table;
/* The line of the '#' of the current directive. */
location_t directive_line;
@@ -508,7 +508,7 @@ struct cpp_reader
cpp_token eof;
/* Opaque handle to the dependencies of mkdeps.c. */
- struct mkdeps *deps;
+ class mkdeps *deps;
/* Obstack holding all macro hash nodes. This never shrinks.
See identifiers.c */
@@ -863,7 +863,7 @@ ufputs (const unsigned char *s, FILE *f)
of the macro, rather than the the location of the first character
of the macro. NUM_TOKENS is the number of tokens that are part of
the replacement-list of MACRO. */
-const line_map_macro *linemap_enter_macro (struct line_maps *,
+const line_map_macro *linemap_enter_macro (class line_maps *,
struct cpp_hashnode*,
location_t,
unsigned int);
@@ -900,7 +900,7 @@ location_t linemap_add_macro_token (const line_map_macro *,
LOCATION is the location of token that is part of the
expansion-list of a macro expansion return the line number of the
macro expansion point. */
-int linemap_get_expansion_line (struct line_maps *,
+int linemap_get_expansion_line (class line_maps *,
location_t);
/* Return the path of the file corresponding to source code location
@@ -911,7 +911,7 @@ int linemap_get_expansion_line (struct line_maps *,
macro expansion point.
SET is the line map set LOCATION comes from. */
-const char* linemap_get_expansion_filename (struct line_maps *,
+const char* linemap_get_expansion_filename (class line_maps *,
location_t);
#ifdef __cplusplus
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 8ab873b..572d7f4 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -26,17 +26,17 @@ along with this program; see the file COPYING3. If not see
#include "internal.h"
#include "hashtab.h"
-static void trace_include (const struct line_maps *, const line_map_ordinary *);
-static const line_map_ordinary * linemap_ordinary_map_lookup (struct line_maps *,
+static void trace_include (const line_maps *, const line_map_ordinary *);
+static const line_map_ordinary * linemap_ordinary_map_lookup (line_maps *,
location_t);
-static const line_map_macro* linemap_macro_map_lookup (struct line_maps *,
+static const line_map_macro* linemap_macro_map_lookup (line_maps *,
location_t);
static location_t linemap_macro_map_loc_to_def_point
(const line_map_macro *, location_t);
static location_t linemap_macro_map_loc_to_exp_point
(const line_map_macro *, location_t);
static location_t linemap_macro_loc_to_spelling_point
-(struct line_maps *, location_t, const line_map_ordinary **);
+(line_maps *, location_t, const line_map_ordinary **);
static location_t linemap_macro_loc_to_def_point (line_maps *,
location_t,
const line_map_ordinary **);
@@ -98,7 +98,7 @@ location_adhoc_data_update (void **slot, void *data)
/* Rebuild the hash table from the location adhoc data. */
void
-rebuild_location_adhoc_htab (struct line_maps *set)
+rebuild_location_adhoc_htab (line_maps *set)
{
unsigned i;
set->location_adhoc_data_map.htab =
@@ -113,7 +113,7 @@ rebuild_location_adhoc_htab (struct line_maps *set)
within a location_t, without needing to use an ad-hoc location. */
static bool
-can_be_stored_compactly_p (struct line_maps *set,
+can_be_stored_compactly_p (line_maps *set,
location_t locus,
source_range src_range,
void *data)
@@ -154,7 +154,7 @@ can_be_stored_compactly_p (struct line_maps *set,
/* Combine LOCUS and DATA to a combined adhoc loc. */
location_t
-get_combined_adhoc_loc (struct line_maps *set,
+get_combined_adhoc_loc (line_maps *set,
location_t locus,
source_range src_range,
void *data)
@@ -242,7 +242,7 @@ get_combined_adhoc_loc (struct line_maps *set,
/* Return the data for the adhoc loc. */
void *
-get_data_from_adhoc_loc (const struct line_maps *set, location_t loc)
+get_data_from_adhoc_loc (const class line_maps *set, location_t loc)
{
linemap_assert (IS_ADHOC_LOC (loc));
return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data;
@@ -251,7 +251,7 @@ get_data_from_adhoc_loc (const struct line_maps *set, location_t loc)
/* Return the location for the adhoc loc. */
location_t
-get_location_from_adhoc_loc (const struct line_maps *set, location_t loc)
+get_location_from_adhoc_loc (const class line_maps *set, location_t loc)
{
linemap_assert (IS_ADHOC_LOC (loc));
return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].locus;
@@ -260,7 +260,7 @@ get_location_from_adhoc_loc (const struct line_maps *set, location_t loc)
/* Return the source_range for adhoc location LOC. */
static source_range
-get_range_from_adhoc_loc (const struct line_maps *set, location_t loc)
+get_range_from_adhoc_loc (const class line_maps *set, location_t loc)
{
linemap_assert (IS_ADHOC_LOC (loc));
return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].src_range;
@@ -270,7 +270,7 @@ get_range_from_adhoc_loc (const struct line_maps *set, location_t loc)
lookaside table, or embedded inside LOC itself. */
source_range
-get_range_from_loc (struct line_maps *set,
+get_range_from_loc (line_maps *set,
location_t loc)
{
if (IS_ADHOC_LOC (loc))
@@ -337,12 +337,12 @@ get_pure_location (line_maps *set, location_t loc)
/* Initialize a line map set. */
void
-linemap_init (struct line_maps *set,
+linemap_init (line_maps *set,
location_t builtin_location)
{
#if __GNUC__ == 4 && __GNUC_MINOR__ == 2 && !defined (__clang__)
/* PR33916, needed to fix PR82939. */
- memset (set, 0, sizeof (struct line_maps));
+ memset (set, 0, sizeof (line_maps));
#else
new (set) line_maps();
#endif
@@ -367,7 +367,7 @@ linemap_included_from_linemap (line_maps *set, const line_map_ordinary *map)
/* Check for and warn about line_maps entered but not exited. */
void
-linemap_check_files_exited (struct line_maps *set)
+linemap_check_files_exited (line_maps *set)
{
/* Depending upon whether we are handling preprocessed input or
not, this can be a user error or an ICE. */
@@ -384,7 +384,7 @@ linemap_check_files_exited (struct line_maps *set)
macro maps are allocated in different memory location. */
static struct line_map *
-new_linemap (struct line_maps *set, location_t start_location)
+new_linemap (line_maps *set, location_t start_location)
{
bool macro_p = start_location >= LINE_MAP_MAX_LOCATION;
unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
@@ -457,7 +457,7 @@ new_linemap (struct line_maps *set, location_t start_location)
maps, so any stored line_map pointers should not be used. */
const struct line_map *
-linemap_add (struct line_maps *set, enum lc_reason reason,
+linemap_add (line_maps *set, enum lc_reason reason,
unsigned int sysp, const char *to_file, linenum_type to_line)
{
/* Generate a start_location above the current highest_location.
@@ -578,7 +578,7 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
macro expansion, FALSE otherwise. */
bool
-linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
+linemap_tracks_macro_expansion_locs_p (line_maps *set)
{
return LINEMAPS_MACRO_MAPS (set) != NULL;
}
@@ -607,7 +607,7 @@ linemap_tracks_macro_expansion_locs_p (struct line_maps *set)
macro tokens anymore. */
const line_map_macro *
-linemap_enter_macro (struct line_maps *set, struct cpp_hashnode *macro_node,
+linemap_enter_macro (class line_maps *set, struct cpp_hashnode *macro_node,
location_t expansion, unsigned int num_tokens)
{
location_t start_location
@@ -682,7 +682,7 @@ linemap_add_macro_token (const line_map_macro *map,
the highest_location). */
location_t
-linemap_line_start (struct line_maps *set, linenum_type to_line,
+linemap_line_start (line_maps *set, linenum_type to_line,
unsigned int max_column_hint)
{
line_map_ordinary *map = LINEMAPS_LAST_ORDINARY_MAP (set);
@@ -791,7 +791,7 @@ linemap_line_start (struct line_maps *set, linenum_type to_line,
encoded from. */
location_t
-linemap_position_for_column (struct line_maps *set, unsigned int to_column)
+linemap_position_for_column (line_maps *set, unsigned int to_column)
{
location_t r = set->highest_line;
@@ -863,7 +863,7 @@ linemap_position_for_line_and_column (line_maps *set,
virtual locations. */
location_t
-linemap_position_for_loc_and_offset (struct line_maps *set,
+linemap_position_for_loc_and_offset (line_maps *set,
location_t loc,
unsigned int column_offset)
{
@@ -929,7 +929,7 @@ linemap_position_for_loc_and_offset (struct line_maps *set,
ordinary or a macro map), returns that map. */
const struct line_map*
-linemap_lookup (struct line_maps *set, location_t line)
+linemap_lookup (line_maps *set, location_t line)
{
if (IS_ADHOC_LOC (line))
line = get_location_from_adhoc_loc (set, line);
@@ -944,7 +944,7 @@ linemap_lookup (struct line_maps *set, location_t line)
binary search. */
static const line_map_ordinary *
-linemap_ordinary_map_lookup (struct line_maps *set, location_t line)
+linemap_ordinary_map_lookup (line_maps *set, location_t line)
{
unsigned int md, mn, mx;
const line_map_ordinary *cached, *result;
@@ -992,7 +992,7 @@ linemap_ordinary_map_lookup (struct line_maps *set, location_t line)
binary search. */
static const line_map_macro *
-linemap_macro_map_lookup (struct line_maps *set, location_t line)
+linemap_macro_map_lookup (line_maps *set, location_t line)
{
unsigned int md, mn, mx;
const struct line_map_macro *cached, *result;
@@ -1122,7 +1122,7 @@ linemap_macro_map_loc_unwind_toward_spelling (line_maps *set,
macro expansion point. */
int
-linemap_get_expansion_line (struct line_maps *set,
+linemap_get_expansion_line (line_maps *set,
location_t location)
{
const line_map_ordinary *map = NULL;
@@ -1149,7 +1149,7 @@ linemap_get_expansion_line (struct line_maps *set,
SET is the line map set LOCATION comes from. */
const char*
-linemap_get_expansion_filename (struct line_maps *set,
+linemap_get_expansion_filename (line_maps *set,
location_t location)
{
const struct line_map_ordinary *map = NULL;
@@ -1185,7 +1185,7 @@ linemap_map_get_macro_name (const line_map_macro *macro_map)
header, but expanded in a non-system file. */
int
-linemap_location_in_system_header_p (struct line_maps *set,
+linemap_location_in_system_header_p (line_maps *set,
location_t location)
{
const struct line_map *map = NULL;
@@ -1230,7 +1230,7 @@ linemap_location_in_system_header_p (struct line_maps *set,
a macro expansion, FALSE otherwise. */
bool
-linemap_location_from_macro_expansion_p (const struct line_maps *set,
+linemap_location_from_macro_expansion_p (const class line_maps *set,
location_t location)
{
if (IS_ADHOC_LOC (location))
@@ -1245,7 +1245,7 @@ linemap_location_from_macro_expansion_p (const struct line_maps *set,
virtual location of the token inside the resulting macro. */
static const struct line_map*
-first_map_in_common_1 (struct line_maps *set,
+first_map_in_common_1 (line_maps *set,
location_t *loc0,
location_t *loc1)
{
@@ -1292,7 +1292,7 @@ first_map_in_common_1 (struct line_maps *set,
return of a non-NULL result. */
static const struct line_map*
-first_map_in_common (struct line_maps *set,
+first_map_in_common (line_maps *set,
location_t loc0,
location_t loc1,
location_t *res_loc0,
@@ -1310,7 +1310,7 @@ first_map_in_common (struct line_maps *set,
otherwise. */
int
-linemap_compare_locations (struct line_maps *set,
+linemap_compare_locations (line_maps *set,
location_t pre,
location_t post)
{
@@ -1366,7 +1366,7 @@ linemap_compare_locations (struct line_maps *set,
/* Print an include trace, for e.g. the -H option of the preprocessor. */
static void
-trace_include (const struct line_maps *set, const line_map_ordinary *map)
+trace_include (const class line_maps *set, const line_map_ordinary *map)
{
unsigned int i = set->depth;
@@ -1382,7 +1382,7 @@ trace_include (const struct line_maps *set, const line_map_ordinary *map)
This is a subroutine for linemap_resolve_location. */
static location_t
-linemap_macro_loc_to_spelling_point (struct line_maps *set,
+linemap_macro_loc_to_spelling_point (line_maps *set,
location_t location,
const line_map_ordinary **original_map)
{
@@ -1416,7 +1416,7 @@ linemap_macro_loc_to_spelling_point (struct line_maps *set,
This is a subroutine of linemap_resolve_location. */
static location_t
-linemap_macro_loc_to_def_point (struct line_maps *set,
+linemap_macro_loc_to_def_point (line_maps *set,
location_t location,
const line_map_ordinary **original_map)
{
@@ -1458,7 +1458,7 @@ linemap_macro_loc_to_def_point (struct line_maps *set,
This is a subroutine of linemap_resolve_location. */
static location_t
-linemap_macro_loc_to_exp_point (struct line_maps *set,
+linemap_macro_loc_to_exp_point (line_maps *set,
location_t location,
const line_map_ordinary **original_map)
{
@@ -1532,7 +1532,7 @@ linemap_macro_loc_to_exp_point (struct line_maps *set,
UNKNOWN_LOCATION or BUILTINS_LOCATION in GCC. */
location_t
-linemap_resolve_location (struct line_maps *set,
+linemap_resolve_location (line_maps *set,
location_t loc,
enum location_resolution_kind lrk,
const line_map_ordinary **map)
@@ -1572,7 +1572,7 @@ linemap_resolve_location (struct line_maps *set,
definition of a macro, FALSE otherwise. */
bool
-linemap_location_from_macro_definition_p (struct line_maps *set,
+linemap_location_from_macro_definition_p (line_maps *set,
location_t loc)
{
if (IS_ADHOC_LOC (loc))
@@ -1612,7 +1612,7 @@ linemap_location_from_macro_definition_p (struct line_maps *set,
to the map of the returned location. */
location_t
-linemap_unwind_toward_expansion (struct line_maps *set,
+linemap_unwind_toward_expansion (line_maps *set,
location_t loc,
const struct line_map **map)
{
@@ -1652,7 +1652,7 @@ linemap_unwind_toward_expansion (struct line_maps *set,
*MAP is set to the map of the returned location if the later is
different from LOC. */
location_t
-linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
+linemap_unwind_to_first_non_reserved_loc (line_maps *set,
location_t loc,
const struct line_map **map)
{
@@ -1696,7 +1696,7 @@ linemap_unwind_to_first_non_reserved_loc (struct line_maps *set,
location is returned. */
expanded_location
-linemap_expand_location (struct line_maps *set,
+linemap_expand_location (line_maps *set,
const struct line_map *map,
location_t loc)
@@ -1745,7 +1745,7 @@ linemap_expand_location (struct line_maps *set,
dump a macro map, false otherwise. */
void
-linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
+linemap_dump (FILE *stream, class line_maps *set, unsigned ix, bool is_macro)
{
const char *const lc_reasons_v[LC_HWM]
= { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
@@ -1801,7 +1801,7 @@ linemap_dump (FILE *stream, struct line_maps *set, unsigned ix, bool is_macro)
stream STREAM. SET is the line map set LOC comes from. */
void
-linemap_dump_location (struct line_maps *set,
+linemap_dump_location (line_maps *set,
location_t loc,
FILE *stream)
{
@@ -1851,7 +1851,7 @@ linemap_dump_location (struct line_maps *set,
location emitted for that file. */
bool
-linemap_get_file_highest_location (struct line_maps *set,
+linemap_get_file_highest_location (line_maps *set,
const char *file_name,
location_t *loc)
{
@@ -1889,7 +1889,7 @@ linemap_get_file_highest_location (struct line_maps *set,
parts of the line table SET. */
void
-linemap_get_statistics (struct line_maps *set,
+linemap_get_statistics (line_maps *set,
struct linemap_stats *s)
{
long ordinary_maps_allocated_size, ordinary_maps_used_size,
@@ -1953,7 +1953,7 @@ linemap_get_statistics (struct line_maps *set,
specifies how many macro maps to dump. */
void
-line_table_dump (FILE *stream, struct line_maps *set, unsigned int num_ordinary,
+line_table_dump (FILE *stream, class line_maps *set, unsigned int num_ordinary,
unsigned int num_macro)
{
unsigned int i;
diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c
index 50f0fb2..147aa90 100644
--- a/libcpp/mkdeps.c
+++ b/libcpp/mkdeps.c
@@ -29,7 +29,7 @@ along with this program; see the file COPYING3. If not see
/* Keep this structure local to this file, so clients don't find it
easy to start making assumptions. */
-struct mkdeps
+class mkdeps
{
public:
/* T has trivial cctor & dtor. */
@@ -184,7 +184,7 @@ munge (const char *str, const char *trail = NULL, ...)
/* If T begins with any of the partial pathnames listed in d->vpathv,
then advance T to point beyond that pathname. */
static const char *
-apply_vpath (struct mkdeps *d, const char *t)
+apply_vpath (class mkdeps *d, const char *t)
{
if (unsigned len = d->vpath.size ())
for (unsigned i = len; i--;)
@@ -222,14 +222,14 @@ apply_vpath (struct mkdeps *d, const char *t)
/* Public routines. */
-struct mkdeps *
+class mkdeps *
deps_init (void)
{
return new mkdeps ();
}
void
-deps_free (struct mkdeps *d)
+deps_free (class mkdeps *d)
{
delete d;
}
@@ -237,7 +237,7 @@ deps_free (struct mkdeps *d)
/* Adds a target T. We make a copy, so it need not be a permanent
string. QUOTE is true if the string should be quoted. */
void
-deps_add_target (struct mkdeps *d, const char *t, int quote)
+deps_add_target (class mkdeps *d, const char *t, int quote)
{
t = xstrdup (apply_vpath (d, t));
@@ -261,7 +261,7 @@ deps_add_target (struct mkdeps *d, const char *t, int quote)
string as the default target in interpreted as stdin. The string
is quoted for MAKE. */
void
-deps_add_default_target (struct mkdeps *d, const char *tgt)
+deps_add_default_target (class mkdeps *d, const char *tgt)
{
/* Only if we have no targets. */
if (d->targets.size ())
@@ -291,7 +291,7 @@ deps_add_default_target (struct mkdeps *d, const char *tgt)
}
void
-deps_add_dep (struct mkdeps *d, const char *t)
+deps_add_dep (class mkdeps *d, const char *t)
{
gcc_assert (*t);
@@ -301,7 +301,7 @@ deps_add_dep (struct mkdeps *d, const char *t)
}
void
-deps_add_vpath (struct mkdeps *d, const char *vpath)
+deps_add_vpath (class mkdeps *d, const char *vpath)
{
const char *elem, *p;
@@ -367,7 +367,7 @@ make_write_vec (const mkdeps::vec<const char *> &vec, FILE *fp,
.PHONY targets for all the dependencies too. */
static void
-make_write (const struct mkdeps *d, FILE *fp, bool phony, unsigned int colmax)
+make_write (const class mkdeps *d, FILE *fp, bool phony, unsigned int colmax)
{
unsigned column = 0;
if (colmax && colmax < 34)
@@ -390,7 +390,7 @@ make_write (const struct mkdeps *d, FILE *fp, bool phony, unsigned int colmax)
only Make at the moment). */
void
-deps_write (const struct mkdeps *d, FILE *fp, bool phony, unsigned int colmax)
+deps_write (const class mkdeps *d, FILE *fp, bool phony, unsigned int colmax)
{
make_write (d, fp, phony, colmax);
}
@@ -400,7 +400,7 @@ deps_write (const struct mkdeps *d, FILE *fp, bool phony, unsigned int colmax)
error number will be in errno. */
int
-deps_save (struct mkdeps *deps, FILE *f)
+deps_save (class mkdeps *deps, FILE *f)
{
unsigned int i;
size_t size;
@@ -432,7 +432,7 @@ deps_save (struct mkdeps *deps, FILE *f)
in which case that filename is skipped. */
int
-deps_restore (struct mkdeps *deps, FILE *fd, const char *self)
+deps_restore (class mkdeps *deps, FILE *fd, const char *self)
{
size_t size;
char *buf = NULL;
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index f9f900b..7997ad8 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,20 @@
+2019-07-22 Martin Liska <mliska@suse.cz>
+
+ * config/pa/stublib.c: Remove stub symbol __gnu_lto_v1.
+ * config/pa/t-stublib: Likewise.
+
+2019-07-22 Stafford Horne <shorne@gmail.com>
+
+ PR target/90362
+ * config/or1k/lib1funcs.S (__udivsi3): Change l.sfeqi
+ to l.sfeq and l.sfltsi to l.sflts equivalents as the immediate
+ instructions are not available on every processor. Change a
+ l.bnf to l.bf to fix logic issue.
+
+2019-07-04 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config.host: Remove reference to t-darwin8.
+
2019-07-03 Iain Sandoe <iain@sandoe.co.uk>
* config.host (powerpc-*-darwin*,powerpc64-*-darwin*): Revise crt
diff --git a/libgcc/config.host b/libgcc/config.host
index e11a065..f5ca779 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -1084,11 +1084,9 @@ powerpc-*-darwin*)
case ${host} in
*-*-darwin9* | *-*-darwin[12][0-9]*)
# libSystem contains unwind information for signal frames since
- # Darwin 9. We don't need longcall either.
+ # Darwin 9.
;;
*)
- # prepend the fragment forcing darwin8 codegen.
- tmake_file="rs6000/t-darwin8 $tmake_file"
md_unwind_header=rs6000/darwin-unwind.h
;;
esac
diff --git a/libgcc/config/or1k/lib1funcs.S b/libgcc/config/or1k/lib1funcs.S
index d210392..6d05897 100644
--- a/libgcc/config/or1k/lib1funcs.S
+++ b/libgcc/config/or1k/lib1funcs.S
@@ -68,18 +68,18 @@ __udivmodsi3_internal:
is not clobbered by this routine, and use that as to
save a return address without creating a stack frame. */
- l.sfeqi r4, 0 /* division by zero; return 0. */
+ l.sfeq r4, r0 /* division by zero; return 0. */
l.ori r11, r0, 0 /* initial quotient */
l.bf 9f
l.ori r12, r3, 0 /* initial remainder */
/* Given X/Y, shift Y left until Y >= X. */
l.ori r6, r0, 1 /* mask = 1 */
-1: l.sfltsi r4, 0 /* y has msb set */
+1: l.sflts r4, r0 /* y has msb set */
l.bf 2f
l.sfltu r4, r12 /* y < x */
l.add r4, r4, r4 /* y <<= 1 */
- l.bnf 1b
+ l.bf 1b
l.add r6, r6, r6 /* mask <<= 1 */
/* Shift Y back to the right again, subtracting from X. */
diff --git a/libgcc/config/pa/stublib.c b/libgcc/config/pa/stublib.c
index b47afe1..7e79dbf 100644
--- a/libgcc/config/pa/stublib.c
+++ b/libgcc/config/pa/stublib.c
@@ -115,7 +115,3 @@ pthread_once (void)
return 0;
}
#endif
-
-#ifdef L_gnu_lto_v1
-char gnu_lto_v1;
-#endif
diff --git a/libgcc/config/pa/t-stublib b/libgcc/config/pa/t-stublib
index 0a6223d..8004c1e 100644
--- a/libgcc/config/pa/t-stublib
+++ b/libgcc/config/pa/t-stublib
@@ -3,8 +3,7 @@ LIBGCCSTUB_OBJS = rfi-stub.o dfi-stub.o ritm-stub.o ditm-stub.o \
pthread_default_stacksize_np-stub.o \
pthread_mutex_lock-stub.o \
pthread_mutex_unlock-stub.o \
- pthread_once-stub.o \
- gnu_lto_v1-stub.o
+ pthread_once-stub.o
rfi-stub.o: $(srcdir)/config/pa/stublib.c
$(gcc_compile) -c -O2 -DL_register_frame_info $<
@@ -36,9 +35,6 @@ pthread_mutex_unlock-stub.o: $(srcdir)/config/pa/stublib.c
pthread_once-stub.o: $(srcdir)/config/pa/stublib.c
$(gcc_compile) -c -O2 -DL_pthread_once $<
-gnu_lto_v1-stub.o: $(srcdir)/config/pa/stublib.c
- $(gcc_compile) -c -O2 -DL_gnu_lto_v1 $<
-
libgcc_stub.a: $(LIBGCCSTUB_OBJS)
-rm -rf $@
$(AR) rc $@ $(LIBGCCSTUB_OBJS)
diff --git a/libgcc/generic-morestack.c b/libgcc/generic-morestack.c
index 0f6f000..2dc3733 100644
--- a/libgcc/generic-morestack.c
+++ b/libgcc/generic-morestack.c
@@ -23,6 +23,8 @@ a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
+#pragma GCC optimize ("no-isolate-erroneous-paths-dereference")
+
/* powerpc 32-bit not supported. */
#if !defined __powerpc__ || defined __powerpc64__
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 71fe27b..b4e3fe7 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,21 @@
+2019-07-21 Thomas König <tkoenig@gcc.gnu.org>
+
+ PR libfortran/91030
+ * io/unix.c (BUFFER_SIZE): Delete.
+ (BUFFER_FORMATTED_SIZE_DEFAULT): New variable.
+ (BUFFER_UNFORMATTED_SIZE_DEFAULT): New variable.
+ (unix_stream): Add buffer_size.
+ (buf_read): Use s->buffer_size instead of BUFFER_SIZE.
+ (buf_write): Likewise.
+ (buf_init): Add argument unformatted. Handle block sizes
+ for unformatted vs. formatted, using defaults if provided.
+ (fd_to_stream): Add argument unformatted in call to buf_init.
+ * libgfortran.h (options_t): Add buffer_size_formatted and
+ buffer_size_unformatted.
+ * runtime/environ.c (variable_table): Add
+ GFORTRAN_UNFORMATTED_BUFFER_SIZE and
+ GFORTRAN_FORMATTED_BUFFER_SIZE.
+
2019-06-25 Kwok Cheung Yeung <kcy@codesourcery.com>
Andrew Stubbs <ams@codesourcery.com>
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index c2fc674..4279297 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -193,7 +193,8 @@ fallback_access (const char *path, int mode)
/* Unix and internal stream I/O module */
-static const int BUFFER_SIZE = 8192;
+static const int FORMATTED_BUFFER_SIZE_DEFAULT = 8192;
+static const int UNFORMATTED_BUFFER_SIZE_DEFAULT = 128*1024;
typedef struct
{
@@ -205,6 +206,7 @@ typedef struct
gfc_offset file_length; /* Length of the file. */
char *buffer; /* Pointer to the buffer. */
+ ssize_t buffer_size; /* Length of the buffer. */
int fd; /* The POSIX file descriptor. */
int active; /* Length of valid bytes in the buffer */
@@ -592,9 +594,9 @@ buf_read (unix_stream *s, void *buf, ssize_t nbyte)
&& raw_seek (s, new_logical, SEEK_SET) < 0)
return -1;
s->buffer_offset = s->physical_offset = new_logical;
- if (to_read <= BUFFER_SIZE/2)
+ if (to_read <= s->buffer_size/2)
{
- did_read = raw_read (s, s->buffer, BUFFER_SIZE);
+ did_read = raw_read (s, s->buffer, s->buffer_size);
if (likely (did_read >= 0))
{
s->physical_offset += did_read;
@@ -632,11 +634,11 @@ buf_write (unix_stream *s, const void *buf, ssize_t nbyte)
s->buffer_offset = s->logical_offset;
/* Does the data fit into the buffer? As a special case, if the
- buffer is empty and the request is bigger than BUFFER_SIZE/2,
+ buffer is empty and the request is bigger than s->buffer_size/2,
write directly. This avoids the case where the buffer would have
to be flushed at every write. */
- if (!(s->ndirty == 0 && nbyte > BUFFER_SIZE/2)
- && s->logical_offset + nbyte <= s->buffer_offset + BUFFER_SIZE
+ if (!(s->ndirty == 0 && nbyte > s->buffer_size/2)
+ && s->logical_offset + nbyte <= s->buffer_offset + s->buffer_size
&& s->buffer_offset <= s->logical_offset
&& s->buffer_offset + s->ndirty >= s->logical_offset)
{
@@ -651,7 +653,7 @@ buf_write (unix_stream *s, const void *buf, ssize_t nbyte)
the request is bigger than the buffer size, write directly
bypassing the buffer. */
buf_flush (s);
- if (nbyte <= BUFFER_SIZE/2)
+ if (nbyte <= s->buffer_size/2)
{
memcpy (s->buffer, buf, nbyte);
s->buffer_offset = s->logical_offset;
@@ -688,7 +690,7 @@ buf_write (unix_stream *s, const void *buf, ssize_t nbyte)
static int
buf_markeor (unix_stream *s)
{
- if (s->unbuffered || s->ndirty >= BUFFER_SIZE / 2)
+ if (s->unbuffered || s->ndirty >= s->buffer_size / 2)
return buf_flush (s);
return 0;
}
@@ -765,11 +767,32 @@ static const struct stream_vtable buf_vtable = {
};
static int
-buf_init (unix_stream *s)
+buf_init (unix_stream *s, bool unformatted)
{
s->st.vptr = &buf_vtable;
- s->buffer = xmalloc (BUFFER_SIZE);
+ /* Try to guess a good value for the buffer size. For formatted
+ I/O, we use so many CPU cycles converting the data that there is
+ more sense in converving memory and especially cache. For
+ unformatted, a bigger block can have a large impact in some
+ environments. */
+
+ if (unformatted)
+ {
+ if (options.unformatted_buffer_size > 0)
+ s->buffer_size = options.unformatted_buffer_size;
+ else
+ s->buffer_size = UNFORMATTED_BUFFER_SIZE_DEFAULT;
+ }
+ else
+ {
+ if (options.formatted_buffer_size > 0)
+ s->buffer_size = options.formatted_buffer_size;
+ else
+ s->buffer_size = FORMATTED_BUFFER_SIZE_DEFAULT;
+ }
+
+ s->buffer = xmalloc (s->buffer_size);
return 0;
}
@@ -1120,13 +1143,13 @@ fd_to_stream (int fd, bool unformatted)
(s->fd == STDIN_FILENO
|| s->fd == STDOUT_FILENO
|| s->fd == STDERR_FILENO)))
- buf_init (s);
+ buf_init (s, unformatted);
else
{
if (unformatted)
{
s->unbuffered = true;
- buf_init (s);
+ buf_init (s, unformatted);
}
else
raw_init (s);
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 433b204..c0db96f 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -540,6 +540,7 @@ typedef struct
int all_unbuffered, unbuffered_preconnected;
int fpe, backtrace;
+ int unformatted_buffer_size, formatted_buffer_size;
}
options_t;
diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c
index e3e7d24..5817d19 100644
--- a/libgfortran/runtime/environ.c
+++ b/libgfortran/runtime/environ.c
@@ -198,6 +198,14 @@ static variable variable_table[] = {
/* Print out a backtrace if possible on runtime error */
{ "GFORTRAN_ERROR_BACKTRACE", -1, &options.backtrace, init_boolean },
+ /* Buffer size for unformatted files. */
+ { "GFORTRAN_UNFORMATTED_BUFFER_SIZE", 0, &options.unformatted_buffer_size,
+ init_integer },
+
+ /* Buffer size for formatted files. */
+ { "GFORTRAN_FORMATTED_BUFFER_SIZE", 0, &options.formatted_buffer_size,
+ init_integer },
+
{ NULL, 0, NULL, NULL }
};
diff --git a/libgo/go/runtime/chan.go b/libgo/go/runtime/chan.go
index 6dfe2f3..6c8d6f7 100644
--- a/libgo/go/runtime/chan.go
+++ b/libgo/go/runtime/chan.go
@@ -32,6 +32,9 @@ import (
//go:linkname chanrecv1 runtime.chanrecv1
//go:linkname chanrecv2 runtime.chanrecv2
//go:linkname closechan runtime.closechan
+//go:linkname selectnbsend runtime.selectnbsend
+//go:linkname selectnbrecv runtime.selectnbrecv
+//go:linkname selectnbrecv2 runtime.selectnbrecv2
const (
maxAlign = 8
diff --git a/libgo/go/runtime/select.go b/libgo/go/runtime/select.go
index d658a34..16de9b8 100644
--- a/libgo/go/runtime/select.go
+++ b/libgo/go/runtime/select.go
@@ -14,6 +14,7 @@ import (
// themselves, so that the compiler will export them.
//
//go:linkname selectgo runtime.selectgo
+//go:linkname block runtime.block
const debugSelect = false
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 26125cc..523dfd9 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -65,7 +65,7 @@ static void gscanstack(G*);
#define __thread
#endif
-static __thread G *g;
+__thread G *g __asm__(GOSYM_PREFIX "runtime.g");
#ifndef SETCONTEXT_CLOBBERS_TLS
@@ -320,7 +320,7 @@ runtime_mcall(FuncVal *fv)
if(gp != nil) {
#ifdef USING_SPLIT_STACK
- __splitstack_getcontext((void*)(&g->stackcontext[0]));
+ __splitstack_getcontext((void*)(&gp->stackcontext[0]));
#else
// We have to point to an address on the stack that is
// below the saved registers.
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index e54f260..547ce4e 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,39 @@
+2019-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c-c++-common/loop-1.c: New test.
+
+2019-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c++/scan-13.C: Replace xfail with target x86.
+ * testsuite/libgomp.c++/scan-16.C: Likewise.
+
+2019-07-06 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/scan-19.c: New test.
+ * testsuite/libgomp.c/scan-20.c: New test.
+
+ * testsuite/libgomp.c/scan-11.c: New test.
+ * testsuite/libgomp.c/scan-12.c: New test.
+ * testsuite/libgomp.c/scan-13.c: New test.
+ * testsuite/libgomp.c/scan-14.c: New test.
+ * testsuite/libgomp.c/scan-15.c: New test.
+ * testsuite/libgomp.c/scan-16.c: New test.
+ * testsuite/libgomp.c/scan-17.c: New test.
+ * testsuite/libgomp.c/scan-18.c: New test.
+ * testsuite/libgomp.c++/scan-9.C: New test.
+ * testsuite/libgomp.c++/scan-10.C: New test.
+ * testsuite/libgomp.c++/scan-11.C: New test.
+ * testsuite/libgomp.c++/scan-12.C: New test.
+ * testsuite/libgomp.c++/scan-13.C: New test.
+ * testsuite/libgomp.c++/scan-14.C: New test.
+ * testsuite/libgomp.c++/scan-15.C: New test.
+ * testsuite/libgomp.c++/scan-16.C: New test.
+
+2019-07-04 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/scan-9.c: New test.
+ * testsuite/libgomp.c/scan-10.c: New test.
+
2019-07-03 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c++/scan-1.C: New test.
diff --git a/libgomp/testsuite/libgomp.c++/scan-10.C b/libgomp/testsuite/libgomp.c++/scan-10.C
new file mode 100644
index 0000000..c72ba6e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-10.C
@@ -0,0 +1,119 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for simd if (0) reduction (inscan, +:r) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd simdlen(1) reduction (inscan, +:s) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-11.C b/libgomp/testsuite/libgomp.c++/scan-11.C
new file mode 100644
index 0000000..d618f12
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-11.C
@@ -0,0 +1,122 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, foo:s) if (0)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-12.C b/libgomp/testsuite/libgomp.c++/scan-12.C
new file mode 100644
index 0000000..6f9bfc3
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-12.C
@@ -0,0 +1,153 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b, S &r)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+bar ()
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b, S &r)
+{
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+qux ()
+{
+ S s;
+ #pragma omp parallel for simd reduction (inscan, plus:s) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ r.s = 0;
+ baz (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-13.C b/libgomp/testsuite/libgomp.c++/scan-13.C
new file mode 100644
index 0000000..9d00625
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-13.C
@@ -0,0 +1,161 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } }
+
+extern "C" void abort ();
+
+template <typename T>
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ T s;
+};
+
+template <typename T>
+S<T>::S () : s (0)
+{
+}
+
+template <typename T>
+S<T>::~S ()
+{
+}
+
+template <typename T>
+S<T>::S (const S &x)
+{
+ s = x.s;
+}
+
+template <typename T>
+S<T> &
+S<T>::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+template <typename T>
+static inline void
+ini (S<T> &x)
+{
+ x.s = 0;
+}
+
+S<int> r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S<int>: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S<int>: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+template <typename T>
+__attribute__((noipa)) void
+foo (S<T> *a, S<T> *b)
+{
+ #pragma omp for simd if (0) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) S<T>
+bar (void)
+{
+ S<T> s;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return S<T> (s);
+}
+
+__attribute__((noipa)) void
+baz (S<int> *a, S<int> *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S<int>
+qux (void)
+{
+ S<int> s;
+ #pragma omp parallel for simd simdlen(1) reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return S<int> (s);
+}
+
+int
+main ()
+{
+ S<int> s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (bar<int> ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+ r.s = 0;
+ baz (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-14.C b/libgomp/testsuite/libgomp.c++/scan-14.C
new file mode 100644
index 0000000..197ec6e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-14.C
@@ -0,0 +1,123 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+template <typename T, typename U>
+__attribute__((noipa)) void
+foo (T a, T b, U r)
+{
+ #pragma omp for simd if (0) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) T
+bar ()
+{
+ T &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+template <typename T>
+__attribute__((noipa)) void
+baz (T *a, T *b, T &r)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (T i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+template <typename T>
+__attribute__((noipa)) int
+qux ()
+{
+ T s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo<int *, int &> (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar<int> () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz<int> (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux<int &> () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-15.C b/libgomp/testsuite/libgomp.c++/scan-15.C
new file mode 100644
index 0000000..b6a8787
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-15.C
@@ -0,0 +1,121 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+int r, a[1024], b[1024], q;
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b, int &r)
+{
+ #pragma omp for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, foo:s) nowait
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, int &r)
+{
+ #pragma omp parallel for simd reduction (inscan, foo:r) if (simd: 0)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int &s = q;
+ q = 0;
+ #pragma omp parallel for simd reduction (inscan, foo:s)simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b, r);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-16.C b/libgomp/testsuite/libgomp.c++/scan-16.C
new file mode 100644
index 0000000..108660b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-16.C
@@ -0,0 +1,153 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target i?86-*-* x86_64-*-* } } }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b, S &r)
+{
+ #pragma omp for simd simdlen (1) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S
+bar (void)
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for simd if (0) reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b, S &r)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r.s += a[i].s;
+ }
+}
+
+__attribute__((noipa)) S
+qux (void)
+{
+ S s;
+ #pragma omp parallel for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s.s += 2 * a[i].s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+ r.s = 0;
+ baz (a, b, r);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ s.s += i;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i].s != s.s)
+ abort ();
+ s.s += 2 * i;
+ }
+}
diff --git a/libgomp/testsuite/libgomp.c++/scan-9.C b/libgomp/testsuite/libgomp.c++/scan-9.C
new file mode 100644
index 0000000..340004e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/scan-9.C
@@ -0,0 +1,154 @@
+// { dg-require-effective-target size32plus }
+// { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" }
+// { dg-additional-options "-mavx" { target avx_runtime } }
+// { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } }
+
+extern "C" void abort ();
+
+struct S {
+ inline S ();
+ inline ~S ();
+ inline S (const S &);
+ inline S & operator= (const S &);
+ int s;
+};
+
+S::S () : s (0)
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+ s = x.s;
+}
+
+S &
+S::operator= (const S &x)
+{
+ s = x.s;
+ return *this;
+}
+
+static inline void
+ini (S &x)
+{
+ x.s = 0;
+}
+
+S r, a[1024], b[1024];
+
+#pragma omp declare reduction (+: S: omp_out.s += omp_in.s)
+#pragma omp declare reduction (plus: S: omp_out.s += omp_in.s) initializer (ini (omp_priv))
+
+__attribute__((noipa)) void
+foo (S *a, S *b)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+bar (void)
+{
+ S s;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return S (s);
+}
+
+__attribute__((noipa)) void
+baz (S *a, S *b)
+{
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r.s += a[i].s;
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) S
+qux (void)
+{
+ S s;
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, plus:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s.s += 2 * a[i].s;
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return S (s);
+}
+
+int
+main ()
+{
+ S s;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i].s = i;
+ b[i].s = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (bar ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ r.s = 0;
+ baz (a, b);
+ if (r.s != 1024 * 1023 / 2)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += i;
+ if (b[i].s != s.s)
+ abort ();
+ else
+ b[i].s = 25;
+ }
+ if (qux ().s != 1024 * 1023)
+ abort ();
+ s.s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s.s += 2 * i;
+ if (b[i].s != s.s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/loop-1.c b/libgomp/testsuite/libgomp.c-c++-common/loop-1.c
new file mode 100644
index 0000000..de69608
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/loop-1.c
@@ -0,0 +1,127 @@
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void abort (void);
+#define N 256
+int r;
+
+void
+foo (int *a)
+{
+ int i, j;
+ #pragma omp loop bind(thread) order(concurrent) private (j) lastprivate (i) reduction(+:r) collapse(1)
+ for (i = 0; i < N; i++)
+ {
+ j = i - 2;
+ a[i] = j;
+ r += j;
+ }
+}
+
+void
+bar (int *a)
+{
+ int i, j;
+ #pragma omp loop bind(parallel) order(concurrent) private (j) lastprivate (i) reduction(+:r) collapse(1)
+ for (i = 0; i < N; i++)
+ {
+ j = i;
+ a[i] = j;
+ r += j;
+ }
+}
+
+void
+baz (int *a)
+{
+ int i, j;
+ #pragma omp loop bind(teams) order(concurrent) private (j) lastprivate (i) reduction(+:r)
+ for (i = 0; i < N; i++)
+ {
+ j = i + 2;
+ a[i] = j;
+ r += j;
+ }
+}
+
+int
+main ()
+{
+ int a[N], i, j;
+ foo (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i - 2)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N - 5) / 2)
+ abort ();
+ else
+ r = 0;
+ bar (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N - 1) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp parallel loop private (j) lastprivate (i) reduction(+:r)
+ for (i = 0; i < N; i++)
+ {
+ j = i + 4;
+ a[i] = j;
+ r += j;
+ }
+ if (i != N)
+ abort ();
+ for (i = 0; i < N; ++i)
+ if (a[i] != i + 4)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N + 7) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp parallel
+ bar (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N - 1) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp teams
+ baz (a);
+ for (i = 0; i < N; ++i)
+ if (a[i] != i + 2)
+ abort ();
+ else
+ a[i] = -35;
+ if (r != N * (N + 3) / 2)
+ abort ();
+ else
+ r = 0;
+ #pragma omp teams loop order(concurrent) private (j) lastprivate (i) reduction(+:r) collapse(1)
+ for (i = 0; i < N; i++)
+ {
+ j = i - 4;
+ a[i] = j;
+ r += j;
+ }
+ if (i != N)
+ abort ();
+ for (i = 0; i < N; ++i)
+ if (a[i] != i - 4)
+ abort ();
+ if (r != N * (N - 9) / 2)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-10.c b/libgomp/testsuite/libgomp.c/scan-10.c
new file mode 100644
index 0000000..0005ce1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-10.c
@@ -0,0 +1,116 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ #pragma omp scan exclusive(r)
+ { y = a[i]; r += y + x + 12; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = s; b[i] = y + x + 12; }
+ #pragma omp scan exclusive(s)
+ { y = 2 * a[i]; s += y; z = y; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r) firstprivate (x) lastprivate (x)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ { r += a[i] + x + 12; if (i == 1023) x = 29; }
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ #pragma omp scan exclusive(s)
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-11.c b/libgomp/testsuite/libgomp.c/scan-11.c
new file mode 100644
index 0000000..7443a50
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-11.c
@@ -0,0 +1,118 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) if (0)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-12.c b/libgomp/testsuite/libgomp.c/scan-12.c
new file mode 100644
index 0000000..6e32046
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-12.c
@@ -0,0 +1,120 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, foo:r) simdlen (1)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r += a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s += 2 * a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-13.c b/libgomp/testsuite/libgomp.c/scan-13.c
new file mode 100644
index 0000000..3c8ce2d
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-13.c
@@ -0,0 +1,91 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+float r = 1.0f, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (float *a, float *b)
+{
+ #pragma omp for simd reduction (inscan, *:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ r *= a[i];
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) float
+bar (void)
+{
+ float s = -__builtin_inff ();
+ #pragma omp parallel for simd reduction (inscan, max:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ s = s > a[i] ? s : a[i];
+ #pragma omp scan inclusive(s)
+ b[i] = s;
+ }
+ return s;
+}
+
+int
+main ()
+{
+ float s = 1.0f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (i < 80)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 200)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else if (i < 280)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 380)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else
+ switch (i % 6)
+ {
+ case 0: a[i] = 0.25f; break;
+ case 1: a[i] = 2.0f; break;
+ case 2: a[i] = -1.0f; break;
+ case 3: a[i] = -4.0f; break;
+ case 4: a[i] = 0.5f; break;
+ case 5: a[i] = 1.0f; break;
+ default: a[i] = 0.0f; break;
+ }
+ b[i] = -19.0f;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r * 16384.0f != 0.125f)
+ abort ();
+ float m = -175.25f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s *= a[i];
+ if (b[i] != s)
+ abort ();
+ else
+ {
+ a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
+ b[i] = -231.75f;
+ m += 0.75f;
+ }
+ }
+ if (bar () != 592.0f)
+ abort ();
+ s = -__builtin_inff ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (s < a[i])
+ s = a[i];
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-14.c b/libgomp/testsuite/libgomp.c/scan-14.c
new file mode 100644
index 0000000..53bd11e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-14.c
@@ -0,0 +1,182 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+unsigned short r2, b2[1024];
+unsigned char r3, b3[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp for simd reduction (inscan, +:r, r2, r3) if (simd:0)
+ for (int i = 0; i < 1024; i++)
+ {
+ { r += a[i]; r2 += a[i]; r3 += a[i]; }
+ #pragma omp scan inclusive(r, r2, r3)
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ }
+}
+
+__attribute__((noipa)) int
+bar (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s, s2, s3) simdlen (1)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ s += 2 * a[i];
+ s2 += 2 * a[i];
+ s3 += 2 * a[i];
+ }
+ #pragma omp scan inclusive(s, s2, s3)
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ r += a[i];
+ r2 += a[i];
+ r3 += a[i];
+ }
+ #pragma omp scan inclusive(r, r2, r3)
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ }
+}
+
+__attribute__((noipa)) int
+qux (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
+ #pragma omp scan inclusive(s, s2, s3)
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ unsigned short s2;
+ unsigned char s3;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ }
+ if (bar (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ }
+ }
+ r = 0;
+ r2 = 0;
+ r3 = 0;
+ baz (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ }
+ s2 = 0;
+ s3 = 0;
+ if (qux (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-15.c b/libgomp/testsuite/libgomp.c/scan-15.c
new file mode 100644
index 0000000..4a02519
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-15.c
@@ -0,0 +1,118 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, +:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-16.c b/libgomp/testsuite/libgomp.c/scan-16.c
new file mode 100644
index 0000000..53705d0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-16.c
@@ -0,0 +1,120 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+
+#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0)
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd simdlen (1) reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd if (simd: 0) reduction (inscan, foo:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r += a[i];
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd reduction (inscan, foo:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s += 2 * a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-17.c b/libgomp/testsuite/libgomp.c/scan-17.c
new file mode 100644
index 0000000..22b2e62
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-17.c
@@ -0,0 +1,89 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+float r = 1.0f, a[1024], b[1024];
+
+__attribute__((noipa)) void
+foo (float *a, float *b)
+{
+ #pragma omp for simd reduction (inscan, *:r)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ r *= a[i];
+ }
+}
+
+__attribute__((noipa)) float
+bar (void)
+{
+ float s = -__builtin_inff ();
+ #pragma omp parallel for simd reduction (inscan, max:s)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = s;
+ #pragma omp scan exclusive(s)
+ s = s > a[i] ? s : a[i];
+ }
+ return s;
+}
+
+int
+main ()
+{
+ float s = 1.0f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (i < 80)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 200)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else if (i < 280)
+ a[i] = (i & 1) ? 0.25f : 0.5f;
+ else if (i < 380)
+ a[i] = (i % 3) == 0 ? 2.0f : (i % 3) == 1 ? 4.0f : 1.0f;
+ else
+ switch (i % 6)
+ {
+ case 0: a[i] = 0.25f; break;
+ case 1: a[i] = 2.0f; break;
+ case 2: a[i] = -1.0f; break;
+ case 3: a[i] = -4.0f; break;
+ case 4: a[i] = 0.5f; break;
+ case 5: a[i] = 1.0f; break;
+ default: a[i] = 0.0f; break;
+ }
+ b[i] = -19.0f;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r * 16384.0f != 0.125f)
+ abort ();
+ float m = -175.25f;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -231.75f;
+ s *= a[i];
+ a[i] = m - ((i % 3) == 1 ? 2.0f : (i % 3) == 2 ? 4.0f : 0.0f);
+ m += 0.75f;
+ }
+ if (bar () != 592.0f)
+ abort ();
+ s = -__builtin_inff ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ if (s < a[i])
+ s = a[i];
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-18.c b/libgomp/testsuite/libgomp.c/scan-18.c
new file mode 100644
index 0000000..ea13687
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-18.c
@@ -0,0 +1,182 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024];
+unsigned short r2, b2[1024];
+unsigned char r3, b3[1024];
+
+__attribute__((noipa)) void
+foo (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp for simd reduction (inscan, +:r, r2, r3)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ #pragma omp scan exclusive(r, r2, r3)
+ { r += a[i]; r2 += a[i]; r3 += a[i]; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ #pragma omp scan exclusive(s, s2, s3)
+ {
+ s += 2 * a[i];
+ s2 += 2 * a[i];
+ s3 += 2 * a[i];
+ }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b, unsigned short *b2, unsigned char *b3)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r, r2, r3) if (simd: 0)
+ for (int i = 0; i < 1024; i++)
+ {
+ {
+ b[i] = r;
+ b2[i] = r2;
+ b3[i] = r3;
+ }
+ #pragma omp scan exclusive(r, r2, r3)
+ {
+ r += a[i];
+ r2 += a[i];
+ r3 += a[i];
+ }
+ }
+}
+
+__attribute__((noipa)) int
+qux (unsigned short *s2p, unsigned char *s3p)
+{
+ int s = 0;
+ unsigned short s2 = 0;
+ unsigned char s3 = 0;
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:s, s2, s3)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; b2[i] = s2; b3[i] = s3; }
+ #pragma omp scan exclusive(s, s2, s3)
+ { s += 2 * a[i]; s2 += 2 * a[i]; s3 += 2 * a[i]; }
+ }
+ *s2p = s2;
+ *s3p = s3;
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ unsigned short s2;
+ unsigned char s3;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ s += i;
+ }
+ if (bar (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = -1;
+ b2[i] = -1;
+ b3[i] = -1;
+ }
+ s += 2 * i;
+ }
+ r = 0;
+ r2 = 0;
+ r3 = 0;
+ baz (a, b, b2, b3);
+ if (r != 1024 * 1023 / 2
+ || r2 != (unsigned short) r
+ || r3 != (unsigned char) r)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ else
+ {
+ b[i] = 25;
+ b2[i] = 24;
+ b3[i] = 26;
+ }
+ s += i;
+ }
+ s2 = 0;
+ s3 = 0;
+ if (qux (&s2, &s3) != 1024 * 1023)
+ abort ();
+ if (s2 != (unsigned short) (1024 * 1023)
+ || s3 != (unsigned char) (1024 * 1023))
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s
+ || b2[i] != (unsigned short) s
+ || b3[i] != (unsigned char) s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-19.c b/libgomp/testsuite/libgomp.c/scan-19.c
new file mode 100644
index 0000000..19d31d9
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-19.c
@@ -0,0 +1,119 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = a[i]; r += y + x + 12; }
+ #pragma omp scan inclusive(r)
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = 2 * a[i]; s += y; z = y; }
+ #pragma omp scan inclusive(s)
+ { y = s; b[i] = y + x + 12; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r) firstprivate (x) lastprivate (x) if (simd: 0)
+ for (int i = 0; i < 1024; i++)
+ {
+ { r += a[i]; if (i == 1023) x = 29; }
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd simdlen (1) reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ #pragma omp scan inclusive(s)
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-20.c b/libgomp/testsuite/libgomp.c/scan-20.c
new file mode 100644
index 0000000..1840164
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-20.c
@@ -0,0 +1,119 @@
+/* { dg-require-effective-target size32plus } */
+/* { dg-additional-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[2-6] loops" 2 "vect" { target sse2_runtime } } } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for simd reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y) simdlen(1)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ #pragma omp scan exclusive(r)
+ { y = a[i]; r += y + x + 12; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for simd reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z) if (0)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = s; b[i] = y + x + 12; }
+ #pragma omp scan exclusive(s)
+ { y = 2 * a[i]; s += y; z = y; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for simd reduction (inscan, +:r) firstprivate (x) lastprivate (x)
+ for (int i = 0; i < 1024; i++)
+ {
+ b[i] = r;
+ #pragma omp scan exclusive(r)
+ { r += a[i]; if (i == 1023) x = 29; }
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for simd reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ #pragma omp scan exclusive(s)
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ s += i;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ s += 2 * i;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ s += i;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (b[i] != s)
+ abort ();
+ s += 2 * i;
+ }
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/scan-9.c b/libgomp/testsuite/libgomp.c/scan-9.c
new file mode 100644
index 0000000..8227523
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/scan-9.c
@@ -0,0 +1,116 @@
+/* { dg-require-effective-target size32plus } */
+
+extern void abort (void);
+int r, a[1024], b[1024], x, y, z;
+
+__attribute__((noipa)) void
+foo (int *a, int *b)
+{
+ #pragma omp for reduction (inscan, +:r) lastprivate (conditional: z) firstprivate (x) private (y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = a[i]; r += y + x + 12; }
+ #pragma omp scan inclusive(r)
+ { b[i] = r; if ((i & 1) == 0 && i < 937) z = r; }
+ }
+}
+
+__attribute__((noipa)) int
+bar (void)
+{
+ int s = 0;
+ #pragma omp parallel
+ #pragma omp for reduction (inscan, +:s) firstprivate (x) private (y) lastprivate (z)
+ for (int i = 0; i < 1024; i++)
+ {
+ { y = 2 * a[i]; s += y; z = y; }
+ #pragma omp scan inclusive(s)
+ { y = s; b[i] = y + x + 12; }
+ }
+ return s;
+}
+
+__attribute__((noipa)) void
+baz (int *a, int *b)
+{
+ #pragma omp parallel for reduction (inscan, +:r) firstprivate (x) lastprivate (x)
+ for (int i = 0; i < 1024; i++)
+ {
+ { r += a[i] + x + 12; if (i == 1023) x = 29; }
+ #pragma omp scan inclusive(r)
+ b[i] = r;
+ }
+}
+
+__attribute__((noipa)) int
+qux (void)
+{
+ int s = 0;
+ #pragma omp parallel for reduction (inscan, +:s) lastprivate (conditional: x, y)
+ for (int i = 0; i < 1024; i++)
+ {
+ { s += 2 * a[i]; if ((a[i] & 1) == 1 && i < 825) x = a[i]; }
+ #pragma omp scan inclusive(s)
+ { b[i] = s; if ((a[i] & 1) == 0 && i < 829) y = a[i]; }
+ }
+ return s;
+}
+
+int
+main ()
+{
+ int s = 0;
+ x = -12;
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i;
+ b[i] = -1;
+ asm ("" : "+g" (i));
+ }
+ #pragma omp parallel
+ foo (a, b);
+ if (r != 1024 * 1023 / 2 || x != -12 || z != b[936])
+ abort ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = 25;
+ }
+ if (bar () != 1024 * 1023 || x != -12 || z != 2 * 1023)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -1;
+ }
+ r = 0;
+ baz (a, b);
+ if (r != 1024 * 1023 / 2 || x != 29)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += i;
+ if (b[i] != s)
+ abort ();
+ else
+ b[i] = -25;
+ }
+ if (qux () != 1024 * 1023 || x != 823 || y != 828)
+ abort ();
+ s = 0;
+ for (int i = 0; i < 1024; ++i)
+ {
+ s += 2 * i;
+ if (b[i] != s)
+ abort ();
+ }
+ return 0;
+}
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index c3daf2a..ddd9618 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,19 @@
+2019-07-12 Ren Kimura <rkx1209dev@gmail.com>
+
+ * simple-object-elf.c (simple_object_elf_match): Check zero value shstrndx.
+ This fixes a Bug 90924.
+
+2019-07-22 Martin Liska <mliska@suse.cz>
+
+ * simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
+ Do not search for gnu_lto_v1, but search for first '\0'.
+
+2019-07-18 Eduard-Mihai Burtescu <eddyb@lyken.rs>
+
+ * cplus-dem.c: Include rust-demangle.h.
+ * rust-demangle.c: Include rust-demangle.h.
+ * rust-demangle.h: New file.
+
2019-05-31 Michael Forney <mforney@mforney.org>
* cp-demangle.c: Don't define CP_DYNAMIC_ARRAYS if __STDC_NO_VLA__
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index afceed2..a39e2bf 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -52,6 +52,7 @@ void * realloc ();
#define CURRENT_DEMANGLING_STYLE options
#include "libiberty.h"
+#include "rust-demangle.h"
enum demangling_styles current_demangling_style = auto_demangling;
diff --git a/libiberty/rust-demangle.c b/libiberty/rust-demangle.c
index 9b2d2db..2302db4 100644
--- a/libiberty/rust-demangle.c
+++ b/libiberty/rust-demangle.c
@@ -47,6 +47,7 @@ extern void *memset(void *s, int c, size_t n);
#include <demangle.h>
#include "libiberty.h"
+#include "rust-demangle.h"
/* Mangled Rust symbols look like this:
diff --git a/libiberty/rust-demangle.h b/libiberty/rust-demangle.h
new file mode 100644
index 0000000..abf4c6c
--- /dev/null
+++ b/libiberty/rust-demangle.h
@@ -0,0 +1,45 @@
+/* Internal demangler interface for the Rust programming language.
+ Copyright (C) 2016-2019 Free Software Foundation, Inc.
+ Written by David Tolnay (dtolnay@gmail.com).
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU Library General Public
+License, the Free Software Foundation gives you unlimited permission
+to link the compiled version of this file into combinations with other
+programs, and to distribute those combinations without any restriction
+coming from the use of this file. (The Library Public License
+restrictions do apply in other respects; for example, they cover
+modification of the file, and distribution when not linked into a
+combined executable.)
+
+Libiberty 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.
+If not, see <http://www.gnu.org/licenses/>. */
+
+/* This file provides some definitions shared by cplus-dem.c and
+ rust-demangle.c. It should not be included by any other files. */
+
+/* Returns non-zero iff MANGLED is a rust mangled symbol. MANGLED must
+ already have been demangled through cplus_demangle_v3. If this function
+ returns non-zero then MANGLED can be demangled (in-place) using
+ RUST_DEMANGLE_SYM. */
+extern int
+rust_is_mangled (const char *mangled);
+
+/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
+ If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
+ replace characters that cannot be demangled with '?' and might truncate
+ SYM. After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
+ larger. */
+extern void
+rust_demangle_sym (char *sym);
diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c
index 22c9ae7..bdee963 100644
--- a/libiberty/simple-object-elf.c
+++ b/libiberty/simple-object-elf.c
@@ -548,7 +548,15 @@ simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
XDELETE (eor);
return NULL;
}
-
+
+ if (eor->shstrndx == 0)
+ {
+ *errmsg = "invalid ELF shstrndx == 0";
+ *err = 0;
+ XDELETE (eor);
+ return NULL;
+ }
+
return (void *) eor;
}
@@ -1358,9 +1366,8 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
return errmsg;
}
- /* If we are processing .symtab purge __gnu_lto_v1 and
- __gnu_lto_slim symbols from it and any symbols in discarded
- sections. */
+ /* If we are processing .symtab purge __gnu_lto_slim symbol
+ from it and any symbols in discarded sections. */
if (sh_type == SHT_SYMTAB)
{
unsigned entsize = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
@@ -1380,14 +1387,9 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
sobj->offset + stroff,
(unsigned char *)strings,
strsz, &errmsg, err);
- /* Find gnu_lto_ in strings. */
- while ((gnu_lto = (char *) memchr (gnu_lto, 'g',
- strings + strsz - gnu_lto)))
- if (strncmp (gnu_lto, "gnu_lto_v1",
- strings + strsz - gnu_lto) == 0)
- break;
- else
- gnu_lto++;
+ /* Find first '\0' in strings. */
+ gnu_lto = (char *) memchr (gnu_lto, '\0',
+ strings + strsz - gnu_lto + 1);
/* Read the section index table if present. */
if (symtab_indices_shndx[i - 1] != 0)
{
@@ -1461,10 +1463,9 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
undefined and sharing the gnu_lto_ name. */
bind = STB_WEAK;
other = STV_HIDDEN;
- if (gnu_lto)
- ELF_SET_FIELD (type_functions, ei_class, Sym,
- ent, st_name, Elf_Word,
- gnu_lto - strings);
+ ELF_SET_FIELD (type_functions, ei_class, Sym,
+ ent, st_name, Elf_Word,
+ gnu_lto - strings);
ELF_SET_FIELD (type_functions, ei_class, Sym,
ent, st_shndx, Elf_Half, SHN_UNDEF);
}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0ac7419..099314d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,106 @@
+2019-07-22 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/26_numerics/bit/bitops.count/*: Rename to ...
+ * testsuite/26_numerics/bit/bit.count/*: Here.
+
+ * include/std/bit (__rotl, __rotr): Change second parameter from
+ unsigned int to int and handle negative values.
+ (rotl, rotr): Remove check for __STRICT_ANSI__. Change second
+ parameter from unsigned int to int. Add nodiscard attribute.
+ * testsuite/26_numerics/bit/bitops.rot/rotl.cc: Rename to ...
+ * testsuite/26_numerics/bit/bit.rotate/rotl.cc: Here. Test negative
+ shifts.
+ * testsuite/26_numerics/bit/bitops.rot/rotr.cc: Rename to ...
+ * testsuite/26_numerics/bit/bit.rotate/rotr.cc: Here. Test negative
+ shifts.
+
+ * include/std/bit (__ceil2): Make unrepresentable results undefined,
+ as per P1355R2. Add debug assertion. Perform one left shift, not two,
+ so that out of range values cause undefined behaviour. Ensure that
+ shift will still be undefined if left operand is promoted.
+ * testsuite/26_numerics/bit/bit.pow.two/ceil2.cc: Replace checks for
+ unrepresentable values with checks that they are not core constant
+ expressions.
+ * testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc: New test.
+
+2019-07-19 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/bits/stl_tempbuf.h (__detail::__return_temporary_buffer): Fix
+ sized deallocation size computation.
+
+2019-07-19 Andreas Schwab <schwab@linux-m68k.org>
+
+ * config/abi/post/m68k-linux-gnu/baseline_symbols.txt: Update.
+
+2019-07-18 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/bits/stl_tempbuf.h (__detail::__return_temporary_buffer): New.
+ (~_Temporary_buffer()): Use latter.
+ (_Temporary_buffer(_FIterator, size_type)): Likewise.
+
+2019-07-17 Andreas Schwab <schwab@suse.de>
+
+ * config/abi/post/ia64-linux-gnu/baseline_symbols.txt: Update.
+
+2019-07-16 Jason Merrill <jason@redhat.com>
+
+ * include/std/memory (uses_allocator_construction_args): Add parens
+ around constraint.
+
+2019-07-12 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/29_atomics/atomic_float/1.cc: Fix comment.
+
+ * include/experimental/string_view (__detail::__idt): Remove.
+ (operator==, operator!=, operator<, operator>, operator<=, operator>=):
+ Use __type_identity_t instead of __detail::__idt;
+ * include/std/string_view (__detail::__idt): Remove.
+ (operator==, operator!=, operator<, operator>, operator<=, operator>=):
+ Use __type_identity_t instead of __detail::__idt;
+ * include/std/type_traits (__type_identity_t): New alias template.
+
+ * doc/xml/manual/status_cxx2020.xml: Update status for atomic_ref
+ and floating point atomics.
+
+2019-07-11 Jonathan Wakely <jwakely@redhat.com>
+
+ * doc/xml/manual/configure.xml: Improve documentation of
+ --enable-libstdcxx-time option.
+
+ * include/bits/atomic_base.h (__atomic_impl): New namespace for
+ wrappers around atomic built-ins.
+ (__atomic_float, __atomic_ref): New class templates for use as base
+ classes.
+ * include/std/atomic (atomic<float>, atomic<double>)
+ (atomic<long double>): New explicit specializations.
+ (atomic_ref): New class template.
+ (__cpp_lib_atomic_ref): Define.
+ * include/std/version (__cpp_lib_atomic_ref): Define.
+ * testsuite/29_atomics/atomic/60695.cc: Adjust dg-error.
+ * testsuite/29_atomics/atomic_float/1.cc: New test.
+ * testsuite/29_atomics/atomic_float/requirements.cc: New test.
+ * testsuite/29_atomics/atomic_ref/deduction.cc: New test.
+ * testsuite/29_atomics/atomic_ref/float.cc: New test.
+ * testsuite/29_atomics/atomic_ref/generic.cc: New test.
+ * testsuite/29_atomics/atomic_ref/integral.cc: New test.
+ * testsuite/29_atomics/atomic_ref/pointer.cc: New test.
+ * testsuite/29_atomics/atomic_ref/requirements.cc: New test.
+
+2019-07-06 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/ext/atomicity.h (__exchange_and_add, __atomic_add): Replace
+ throw() with _GLIBCXX_NOTHROW.
+ (__atomic_add_dispatch): Return after performing atomic increment.
+
+2019-07-05 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/ext/atomicity.h [_GLIBCXX_ATOMIC_BUILTINS] (__atomic_add)
+ (__exchange_and_add): Replace static specifier with always_inline
+ attribute.
+ (__exchange_and_add_single, __atomic_add_single): Likewise.
+ (__exchange_and_add_dispatch, __atomic_add_dispatch): Likewise. Also
+ combine !__gthread_active_p() and !__GTHREADS branches.
+
2019-07-03 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/91067
diff --git a/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt
index 0411f41..3361bae 100644
--- a/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt
+++ b/libstdc++-v3/config/abi/post/ia64-linux-gnu/baseline_symbols.txt
@@ -112,6 +112,7 @@ FUNC:_ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_@@GLIBCXX_3.4
+FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.26
FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.17
FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv@@GLIBCXX_3.4.17
FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv@@GLIBCXX_3.4.17
@@ -261,6 +262,7 @@ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEmm@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv@@GLIBCXX_3.4
+FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS0_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4
FUNC:_ZNKSi6gcountEv@@GLIBCXX_3.4
FUNC:_ZNKSi6sentrycvbEv@@GLIBCXX_3.4
@@ -328,9 +330,66 @@ FUNC:_ZNKSs8_M_limitEmm@@GLIBCXX_3.4
FUNC:_ZNKSs8capacityEv@@GLIBCXX_3.4
FUNC:_ZNKSs8max_sizeEv@@GLIBCXX_3.4
FUNC:_ZNKSs9_M_ibeginEv@@GLIBCXX_3.4
+FUNC:_ZNKSscvSt17basic_string_viewIcSt11char_traitsIcEEEv@@GLIBCXX_3.4.26
FUNC:_ZNKSsixEm@@GLIBCXX_3.4
FUNC:_ZNKSt10bad_typeid4whatEv@@GLIBCXX_3.4.9
FUNC:_ZNKSt10error_code23default_error_conditionEv@@GLIBCXX_3.4.11
+FUNC:_ZNKSt10filesystem16filesystem_error4whatEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem16filesystem_error5path1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem16filesystem_error5path2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem18directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path11parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path12has_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13has_root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13has_root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path14root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path15has_parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path16lexically_normalEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path17_M_find_extensionEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path17has_relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path18has_root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path18lexically_relativeERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path19lexically_proximateERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List13_Impl_deleterclEPNS1_5_ImplE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List3endEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List5beginEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path7compareERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path9root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path9root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error4whatEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1118directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path11parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path12has_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13has_root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13has_root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path14root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path15has_parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path16lexically_normalEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path17_M_find_extensionEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path17has_relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path18has_root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path18lexically_relativeERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path19lexically_proximateERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List3endEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List5beginEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path7compareERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path9root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path9root_pathEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt10istrstream5rdbufEv@@GLIBCXX_3.4
FUNC:_ZNKSt10lock_error4whatEv@@GLIBCXX_3.4.11
FUNC:_ZNKSt10moneypunctIcLb0EE10neg_formatEv@@GLIBCXX_3.4
@@ -734,6 +793,7 @@ FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEmPKc@@GLIBC
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_limitEmm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8capacityEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8max_sizeEv@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEcvSt17basic_string_viewIcS2_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_is_localEv@@GLIBCXX_3.4.21
@@ -794,6 +854,7 @@ FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_checkEmPKc@@GLIBC
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_limitEmm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS2_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21
@@ -925,6 +986,13 @@ FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewe@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE6do_outERS0_PKDiS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE9do_lengthERS0_PKDuS4_m@@GLIBCXX_3.4.26
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21
@@ -932,6 +1000,13 @@ FUNC:_ZNKSt7codecvtIDic11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE5do_inERS0_PKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE6do_outERS0_PKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE9do_lengthERS0_PKcS4_m@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE6do_outERS0_PKDsS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE9do_lengthERS0_PKDuS4_m@@GLIBCXX_3.4.26
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21
@@ -1134,6 +1209,7 @@ FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_mont
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES3_S3_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSC_@@GLIBCXX_3.4.21
+FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
@@ -1152,6 +1228,7 @@ FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_mont
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES3_S3_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSC_@@GLIBCXX_3.4.21
+FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
@@ -1244,6 +1321,8 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iterato
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPKwEEPwT_S7_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPwEES4_T_S5_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5_@@GLIBCXX_3.4
@@ -1251,6 +1330,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEmmmw@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEmmPKwm@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EmwRKS1_@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4
@@ -1267,6 +1347,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_m@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEmmRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4
@@ -1325,11 +1406,14 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@@GLIBCXX_3.4.5
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEmmm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_@@GLIBCXX_3.4.14
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwmRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mRKS1_@@GLIBCXX_3.4.23
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mmRKS1_@@GLIBCXX_3.4
@@ -1339,11 +1423,14 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPKwEET_S6_RKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPwEET_S5_RKS1_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_@@GLIBCXX_3.4.15
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwmRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mRKS1_@@GLIBCXX_3.4.23
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mmRKS1_@@GLIBCXX_3.4
@@ -1471,6 +1558,7 @@ FUNC:_ZNSoD0Ev@@GLIBCXX_3.4
FUNC:_ZNSoD1Ev@@GLIBCXX_3.4
FUNC:_ZNSoD2Ev@@GLIBCXX_3.4
FUNC:_ZNSoaSEOSo@@GLIBCXX_3.4.21
+FUNC:_ZNSolsEDn@@GLIBCXX_3.4.26
FUNC:_ZNSolsEPFRSoS_E@@GLIBCXX_3.4
FUNC:_ZNSolsEPFRSt8ios_baseS0_E@@GLIBCXX_3.4
FUNC:_ZNSolsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E@@GLIBCXX_3.4
@@ -1497,6 +1585,8 @@ FUNC:_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcES
FUNC:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSs12_S_empty_repEv@@GLIBCXX_3.4
+FUNC:_ZNSs12__sv_wrapperC1ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSs12__sv_wrapperC2ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_@@GLIBCXX_3.4
FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_@@GLIBCXX_3.4
FUNC:_ZNSs13_S_copy_charsEPcPKcS1_@@GLIBCXX_3.4
@@ -1504,6 +1594,7 @@ FUNC:_ZNSs13_S_copy_charsEPcS_S_@@GLIBCXX_3.4
FUNC:_ZNSs13shrink_to_fitEv@@GLIBCXX_3.4.14
FUNC:_ZNSs14_M_replace_auxEmmmc@@GLIBCXX_3.4
FUNC:_ZNSs15_M_replace_safeEmmPKcm@@GLIBCXX_3.4
+FUNC:_ZNSs17_S_to_string_viewESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
FUNC:_ZNSs18_S_construct_aux_2EmcRKSaIcE@@GLIBCXX_3.4.14
FUNC:_ZNSs2atEm@@GLIBCXX_3.4
FUNC:_ZNSs3endEv@@GLIBCXX_3.4
@@ -1520,6 +1611,7 @@ FUNC:_ZNSs4_Rep7_M_grabERKSaIcES2_@@GLIBCXX_3.4
FUNC:_ZNSs4_Rep8_M_cloneERKSaIcEm@@GLIBCXX_3.4
FUNC:_ZNSs4_Rep9_S_createEmmRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSs4backEv@@GLIBCXX_3.4.15
+FUNC:_ZNSs4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSs4rendEv@@GLIBCXX_3.4
FUNC:_ZNSs4swapERSs@@GLIBCXX_3.4
FUNC:_ZNSs5beginEv@@GLIBCXX_3.4
@@ -1578,11 +1670,14 @@ FUNC:_ZNSs9_M_assignEPcmc@@GLIBCXX_3.4.5
FUNC:_ZNSs9_M_assignEPcmc@GLIBCXX_3.4
FUNC:_ZNSs9_M_mutateEmmm@@GLIBCXX_3.4
FUNC:_ZNSs9push_backEc@@GLIBCXX_3.4
+FUNC:_ZNSsC1ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1EOSs@@GLIBCXX_3.4.14
+FUNC:_ZNSsC1EOSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1EPKcmRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSsC1ERKSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1ERKSsmRKSaIcE@@GLIBCXX_3.4.23
FUNC:_ZNSsC1ERKSsmm@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSsmmRKSaIcE@@GLIBCXX_3.4
@@ -1592,11 +1687,14 @@ FUNC:_ZNSsC1Ev@@GLIBCXX_3.4
FUNC:_ZNSsC1IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1IPcEET_S1_RKSaIcE@@GLIBCXX_3.4
+FUNC:_ZNSsC2ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2EOSs@@GLIBCXX_3.4.15
+FUNC:_ZNSsC2EOSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2EPKcRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2EPKcmRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSsC2ERKSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2ERKSsmRKSaIcE@@GLIBCXX_3.4.23
FUNC:_ZNSsC2ERKSsmm@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSsmmRKSaIcE@@GLIBCXX_3.4
@@ -1628,6 +1726,208 @@ FUNC:_ZNSt10__num_base15_S_format_floatERKSt8ios_basePcc@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10hash_valueERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEm@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEmRSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEm@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEmRSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathB5cxx11Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIlSt5ratioILl1ELl1000000000EEEEEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIlSt5ratioILl1ELl1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIlSt5ratioILl1ELl1000000000EEEEEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIlSt5ratioILl1ELl1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator3popEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSEOS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSERKS0_@@GLIBCXX_3.4.27
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path14_M_split_cmptsEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path14_S_convert_locEPKcS2_RKSt6locale@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path15remove_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path16replace_filenameERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path17replace_extensionERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path5_ListC1ERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path5_ListC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathaSERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathdVERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathpLERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1110hash_valueERKNS0_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSERKS1_@@GLIBCXX_3.4.27
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path14_M_split_cmptsEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path14_S_convert_locEPKcS3_RKSt6locale@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path15remove_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path16replace_filenameERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path17replace_extensionERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path5_ListC1ERKS2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path5_ListC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathaSERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathdVERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathpLERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
FUNC:_ZNSt10istrstream3strEv@@GLIBCXX_3.4
FUNC:_ZNSt10istrstreamC1EPKc@@GLIBCXX_3.4
FUNC:_ZNSt10istrstreamC1EPKcl@@GLIBCXX_3.4
@@ -1714,10 +2014,12 @@ FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@@GLIBCXX_3.4.5
FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@GLIBCXX_3.4
FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@@GLIBCXX_3.4.5
FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@GLIBCXX_3.4
+FUNC:_ZNSt11logic_errorC1EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSt11logic_errorC2EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_errorC2EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC2ERKS_@@GLIBCXX_3.4.21
@@ -1725,6 +2027,7 @@ FUNC:_ZNSt11logic_errorC2ERKSs@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt11logic_erroraSEOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_erroraSERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt11range_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
@@ -1757,6 +2060,20 @@ FUNC:_ZNSt12__basic_fileIcEC1EP15pthread_mutex_t@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcEC2EP15pthread_mutex_t@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcED2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS4_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS4_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS6_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_@@GLIBCXX_3.4.26
FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15
FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15
FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15
@@ -2057,6 +2374,7 @@ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21
+FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn@@GLIBCXX_3.4.26
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRS2_S3_E@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt8ios_baseS4_E@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt9basic_iosIwS1_ES5_E@@GLIBCXX_3.4
@@ -2081,10 +2399,12 @@ FUNC:_ZNSt13random_device7_M_finiEv@@GLIBCXX_3.4.18
FUNC:_ZNSt13random_device7_M_initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13random_device7_M_initERKSs@@GLIBCXX_3.4.18
FUNC:_ZNSt13random_device9_M_getvalEv@@GLIBCXX_3.4.18
+FUNC:_ZNSt13runtime_errorC1EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSt13runtime_errorC2EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_errorC2EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC2ERKS_@@GLIBCXX_3.4.21
@@ -2092,6 +2412,7 @@ FUNC:_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt13runtime_erroraSEOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_erroraSERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21
@@ -2203,12 +2524,16 @@ FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcEC1EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIcEC1ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIcEC2EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIcEC2ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIcED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwEC1EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIwEC1ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIwEC2EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIwEC2ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIwED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwED2Ev@@GLIBCXX_3.4
@@ -2348,9 +2673,11 @@ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21
@@ -2370,9 +2697,11 @@ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21
@@ -2540,9 +2869,11 @@ FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2552,9 +2883,11 @@ FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2566,6 +2899,7 @@ FUNC:_ZNSt18condition_variableC1Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableC2Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableD1Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableD2Ev@@GLIBCXX_3.4.11
+FUNC:_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info@@GLIBCXX_3.4.26
FUNC:_ZNSt19__codecvt_utf8_baseIDiED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt19__codecvt_utf8_baseIDiED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt19__codecvt_utf8_baseIDiED2Ev@@GLIBCXX_3.4.21
@@ -2580,9 +2914,11 @@ FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2592,9 +2928,11 @@ FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2604,9 +2942,11 @@ FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2616,9 +2956,11 @@ FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2659,6 +3001,26 @@ FUNC:_ZNSt3_V214error_categoryD1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V214error_categoryD2Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V215system_categoryEv@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V216generic_categoryEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt3pmr19new_delete_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20get_default_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20null_memory_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20set_default_resourceEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resource13_M_new_bufferEmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource11do_allocateEmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource13do_deallocateEPvmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt5ctypeIcE13classic_tableEv@@GLIBCXX_3.4
FUNC:_ZNSt5ctypeIcEC1EP15__locale_structPKtbm@@GLIBCXX_3.4
FUNC:_ZNSt5ctypeIcEC1EPKtbm@@GLIBCXX_3.4
@@ -2792,6 +3154,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC1ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC2ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_set_lengthEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcS4_EESA_@@GLIBCXX_3.4.21
@@ -2801,10 +3165,12 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcS5_S
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13shrink_to_fitEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEmmmc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17_S_to_string_viewESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE18_M_construct_aux_2Emc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv@@GLIBCXX_3.4.21
@@ -2828,6 +3194,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_@@GLIBCXX
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_mm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignESt16initializer_listIcE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEmc@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEmc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.21
@@ -2877,6 +3244,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_lengthEm@@GLIBCXX_
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcmc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9push_backEc@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@@GLIBCXX_3.4.21
@@ -2893,6 +3261,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPKcvEET_S8_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPcvEET_S7_RKS3_@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS3_@@GLIBCXX_3.4.21
@@ -2935,6 +3304,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPwEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_set_lengthEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS4_EESA_@@GLIBCXX_3.4.21
@@ -2944,10 +3315,12 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS5_S
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE14_M_replace_auxEmmmw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE18_M_construct_aux_2Emw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4.21
@@ -2971,6 +3344,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_@@GLIBCXX
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_mm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEmw@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEmw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.21
@@ -3020,6 +3394,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_lengthEm@@GLIBCXX_
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_mutateEmmPKwm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_S_assignEPwmw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwRKS3_@@GLIBCXX_3.4.21
@@ -3036,6 +3411,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPKwvEET_S8_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPwvEET_S7_RKS3_@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwRKS3_@@GLIBCXX_3.4.21
@@ -3099,10 +3475,12 @@ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3128,10 +3506,12 @@ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3211,9 +3591,11 @@ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIB
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3223,9 +3605,11 @@ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIB
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3235,9 +3619,11 @@ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3247,9 +3633,11 @@ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3259,9 +3647,11 @@ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3271,9 +3661,11 @@ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3356,9 +3748,15 @@ FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7codecvtIDic11__mbstate_tED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDic11__mbstate_tED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDic11__mbstate_tED2Ev@@GLIBCXX_3.4.21
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED2Ev@@GLIBCXX_3.4.21
@@ -3640,6 +4038,7 @@ FUNC:_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4
FUNC:_ZSt18__throw_bad_typeidv@@GLIBCXX_3.4
FUNC:_ZSt18uncaught_exceptionv@@GLIBCXX_3.4
FUNC:_ZSt19__throw_ios_failurePKc@@GLIBCXX_3.4
+FUNC:_ZSt19__throw_ios_failurePKci@@GLIBCXX_3.4.26
FUNC:_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4
FUNC:_ZSt19__throw_range_errorPKc@@GLIBCXX_3.4
FUNC:_ZSt19__throw_regex_errorNSt15regex_constants10error_typeE@@GLIBCXX_3.4.15
@@ -3978,6 +4377,7 @@ OBJECT:0:CXXABI_1.3
OBJECT:0:CXXABI_1.3.1
OBJECT:0:CXXABI_1.3.10
OBJECT:0:CXXABI_1.3.11
+OBJECT:0:CXXABI_1.3.12
OBJECT:0:CXXABI_1.3.2
OBJECT:0:CXXABI_1.3.3
OBJECT:0:CXXABI_1.3.4
@@ -4007,6 +4407,8 @@ OBJECT:0:GLIBCXX_3.4.22
OBJECT:0:GLIBCXX_3.4.23
OBJECT:0:GLIBCXX_3.4.24
OBJECT:0:GLIBCXX_3.4.25
+OBJECT:0:GLIBCXX_3.4.26
+OBJECT:0:GLIBCXX_3.4.27
OBJECT:0:GLIBCXX_3.4.3
OBJECT:0:GLIBCXX_3.4.4
OBJECT:0:GLIBCXX_3.4.5
@@ -4097,7 +4499,9 @@ OBJECT:160:_ZTVSt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:160:_ZTVSt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21
OBJECT:160:_ZTVSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:160:_ZTVSt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21
+OBJECT:160:_ZTVSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:160:_ZTVSt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21
+OBJECT:160:_ZTVSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:160:_ZTVSt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21
OBJECT:160:_ZTVSt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:160:_ZTVSt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4
@@ -4116,6 +4520,7 @@ OBJECT:16:_ZTIDf@@CXXABI_1.3.4
OBJECT:16:_ZTIDi@@CXXABI_1.3.3
OBJECT:16:_ZTIDn@@CXXABI_1.3.5
OBJECT:16:_ZTIDs@@CXXABI_1.3.3
+OBJECT:16:_ZTIDu@@CXXABI_1.3.12
OBJECT:16:_ZTIN10__cxxabiv115__forced_unwindE@@CXXABI_1.3.2
OBJECT:16:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2
OBJECT:16:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
@@ -4257,6 +4662,19 @@ OBJECT:1:_ZNSt14numeric_limitsIDsE8is_exactE@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_iec559E@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_moduloE@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_signedE@@GLIBCXX_3.4.11
+OBJECT:1:_ZNSt14numeric_limitsIDuE10is_boundedE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE10is_integerE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE12has_infinityE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE13has_quiet_NaNE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE14is_specializedE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE15has_denorm_lossE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE15tinyness_beforeE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE17has_signaling_NaNE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE5trapsE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE8is_exactE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_iec559E@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_moduloE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_signedE@@GLIBCXX_3.4.26
OBJECT:1:_ZNSt14numeric_limitsIaE10is_boundedE@@GLIBCXX_3.4
OBJECT:1:_ZNSt14numeric_limitsIaE10is_integerE@@GLIBCXX_3.4
OBJECT:1:_ZNSt14numeric_limitsIaE12has_infinityE@@GLIBCXX_3.4
@@ -4572,7 +4990,11 @@ OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4
OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4
OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4
OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4
+OBJECT:24:_ZTINSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26
+OBJECT:24:_ZTINSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26
OBJECT:24:_ZTINSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17
+OBJECT:24:_ZTINSt3pmr26synchronized_pool_resourceE@@GLIBCXX_3.4.26
+OBJECT:24:_ZTINSt3pmr28unsynchronized_pool_resourceE@@GLIBCXX_3.4.26
OBJECT:24:_ZTINSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21
OBJECT:24:_ZTINSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21
OBJECT:24:_ZTINSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
@@ -4671,7 +5093,9 @@ OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt5ctypeIwE@@GLIBCXX_3.4
+OBJECT:24:_ZTISt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:24:_ZTISt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21
+OBJECT:24:_ZTISt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:24:_ZTISt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:24:_ZTISt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4
@@ -4758,6 +5182,8 @@ OBJECT:2:_ZTSv@@CXXABI_1.3
OBJECT:2:_ZTSw@@CXXABI_1.3
OBJECT:2:_ZTSx@@CXXABI_1.3
OBJECT:2:_ZTSy@@CXXABI_1.3
+OBJECT:30:_ZTSSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
+OBJECT:30:_ZTSSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:32:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4
OBJECT:32:_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4
OBJECT:32:_ZTIPDd@@CXXABI_1.3.4
@@ -4766,12 +5192,14 @@ OBJECT:32:_ZTIPDf@@CXXABI_1.3.4
OBJECT:32:_ZTIPDi@@CXXABI_1.3.3
OBJECT:32:_ZTIPDn@@CXXABI_1.3.5
OBJECT:32:_ZTIPDs@@CXXABI_1.3.3
+OBJECT:32:_ZTIPDu@@CXXABI_1.3.12
OBJECT:32:_ZTIPKDd@@CXXABI_1.3.4
OBJECT:32:_ZTIPKDe@@CXXABI_1.3.4
OBJECT:32:_ZTIPKDf@@CXXABI_1.3.4
OBJECT:32:_ZTIPKDi@@CXXABI_1.3.3
OBJECT:32:_ZTIPKDn@@CXXABI_1.3.5
OBJECT:32:_ZTIPKDs@@CXXABI_1.3.3
+OBJECT:32:_ZTIPKDu@@CXXABI_1.3.12
OBJECT:32:_ZTIPKa@@CXXABI_1.3
OBJECT:32:_ZTIPKb@@CXXABI_1.3
OBJECT:32:_ZTIPKc@@CXXABI_1.3
@@ -4935,6 +5363,15 @@ OBJECT:4:_ZNSt14numeric_limitsIDsE14min_exponent10E@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE5radixE@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE6digitsE@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE8digits10E@@GLIBCXX_3.4.11
+OBJECT:4:_ZNSt14numeric_limitsIDuE10has_denormE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE11round_styleE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE12max_exponentE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE12min_exponentE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE14max_exponent10E@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE14min_exponent10E@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE5radixE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE6digitsE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE8digits10E@@GLIBCXX_3.4.26
OBJECT:4:_ZNSt14numeric_limitsIaE10has_denormE@@GLIBCXX_3.4
OBJECT:4:_ZNSt14numeric_limitsIaE11round_styleE@@GLIBCXX_3.4
OBJECT:4:_ZNSt14numeric_limitsIaE12max_digits10E@@GLIBCXX_3.4.14
@@ -5235,6 +5672,8 @@ OBJECT:60:_ZTSSt9money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBC
OBJECT:60:_ZTSSt9money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4
OBJECT:60:_ZTSSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE@@GLIBCXX_3.4
OBJECT:60:_ZTSSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE@@GLIBCXX_3.4
+OBJECT:64:_ZTVNSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26
+OBJECT:64:_ZTVNSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26
OBJECT:64:_ZTVNSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
OBJECT:64:_ZTVNSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15
OBJECT:64:_ZTVNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17
@@ -5368,7 +5807,9 @@ OBJECT:8:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2
OBJECT:8:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21
OBJECT:8:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21
OBJECT:8:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21
+OBJECT:8:_ZNSt7codecvtIDiDu11__mbstate_tE2idE@@GLIBCXX_3.4.26
OBJECT:8:_ZNSt7codecvtIDic11__mbstate_tE2idE@@GLIBCXX_3.4.21
+OBJECT:8:_ZNSt7codecvtIDsDu11__mbstate_tE2idE@@GLIBCXX_3.4.26
OBJECT:8:_ZNSt7codecvtIDsc11__mbstate_tE2idE@@GLIBCXX_3.4.21
OBJECT:8:_ZNSt7codecvtIcc11__mbstate_tE2idE@@GLIBCXX_3.4
OBJECT:8:_ZNSt7codecvtIwc11__mbstate_tE2idE@@GLIBCXX_3.4
diff --git a/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt
index 2af971a..1b4fbff 100644
--- a/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt
+++ b/libstdc++-v3/config/abi/post/m68k-linux-gnu/baseline_symbols.txt
@@ -112,6 +112,7 @@ FUNC:_ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_@@GLIBCXX_3.4
+FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.26
FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.17
FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv@@GLIBCXX_3.4.17
FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv@@GLIBCXX_3.4.17
@@ -261,6 +262,7 @@ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEjj@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv@@GLIBCXX_3.4
+FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS0_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEixEj@@GLIBCXX_3.4
FUNC:_ZNKSi6gcountEv@@GLIBCXX_3.4
FUNC:_ZNKSi6sentrycvbEv@@GLIBCXX_3.4
@@ -328,9 +330,66 @@ FUNC:_ZNKSs8_M_limitEjj@@GLIBCXX_3.4
FUNC:_ZNKSs8capacityEv@@GLIBCXX_3.4
FUNC:_ZNKSs8max_sizeEv@@GLIBCXX_3.4
FUNC:_ZNKSs9_M_ibeginEv@@GLIBCXX_3.4
+FUNC:_ZNKSscvSt17basic_string_viewIcSt11char_traitsIcEEEv@@GLIBCXX_3.4.26
FUNC:_ZNKSsixEj@@GLIBCXX_3.4
FUNC:_ZNKSt10bad_typeid4whatEv@@GLIBCXX_3.4.9
FUNC:_ZNKSt10error_code23default_error_conditionEv@@GLIBCXX_3.4.11
+FUNC:_ZNKSt10filesystem16filesystem_error4whatEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem16filesystem_error5path1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem16filesystem_error5path2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem18directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path11parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path12has_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13has_root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13has_root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path14root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path15has_parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path16lexically_normalEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path17_M_find_extensionEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path17has_relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path18has_root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path18lexically_relativeERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path19lexically_proximateERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List13_Impl_deleterclEPNS1_5_ImplE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List3endEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List5beginEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path7compareERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path9root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path9root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error4whatEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1118directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path11parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path12has_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13has_root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13has_root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path14root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path15has_parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path16lexically_normalEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path17_M_find_extensionEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path17has_relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path18has_root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path18lexically_relativeERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path19lexically_proximateERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List3endEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List5beginEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path7compareERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path9root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path9root_pathEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt10istrstream5rdbufEv@@GLIBCXX_3.4
FUNC:_ZNKSt10lock_error4whatEv@@GLIBCXX_3.4.11
FUNC:_ZNKSt10moneypunctIcLb0EE10neg_formatEv@@GLIBCXX_3.4
@@ -734,6 +793,7 @@ FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEjPKc@@GLIBC
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_limitEjj@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8capacityEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8max_sizeEv@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEcvSt17basic_string_viewIcS2_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEj@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_is_localEv@@GLIBCXX_3.4.21
@@ -794,6 +854,7 @@ FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_checkEjPKc@@GLIBC
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_limitEjj@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS2_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEj@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21
@@ -925,6 +986,13 @@ FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewe@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE6do_outERS0_PKDiS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE9do_lengthERS0_PKDuS4_j@@GLIBCXX_3.4.26
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21
@@ -932,6 +1000,13 @@ FUNC:_ZNKSt7codecvtIDic11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE5do_inERS0_PKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE6do_outERS0_PKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE9do_lengthERS0_PKcS4_j@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE6do_outERS0_PKDsS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE9do_lengthERS0_PKDuS4_j@@GLIBCXX_3.4.26
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21
@@ -1134,6 +1209,7 @@ FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_mont
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES3_S3_RiPPKcjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSC_@@GLIBCXX_3.4.21
+FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
@@ -1152,6 +1228,7 @@ FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_mont
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES3_S3_RiPPKwjRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSC_@@GLIBCXX_3.4.21
+FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
@@ -1244,6 +1321,8 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iterato
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPKwEEPwT_S7_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPwEES4_T_S5_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5_@@GLIBCXX_3.4
@@ -1251,6 +1330,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEjjPKwj@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EjwRKS1_@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE2atEj@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4
@@ -1267,6 +1347,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_j@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEjjRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4
@@ -1325,11 +1406,14 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjw@@GLIBCXX_3.4.5
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwjw@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEjjj@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_@@GLIBCXX_3.4.14
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwjRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jRKS1_@@GLIBCXX_3.4.24
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jj@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_jjRKS1_@@GLIBCXX_3.4
@@ -1339,11 +1423,14 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPKwEET_S6_RKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPwEET_S5_RKS1_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_@@GLIBCXX_3.4.15
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwjRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jRKS1_@@GLIBCXX_3.4.24
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jj@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_jjRKS1_@@GLIBCXX_3.4
@@ -1471,6 +1558,7 @@ FUNC:_ZNSoD0Ev@@GLIBCXX_3.4
FUNC:_ZNSoD1Ev@@GLIBCXX_3.4
FUNC:_ZNSoD2Ev@@GLIBCXX_3.4
FUNC:_ZNSoaSEOSo@@GLIBCXX_3.4.21
+FUNC:_ZNSolsEDn@@GLIBCXX_3.4.26
FUNC:_ZNSolsEPFRSoS_E@@GLIBCXX_3.4
FUNC:_ZNSolsEPFRSt8ios_baseS0_E@@GLIBCXX_3.4
FUNC:_ZNSolsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E@@GLIBCXX_3.4
@@ -1497,6 +1585,8 @@ FUNC:_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcES
FUNC:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSs12_S_empty_repEv@@GLIBCXX_3.4
+FUNC:_ZNSs12__sv_wrapperC1ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSs12__sv_wrapperC2ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_@@GLIBCXX_3.4
FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_@@GLIBCXX_3.4
FUNC:_ZNSs13_S_copy_charsEPcPKcS1_@@GLIBCXX_3.4
@@ -1504,6 +1594,7 @@ FUNC:_ZNSs13_S_copy_charsEPcS_S_@@GLIBCXX_3.4
FUNC:_ZNSs13shrink_to_fitEv@@GLIBCXX_3.4.14
FUNC:_ZNSs14_M_replace_auxEjjjc@@GLIBCXX_3.4
FUNC:_ZNSs15_M_replace_safeEjjPKcj@@GLIBCXX_3.4
+FUNC:_ZNSs17_S_to_string_viewESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
FUNC:_ZNSs18_S_construct_aux_2EjcRKSaIcE@@GLIBCXX_3.4.14
FUNC:_ZNSs2atEj@@GLIBCXX_3.4
FUNC:_ZNSs3endEv@@GLIBCXX_3.4
@@ -1520,6 +1611,7 @@ FUNC:_ZNSs4_Rep7_M_grabERKSaIcES2_@@GLIBCXX_3.4
FUNC:_ZNSs4_Rep8_M_cloneERKSaIcEj@@GLIBCXX_3.4
FUNC:_ZNSs4_Rep9_S_createEjjRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSs4backEv@@GLIBCXX_3.4.15
+FUNC:_ZNSs4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSs4rendEv@@GLIBCXX_3.4
FUNC:_ZNSs4swapERSs@@GLIBCXX_3.4
FUNC:_ZNSs5beginEv@@GLIBCXX_3.4
@@ -1578,11 +1670,14 @@ FUNC:_ZNSs9_M_assignEPcjc@@GLIBCXX_3.4.5
FUNC:_ZNSs9_M_assignEPcjc@GLIBCXX_3.4
FUNC:_ZNSs9_M_mutateEjjj@@GLIBCXX_3.4
FUNC:_ZNSs9push_backEc@@GLIBCXX_3.4
+FUNC:_ZNSsC1ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1EOSs@@GLIBCXX_3.4.14
+FUNC:_ZNSsC1EOSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1EPKcjRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSsC1ERKSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1ERKSsjRKSaIcE@@GLIBCXX_3.4.23
FUNC:_ZNSsC1ERKSsjj@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSsjjRKSaIcE@@GLIBCXX_3.4
@@ -1592,11 +1687,14 @@ FUNC:_ZNSsC1Ev@@GLIBCXX_3.4
FUNC:_ZNSsC1IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1IPcEET_S1_RKSaIcE@@GLIBCXX_3.4
+FUNC:_ZNSsC2ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2EOSs@@GLIBCXX_3.4.15
+FUNC:_ZNSsC2EOSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2EPKcRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2EPKcjRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSsC2ERKSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2ERKSsjRKSaIcE@@GLIBCXX_3.4.23
FUNC:_ZNSsC2ERKSsjj@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSsjjRKSaIcE@@GLIBCXX_3.4
@@ -1628,6 +1726,208 @@ FUNC:_ZNSt10__num_base15_S_format_floatERKSt8ios_basePcc@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10hash_valueERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEy@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEyRSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEy@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEyRSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathB5cxx11Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIxSt5ratioILx1ELx1000000000EEEEEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIxSt5ratioILx1ELx1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIxSt5ratioILx1ELx1000000000EEEEEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIxSt5ratioILx1ELx1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator3popEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSEOS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSERKS0_@@GLIBCXX_3.4.27
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path14_M_split_cmptsEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path14_S_convert_locEPKcS2_RKSt6locale@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path15remove_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path16replace_filenameERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path17replace_extensionERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path5_ListC1ERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path5_ListC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathaSERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathdVERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathpLERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1110hash_valueERKNS0_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSERKS1_@@GLIBCXX_3.4.27
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path14_M_split_cmptsEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path14_S_convert_locEPKcS3_RKSt6locale@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path15remove_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path16replace_filenameERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path17replace_extensionERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path5_ListC1ERKS2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path5_ListC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathaSERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathdVERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathpLERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
FUNC:_ZNSt10istrstream3strEv@@GLIBCXX_3.4
FUNC:_ZNSt10istrstreamC1EPKc@@GLIBCXX_3.4
FUNC:_ZNSt10istrstreamC1EPKci@@GLIBCXX_3.4
@@ -1714,10 +2014,12 @@ FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@@GLIBCXX_3.4.5
FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@GLIBCXX_3.4
FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@@GLIBCXX_3.4.5
FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@GLIBCXX_3.4
+FUNC:_ZNSt11logic_errorC1EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSt11logic_errorC2EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_errorC2EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC2ERKS_@@GLIBCXX_3.4.21
@@ -1725,6 +2027,7 @@ FUNC:_ZNSt11logic_errorC2ERKSs@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt11logic_erroraSEOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_erroraSERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt11range_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
@@ -1757,6 +2060,20 @@ FUNC:_ZNSt12__basic_fileIcEC1EP15pthread_mutex_t@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcEC2EP15pthread_mutex_t@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcED2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS4_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS4_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS6_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_@@GLIBCXX_3.4.26
FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15
FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15
FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15
@@ -2057,6 +2374,7 @@ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21
+FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn@@GLIBCXX_3.4.26
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRS2_S3_E@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt8ios_baseS4_E@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt9basic_iosIwS1_ES5_E@@GLIBCXX_3.4
@@ -2081,10 +2399,12 @@ FUNC:_ZNSt13random_device7_M_finiEv@@GLIBCXX_3.4.18
FUNC:_ZNSt13random_device7_M_initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13random_device7_M_initERKSs@@GLIBCXX_3.4.18
FUNC:_ZNSt13random_device9_M_getvalEv@@GLIBCXX_3.4.18
+FUNC:_ZNSt13runtime_errorC1EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSt13runtime_errorC2EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_errorC2EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC2ERKS_@@GLIBCXX_3.4.21
@@ -2092,6 +2412,7 @@ FUNC:_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt13runtime_erroraSEOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_erroraSERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21
@@ -2203,12 +2524,16 @@ FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcEC1EPKcj@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIcEC1ERKSsj@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIcEC2EPKcj@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIcEC2ERKSsj@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIcED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwEC1EPKcj@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIwEC1ERKSsj@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIwEC2EPKcj@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIwEC2ERKSsj@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIwED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwED2Ev@@GLIBCXX_3.4
@@ -2348,9 +2673,11 @@ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21
@@ -2370,9 +2697,11 @@ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21
@@ -2540,9 +2869,11 @@ FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2552,9 +2883,11 @@ FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2566,6 +2899,7 @@ FUNC:_ZNSt18condition_variableC1Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableC2Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableD1Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableD2Ev@@GLIBCXX_3.4.11
+FUNC:_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info@@GLIBCXX_3.4.26
FUNC:_ZNSt19__codecvt_utf8_baseIDiED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt19__codecvt_utf8_baseIDiED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt19__codecvt_utf8_baseIDiED2Ev@@GLIBCXX_3.4.21
@@ -2580,9 +2914,11 @@ FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2592,9 +2928,11 @@ FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2604,9 +2942,11 @@ FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2616,9 +2956,11 @@ FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2659,6 +3001,26 @@ FUNC:_ZNSt3_V214error_categoryD1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V214error_categoryD2Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V215system_categoryEv@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V216generic_categoryEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt3pmr19new_delete_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20get_default_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20null_memory_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20set_default_resourceEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resource13_M_new_bufferEjj@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEjj@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvjj@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource11do_allocateEjj@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource13do_deallocateEPvjj@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt5ctypeIcE13classic_tableEv@@GLIBCXX_3.4
FUNC:_ZNSt5ctypeIcEC1EP15__locale_structPKtbj@@GLIBCXX_3.4
FUNC:_ZNSt5ctypeIcEC1EPKtbj@@GLIBCXX_3.4
@@ -2792,6 +3154,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC1ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC2ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_set_lengthEj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcS4_EESA_@@GLIBCXX_3.4.21
@@ -2801,10 +3165,12 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcS5_S
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13shrink_to_fitEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEjjjc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17_S_to_string_viewESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE18_M_construct_aux_2Ejc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv@@GLIBCXX_3.4.21
@@ -2828,6 +3194,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_@@GLIBCXX
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_jj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignESt16initializer_listIcE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEjc@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEjc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.21
@@ -2877,6 +3244,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_lengthEj@@GLIBCXX_
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEjjPKcj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcjc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9push_backEc@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@@GLIBCXX_3.4.21
@@ -2893,6 +3261,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPKcvEET_S8_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPcvEET_S7_RKS3_@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS3_@@GLIBCXX_3.4.21
@@ -2935,6 +3304,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPwEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_set_lengthEj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS4_EESA_@@GLIBCXX_3.4.21
@@ -2944,10 +3315,12 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS5_S
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE14_M_replace_auxEjjjw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE18_M_construct_aux_2Ejw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4.21
@@ -2971,6 +3344,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_@@GLIBCXX
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_jj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEjw@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEjw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.21
@@ -3020,6 +3394,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_lengthEj@@GLIBCXX_
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_mutateEjjPKwj@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_S_assignEPwjw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwRKS3_@@GLIBCXX_3.4.21
@@ -3036,6 +3411,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPKwvEET_S8_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPwvEET_S7_RKS3_@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwRKS3_@@GLIBCXX_3.4.21
@@ -3099,10 +3475,12 @@ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3128,10 +3506,12 @@ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3211,9 +3591,11 @@ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIB
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3223,9 +3605,11 @@ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIB
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3235,9 +3619,11 @@ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3247,9 +3633,11 @@ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3259,9 +3647,11 @@ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3271,9 +3661,11 @@ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3356,9 +3748,15 @@ FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Ej@
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7codecvtIDic11__mbstate_tED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDic11__mbstate_tED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDic11__mbstate_tED2Ev@@GLIBCXX_3.4.21
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED2Ev@@GLIBCXX_3.4.21
@@ -3640,6 +4038,7 @@ FUNC:_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4
FUNC:_ZSt18__throw_bad_typeidv@@GLIBCXX_3.4
FUNC:_ZSt18uncaught_exceptionv@@GLIBCXX_3.4
FUNC:_ZSt19__throw_ios_failurePKc@@GLIBCXX_3.4
+FUNC:_ZSt19__throw_ios_failurePKci@@GLIBCXX_3.4.26
FUNC:_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4
FUNC:_ZSt19__throw_range_errorPKc@@GLIBCXX_3.4
FUNC:_ZSt19__throw_regex_errorNSt15regex_constants10error_typeE@@GLIBCXX_3.4.15
@@ -3978,6 +4377,7 @@ OBJECT:0:CXXABI_1.3
OBJECT:0:CXXABI_1.3.1
OBJECT:0:CXXABI_1.3.10
OBJECT:0:CXXABI_1.3.11
+OBJECT:0:CXXABI_1.3.12
OBJECT:0:CXXABI_1.3.2
OBJECT:0:CXXABI_1.3.3
OBJECT:0:CXXABI_1.3.4
@@ -4006,6 +4406,8 @@ OBJECT:0:GLIBCXX_3.4.22
OBJECT:0:GLIBCXX_3.4.23
OBJECT:0:GLIBCXX_3.4.24
OBJECT:0:GLIBCXX_3.4.25
+OBJECT:0:GLIBCXX_3.4.26
+OBJECT:0:GLIBCXX_3.4.27
OBJECT:0:GLIBCXX_3.4.3
OBJECT:0:GLIBCXX_3.4.4
OBJECT:0:GLIBCXX_3.4.5
@@ -4029,7 +4431,11 @@ OBJECT:12:_ZTIN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4
OBJECT:12:_ZTIN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4
OBJECT:12:_ZTIN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4
OBJECT:12:_ZTIN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4
+OBJECT:12:_ZTINSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26
+OBJECT:12:_ZTINSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26
OBJECT:12:_ZTINSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17
+OBJECT:12:_ZTINSt3pmr26synchronized_pool_resourceE@@GLIBCXX_3.4.26
+OBJECT:12:_ZTINSt3pmr28unsynchronized_pool_resourceE@@GLIBCXX_3.4.26
OBJECT:12:_ZTINSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21
OBJECT:12:_ZTINSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21
OBJECT:12:_ZTINSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
@@ -4128,7 +4534,9 @@ OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21
OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:12:_ZTISt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21
OBJECT:12:_ZTISt5ctypeIwE@@GLIBCXX_3.4
+OBJECT:12:_ZTISt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:12:_ZTISt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21
+OBJECT:12:_ZTISt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:12:_ZTISt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21
OBJECT:12:_ZTISt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:12:_ZTISt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4
@@ -4188,12 +4596,14 @@ OBJECT:16:_ZTIPDf@@CXXABI_1.3.4
OBJECT:16:_ZTIPDi@@CXXABI_1.3.3
OBJECT:16:_ZTIPDn@@CXXABI_1.3.5
OBJECT:16:_ZTIPDs@@CXXABI_1.3.3
+OBJECT:16:_ZTIPDu@@CXXABI_1.3.12
OBJECT:16:_ZTIPKDd@@CXXABI_1.3.4
OBJECT:16:_ZTIPKDe@@CXXABI_1.3.4
OBJECT:16:_ZTIPKDf@@CXXABI_1.3.4
OBJECT:16:_ZTIPKDi@@CXXABI_1.3.3
OBJECT:16:_ZTIPKDn@@CXXABI_1.3.5
OBJECT:16:_ZTIPKDs@@CXXABI_1.3.3
+OBJECT:16:_ZTIPKDu@@CXXABI_1.3.12
OBJECT:16:_ZTIPKa@@CXXABI_1.3
OBJECT:16:_ZTIPKb@@CXXABI_1.3
OBJECT:16:_ZTIPKc@@CXXABI_1.3
@@ -4327,6 +4737,19 @@ OBJECT:1:_ZNSt14numeric_limitsIDsE8is_exactE@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_iec559E@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_moduloE@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_signedE@@GLIBCXX_3.4.11
+OBJECT:1:_ZNSt14numeric_limitsIDuE10is_boundedE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE10is_integerE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE12has_infinityE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE13has_quiet_NaNE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE14is_specializedE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE15has_denorm_lossE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE15tinyness_beforeE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE17has_signaling_NaNE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE5trapsE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE8is_exactE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_iec559E@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_moduloE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_signedE@@GLIBCXX_3.4.26
OBJECT:1:_ZNSt14numeric_limitsIaE10is_boundedE@@GLIBCXX_3.4
OBJECT:1:_ZNSt14numeric_limitsIaE10is_integerE@@GLIBCXX_3.4
OBJECT:1:_ZNSt14numeric_limitsIaE12has_infinityE@@GLIBCXX_3.4
@@ -4570,6 +4993,8 @@ OBJECT:1:_ZSt7nothrow@@GLIBCXX_3.4
OBJECT:20:_ZTSSt12ctype_bynameIcE@@GLIBCXX_3.4
OBJECT:20:_ZTSSt12ctype_bynameIwE@@GLIBCXX_3.4
OBJECT:20:_ZTSSt15underflow_error@@GLIBCXX_3.4
+OBJECT:20:_ZTVNSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26
+OBJECT:20:_ZTVNSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26
OBJECT:20:_ZTVNSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
OBJECT:20:_ZTVNSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15
OBJECT:20:_ZTVNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17
@@ -4698,6 +5123,8 @@ OBJECT:2:_ZTSv@@CXXABI_1.3
OBJECT:2:_ZTSw@@CXXABI_1.3
OBJECT:2:_ZTSx@@CXXABI_1.3
OBJECT:2:_ZTSy@@CXXABI_1.3
+OBJECT:30:_ZTSSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
+OBJECT:30:_ZTSSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:32:_ZTINSt7__cxx1110moneypunctIcLb0EEE@@GLIBCXX_3.4.21
OBJECT:32:_ZTINSt7__cxx1110moneypunctIcLb1EEE@@GLIBCXX_3.4.21
OBJECT:32:_ZTINSt7__cxx1110moneypunctIwLb0EEE@@GLIBCXX_3.4.21
@@ -4852,7 +5279,9 @@ OBJECT:44:_ZTVSt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21
OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:44:_ZTVSt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21
+OBJECT:44:_ZTVSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:44:_ZTVSt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21
+OBJECT:44:_ZTVSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:44:_ZTVSt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21
OBJECT:44:_ZTVSt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:44:_ZTVSt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4
@@ -4904,6 +5333,15 @@ OBJECT:4:_ZNSt14numeric_limitsIDsE14min_exponent10E@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE5radixE@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE6digitsE@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE8digits10E@@GLIBCXX_3.4.11
+OBJECT:4:_ZNSt14numeric_limitsIDuE10has_denormE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE11round_styleE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE12max_exponentE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE12min_exponentE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE14max_exponent10E@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE14min_exponent10E@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE5radixE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE6digitsE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE8digits10E@@GLIBCXX_3.4.26
OBJECT:4:_ZNSt14numeric_limitsIaE10has_denormE@@GLIBCXX_3.4
OBJECT:4:_ZNSt14numeric_limitsIaE11round_styleE@@GLIBCXX_3.4
OBJECT:4:_ZNSt14numeric_limitsIaE12max_digits10E@@GLIBCXX_3.4.14
@@ -5103,7 +5541,9 @@ OBJECT:4:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2
OBJECT:4:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21
OBJECT:4:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21
OBJECT:4:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21
+OBJECT:4:_ZNSt7codecvtIDiDu11__mbstate_tE2idE@@GLIBCXX_3.4.26
OBJECT:4:_ZNSt7codecvtIDic11__mbstate_tE2idE@@GLIBCXX_3.4.21
+OBJECT:4:_ZNSt7codecvtIDsDu11__mbstate_tE2idE@@GLIBCXX_3.4.26
OBJECT:4:_ZNSt7codecvtIDsc11__mbstate_tE2idE@@GLIBCXX_3.4.21
OBJECT:4:_ZNSt7codecvtIcc11__mbstate_tE2idE@@GLIBCXX_3.4
OBJECT:4:_ZNSt7codecvtIwc11__mbstate_tE2idE@@GLIBCXX_3.4
@@ -5302,6 +5742,7 @@ OBJECT:8:_ZTIDf@@CXXABI_1.3.4
OBJECT:8:_ZTIDi@@CXXABI_1.3.3
OBJECT:8:_ZTIDn@@CXXABI_1.3.5
OBJECT:8:_ZTIDs@@CXXABI_1.3.3
+OBJECT:8:_ZTIDu@@CXXABI_1.3.12
OBJECT:8:_ZTIN10__cxxabiv115__forced_unwindE@@CXXABI_1.3.2
OBJECT:8:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2
OBJECT:8:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml
index d296c8d..58587e8 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -166,18 +166,24 @@
<varlistentry><term><code>--enable-libstdcxx-time=OPTION</code></term>
<listitem><para>Enables link-type checks for the availability of the
- clock_gettime clocks, used in the implementation of [time.clock],
- and of the nanosleep and sched_yield functions, used in the
+ <function>clock_gettime</function> clocks, used in the implementation
+ of [time.clock], and of the <function>nanosleep</function> and
+ <function>sched_yield</function> functions, used in the
implementation of [thread.thread.this] of the 2011 ISO C++ standard.
The choice OPTION=yes checks for the availability of the facilities
in libc and libposix4. In case it's needed the latter is also linked
- to libstdc++ as part of the build process. OPTION=rt also searches
- (and, if needed, links) librt. Note that the latter is not always
- desirable because, in glibc, for example, in turn it triggers the
- linking of libpthread too, which activates locking, a large overhead
- for single-thread programs. OPTION=no skips the tests completely.
+ to libstdc++ as part of the build process. OPTION=rt also checks in
+ librt (and, if it's needed, links to it). Note that linking to librt
+ is not always desirable because for glibc it requires linking to
+ libpthread too, which causes all reference counting to use atomic
+ operations, resulting in a potentially large overhead for
+ single-threaded programs. OPTION=no skips the tests completely.
The default is OPTION=auto, which skips the checks and enables the
features only for targets known to support them.
+ For Linux targets, if <function>clock_gettime</function> is not used
+ then the [time.clock] implementation will use a system call to access
+ the realtime and monotonic clocks, which is significantly slower than
+ the C library's <function>clock_gettime</function> function.
</para>
</listitem></varlistentry>
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
index 029c5bc..3a5de38 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
@@ -78,14 +78,13 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Floating Point Atomic </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0020r6.html">
P0020R6
</link>
</entry>
- <entry align="center"> </entry>
+ <entry align="center"> 10.1 </entry>
<entry />
</row>
@@ -345,15 +344,14 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#C8B0B0" ?>
<entry> Atomic Ref </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0019r8.html">
P0019R8
</link>
</entry>
- <entry align="center"> </entry>
- <entry />
+ <entry align="center"> 10.1 </entry>
+ <entry> <code>__cpp_lib_atomic_ref &gt;= 201806L</code> </entry>
</row>
<row>
diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index e30caef..146e70a 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -35,6 +35,7 @@
#include <bits/c++config.h>
#include <stdint.h>
#include <bits/atomic_lockfree_defines.h>
+#include <bits/move.h>
#ifndef _GLIBCXX_ALWAYS_INLINE
#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
@@ -817,6 +818,876 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __atomic_fetch_sub(&_M_p, _M_type_size(__d), int(__m)); }
};
+#if __cplusplus > 201703L
+ // Implementation details of atomic_ref and atomic<floating-point>.
+ namespace __atomic_impl
+ {
+ // Remove volatile and create a non-deduced context for value arguments.
+ template<typename _Tp>
+ using _Val = remove_volatile_t<_Tp>;
+
+ // As above, but for difference_type arguments.
+ template<typename _Tp>
+ using _Diff = conditional_t<is_pointer_v<_Tp>, ptrdiff_t, _Val<_Tp>>;
+
+ template<size_t _Size, size_t _Align>
+ _GLIBCXX_ALWAYS_INLINE bool
+ is_lock_free() noexcept
+ {
+ // Produce a fake, minimally aligned pointer.
+ return __atomic_is_lock_free(_Size, reinterpret_cast<void *>(-_Align));
+ }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE void
+ store(_Tp* __ptr, _Val<_Tp> __t, memory_order __m) noexcept
+ { __atomic_store(__ptr, std::__addressof(__t), int(__m)); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ load(_Tp* __ptr, memory_order __m) noexcept
+ {
+ alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
+ _Tp* __dest = reinterpret_cast<_Tp*>(__buf);
+ __atomic_load(__ptr, __dest, int(__m));
+ return *__dest;
+ }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ exchange(_Tp* __ptr, _Val<_Tp> __desired, memory_order __m) noexcept
+ {
+ alignas(_Tp) unsigned char __buf[sizeof(_Tp)];
+ _Tp* __dest = reinterpret_cast<_Tp*>(__buf);
+ __atomic_exchange(__ptr, std::__addressof(__desired), __dest, int(__m));
+ return *__dest;
+ }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE bool
+ compare_exchange_weak(_Tp* __ptr, _Val<_Tp>& __expected,
+ _Val<_Tp> __desired, memory_order __success,
+ memory_order __failure) noexcept
+ {
+ return __atomic_compare_exchange(__ptr, std::__addressof(__expected),
+ std::__addressof(__desired), true,
+ int(__success), int(__failure));
+ }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE bool
+ compare_exchange_strong(_Tp* __ptr, _Val<_Tp>& __expected,
+ _Val<_Tp> __desired, memory_order __success,
+ memory_order __failure) noexcept
+ {
+ return __atomic_compare_exchange(__ptr, std::__addressof(__expected),
+ std::__addressof(__desired), false,
+ int(__success), int(__failure));
+ }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ fetch_add(_Tp* __ptr, _Diff<_Tp> __i, memory_order __m) noexcept
+ { return __atomic_fetch_add(__ptr, __i, int(__m)); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ fetch_sub(_Tp* __ptr, _Diff<_Tp> __i, memory_order __m) noexcept
+ { return __atomic_fetch_sub(__ptr, __i, int(__m)); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ fetch_and(_Tp* __ptr, _Val<_Tp> __i, memory_order __m) noexcept
+ { return __atomic_fetch_and(__ptr, __i, int(__m)); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ fetch_or(_Tp* __ptr, _Val<_Tp> __i, memory_order __m) noexcept
+ { return __atomic_fetch_or(__ptr, __i, int(__m)); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ fetch_xor(_Tp* __ptr, _Val<_Tp> __i, memory_order __m) noexcept
+ { return __atomic_fetch_xor(__ptr, __i, int(__m)); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ __add_fetch(_Tp* __ptr, _Diff<_Tp> __i) noexcept
+ { return __atomic_add_fetch(__ptr, __i, __ATOMIC_SEQ_CST); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ __sub_fetch(_Tp* __ptr, _Diff<_Tp> __i) noexcept
+ { return __atomic_sub_fetch(__ptr, __i, __ATOMIC_SEQ_CST); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ __and_fetch(_Tp* __ptr, _Val<_Tp> __i) noexcept
+ { return __atomic_and_fetch(__ptr, __i, __ATOMIC_SEQ_CST); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ __or_fetch(_Tp* __ptr, _Val<_Tp> __i) noexcept
+ { return __atomic_or_fetch(__ptr, __i, __ATOMIC_SEQ_CST); }
+
+ template<typename _Tp>
+ _GLIBCXX_ALWAYS_INLINE _Tp
+ __xor_fetch(_Tp* __ptr, _Val<_Tp> __i) noexcept
+ { return __atomic_xor_fetch(__ptr, __i, __ATOMIC_SEQ_CST); }
+
+ template<typename _Tp>
+ _Tp
+ __fetch_add_flt(_Tp* __ptr, _Val<_Tp> __i, memory_order __m) noexcept
+ {
+ _Val<_Tp> __oldval = load(__ptr, memory_order_relaxed);
+ _Val<_Tp> __newval = __oldval + __i;
+ while (!compare_exchange_weak(__ptr, __oldval, __newval, __m,
+ memory_order_relaxed))
+ __newval = __oldval + __i;
+ return __oldval;
+ }
+
+ template<typename _Tp>
+ _Tp
+ __fetch_sub_flt(_Tp* __ptr, _Val<_Tp> __i, memory_order __m) noexcept
+ {
+ _Val<_Tp> __oldval = load(__ptr, memory_order_relaxed);
+ _Val<_Tp> __newval = __oldval - __i;
+ while (!compare_exchange_weak(__ptr, __oldval, __newval, __m,
+ memory_order_relaxed))
+ __newval = __oldval - __i;
+ return __oldval;
+ }
+
+ template<typename _Tp>
+ _Tp
+ __add_fetch_flt(_Tp* __ptr, _Val<_Tp> __i) noexcept
+ {
+ _Val<_Tp> __oldval = load(__ptr, memory_order_relaxed);
+ _Val<_Tp> __newval = __oldval + __i;
+ while (!compare_exchange_weak(__ptr, __oldval, __newval,
+ memory_order_seq_cst,
+ memory_order_relaxed))
+ __newval = __oldval + __i;
+ return __newval;
+ }
+
+ template<typename _Tp>
+ _Tp
+ __sub_fetch_flt(_Tp* __ptr, _Val<_Tp> __i) noexcept
+ {
+ _Val<_Tp> __oldval = load(__ptr, memory_order_relaxed);
+ _Val<_Tp> __newval = __oldval - __i;
+ while (!compare_exchange_weak(__ptr, __oldval, __newval,
+ memory_order_seq_cst,
+ memory_order_relaxed))
+ __newval = __oldval - __i;
+ return __newval;
+ }
+ } // namespace __atomic_impl
+
+ // base class for atomic<floating-point-type>
+ template<typename _Fp>
+ struct __atomic_float
+ {
+ static_assert(is_floating_point_v<_Fp>);
+
+ static constexpr size_t _S_alignment = __alignof__(_Fp);
+
+ public:
+ using value_type = _Fp;
+ using difference_type = value_type;
+
+ static constexpr bool is_always_lock_free
+ = __atomic_always_lock_free(sizeof(_Fp), 0);
+
+ __atomic_float() = default;
+
+ constexpr
+ __atomic_float(_Fp __t) : _M_fp(__t)
+ { }
+
+ __atomic_float(const __atomic_float&) = delete;
+ __atomic_float& operator=(const __atomic_float&) = delete;
+ __atomic_float& operator=(const __atomic_float&) volatile = delete;
+
+ _Fp
+ operator=(_Fp __t) volatile noexcept
+ {
+ this->store(__t);
+ return __t;
+ }
+
+ _Fp
+ operator=(_Fp __t) noexcept
+ {
+ this->store(__t);
+ return __t;
+ }
+
+ bool
+ is_lock_free() const volatile noexcept
+ { return __atomic_impl::is_lock_free<sizeof(_Fp), _S_alignment>(); }
+
+ bool
+ is_lock_free() const noexcept
+ { return __atomic_impl::is_lock_free<sizeof(_Fp), _S_alignment>(); }
+
+ void
+ store(_Fp __t, memory_order __m = memory_order_seq_cst) volatile noexcept
+ { __atomic_impl::store(&_M_fp, __t, __m); }
+
+ void
+ store(_Fp __t, memory_order __m = memory_order_seq_cst) noexcept
+ { __atomic_impl::store(&_M_fp, __t, __m); }
+
+ _Fp
+ load(memory_order __m = memory_order_seq_cst) const volatile noexcept
+ { return __atomic_impl::load(&_M_fp, __m); }
+
+ _Fp
+ load(memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::load(&_M_fp, __m); }
+
+ operator _Fp() const volatile noexcept { return this->load(); }
+ operator _Fp() const noexcept { return this->load(); }
+
+ _Fp
+ exchange(_Fp __desired,
+ memory_order __m = memory_order_seq_cst) volatile noexcept
+ { return __atomic_impl::exchange(&_M_fp, __desired, __m); }
+
+ _Fp
+ exchange(_Fp __desired,
+ memory_order __m = memory_order_seq_cst) noexcept
+ { return __atomic_impl::exchange(&_M_fp, __desired, __m); }
+
+ bool
+ compare_exchange_weak(_Fp& __expected, _Fp __desired,
+ memory_order __success,
+ memory_order __failure) noexcept
+ {
+ return __atomic_impl::compare_exchange_weak(&_M_fp,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_weak(_Fp& __expected, _Fp __desired,
+ memory_order __success,
+ memory_order __failure) volatile noexcept
+ {
+ return __atomic_impl::compare_exchange_weak(&_M_fp,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_strong(_Fp& __expected, _Fp __desired,
+ memory_order __success,
+ memory_order __failure) noexcept
+ {
+ return __atomic_impl::compare_exchange_strong(&_M_fp,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_strong(_Fp& __expected, _Fp __desired,
+ memory_order __success,
+ memory_order __failure) volatile noexcept
+ {
+ return __atomic_impl::compare_exchange_strong(&_M_fp,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_weak(_Fp& __expected, _Fp __desired,
+ memory_order __order = memory_order_seq_cst)
+ noexcept
+ {
+ return compare_exchange_weak(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ bool
+ compare_exchange_weak(_Fp& __expected, _Fp __desired,
+ memory_order __order = memory_order_seq_cst)
+ volatile noexcept
+ {
+ return compare_exchange_weak(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ bool
+ compare_exchange_strong(_Fp& __expected, _Fp __desired,
+ memory_order __order = memory_order_seq_cst)
+ noexcept
+ {
+ return compare_exchange_strong(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ bool
+ compare_exchange_strong(_Fp& __expected, _Fp __desired,
+ memory_order __order = memory_order_seq_cst)
+ volatile noexcept
+ {
+ return compare_exchange_strong(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ value_type
+ fetch_add(value_type __i,
+ memory_order __m = memory_order_seq_cst) noexcept
+ { return __atomic_impl::__fetch_add_flt(&_M_fp, __i, __m); }
+
+ value_type
+ fetch_add(value_type __i,
+ memory_order __m = memory_order_seq_cst) volatile noexcept
+ { return __atomic_impl::__fetch_add_flt(&_M_fp, __i, __m); }
+
+ value_type
+ fetch_sub(value_type __i,
+ memory_order __m = memory_order_seq_cst) noexcept
+ { return __atomic_impl::__fetch_sub_flt(&_M_fp, __i, __m); }
+
+ value_type
+ fetch_sub(value_type __i,
+ memory_order __m = memory_order_seq_cst) volatile noexcept
+ { return __atomic_impl::__fetch_sub_flt(&_M_fp, __i, __m); }
+
+ value_type
+ operator+=(value_type __i) noexcept
+ { return __atomic_impl::__add_fetch_flt(&_M_fp, __i); }
+
+ value_type
+ operator+=(value_type __i) volatile noexcept
+ { return __atomic_impl::__add_fetch_flt(&_M_fp, __i); }
+
+ value_type
+ operator-=(value_type __i) noexcept
+ { return __atomic_impl::__sub_fetch_flt(&_M_fp, __i); }
+
+ value_type
+ operator-=(value_type __i) volatile noexcept
+ { return __atomic_impl::__sub_fetch_flt(&_M_fp, __i); }
+
+ private:
+ alignas(_S_alignment) _Fp _M_fp;
+ };
+
+ template<typename _Tp,
+ bool = is_integral_v<_Tp>, bool = is_floating_point_v<_Tp>>
+ struct __atomic_ref;
+
+ // base class for non-integral, non-floating-point, non-pointer types
+ template<typename _Tp>
+ struct __atomic_ref<_Tp, false, false>
+ {
+ static_assert(is_trivially_copyable_v<_Tp>);
+
+ // 1/2/4/8/16-byte types must be aligned to at least their size.
+ static constexpr int _S_min_alignment
+ = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
+ ? 0 : sizeof(_Tp);
+
+ public:
+ using value_type = _Tp;
+
+ static constexpr bool is_always_lock_free
+ = __atomic_always_lock_free(sizeof(_Tp), 0);
+
+ static constexpr size_t required_alignment
+ = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
+
+ __atomic_ref& operator=(const __atomic_ref&) = delete;
+
+ explicit
+ __atomic_ref(_Tp& __t) : _M_ptr(std::__addressof(__t))
+ { __glibcxx_assert(((uintptr_t)_M_ptr % required_alignment) == 0); }
+
+ __atomic_ref(const __atomic_ref&) noexcept = default;
+
+ _Tp
+ operator=(_Tp __t) const noexcept
+ {
+ this->store(__t);
+ return __t;
+ }
+
+ operator _Tp() const noexcept { return this->load(); }
+
+ bool
+ is_lock_free() const noexcept
+ { return __atomic_impl::is_lock_free<sizeof(_Tp), required_alignment>(); }
+
+ void
+ store(_Tp __t, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::store(_M_ptr, __t, __m); }
+
+ _Tp
+ load(memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::load(_M_ptr, __m); }
+
+ _Tp
+ exchange(_Tp __desired, memory_order __m = memory_order_seq_cst)
+ const noexcept
+ { return __atomic_impl::exchange(_M_ptr, __desired, __m); }
+
+ bool
+ compare_exchange_weak(_Tp& __expected, _Tp __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_weak(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_strong(_Tp& __expected, _Tp __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_strong(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_weak(_Tp& __expected, _Tp __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_weak(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ bool
+ compare_exchange_strong(_Tp& __expected, _Tp __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_strong(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ private:
+ _Tp* _M_ptr;
+ };
+
+ // base class for atomic_ref<integral-type>
+ template<typename _Tp>
+ struct __atomic_ref<_Tp, true, false>
+ {
+ static_assert(is_integral_v<_Tp>);
+
+ public:
+ using value_type = _Tp;
+ using difference_type = value_type;
+
+ static constexpr bool is_always_lock_free
+ = __atomic_always_lock_free(sizeof(_Tp), 0);
+
+ static constexpr size_t required_alignment
+ = sizeof(_Tp) > alignof(_Tp) ? sizeof(_Tp) : alignof(_Tp);
+
+ __atomic_ref() = delete;
+ __atomic_ref& operator=(const __atomic_ref&) = delete;
+
+ explicit
+ __atomic_ref(_Tp& __t) : _M_ptr(&__t)
+ { __glibcxx_assert(((uintptr_t)_M_ptr % required_alignment) == 0); }
+
+ __atomic_ref(const __atomic_ref&) noexcept = default;
+
+ _Tp
+ operator=(_Tp __t) const noexcept
+ {
+ this->store(__t);
+ return __t;
+ }
+
+ operator _Tp() const noexcept { return this->load(); }
+
+ bool
+ is_lock_free() const noexcept
+ {
+ return __atomic_impl::is_lock_free<sizeof(_Tp), required_alignment>();
+ }
+
+ void
+ store(_Tp __t, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::store(_M_ptr, __t, __m); }
+
+ _Tp
+ load(memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::load(_M_ptr, __m); }
+
+ _Tp
+ exchange(_Tp __desired,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::exchange(_M_ptr, __desired, __m); }
+
+ bool
+ compare_exchange_weak(_Tp& __expected, _Tp __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_weak(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_strong(_Tp& __expected, _Tp __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_strong(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_weak(_Tp& __expected, _Tp __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_weak(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ bool
+ compare_exchange_strong(_Tp& __expected, _Tp __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_strong(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ value_type
+ fetch_add(value_type __i,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::fetch_add(_M_ptr, __i, __m); }
+
+ value_type
+ fetch_sub(value_type __i,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::fetch_sub(_M_ptr, __i, __m); }
+
+ value_type
+ fetch_and(value_type __i,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::fetch_and(_M_ptr, __i, __m); }
+
+ value_type
+ fetch_or(value_type __i,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::fetch_or(_M_ptr, __i, __m); }
+
+ value_type
+ fetch_xor(value_type __i,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::fetch_xor(_M_ptr, __i, __m); }
+
+ _GLIBCXX_ALWAYS_INLINE value_type
+ operator++(int) const noexcept
+ { return fetch_add(1); }
+
+ _GLIBCXX_ALWAYS_INLINE value_type
+ operator--(int) const noexcept
+ { return fetch_sub(1); }
+
+ value_type
+ operator++() const noexcept
+ { return __atomic_impl::__add_fetch(_M_ptr, value_type(1)); }
+
+ value_type
+ operator--() const noexcept
+ { return __atomic_impl::__sub_fetch(_M_ptr, value_type(1)); }
+
+ value_type
+ operator+=(value_type __i) const noexcept
+ { return __atomic_impl::__add_fetch(_M_ptr, __i); }
+
+ value_type
+ operator-=(value_type __i) const noexcept
+ { return __atomic_impl::__sub_fetch(_M_ptr, __i); }
+
+ value_type
+ operator&=(value_type __i) const noexcept
+ { return __atomic_impl::__and_fetch(_M_ptr, __i); }
+
+ value_type
+ operator|=(value_type __i) const noexcept
+ { return __atomic_impl::__or_fetch(_M_ptr, __i); }
+
+ value_type
+ operator^=(value_type __i) const noexcept
+ { return __atomic_impl::__xor_fetch(_M_ptr, __i); }
+
+ private:
+ _Tp* _M_ptr;
+ };
+
+ // base class for atomic_ref<floating-point-type>
+ template<typename _Fp>
+ struct __atomic_ref<_Fp, false, true>
+ {
+ static_assert(is_floating_point_v<_Fp>);
+
+ public:
+ using value_type = _Fp;
+ using difference_type = value_type;
+
+ static constexpr bool is_always_lock_free
+ = __atomic_always_lock_free(sizeof(_Fp), 0);
+
+ static constexpr size_t required_alignment = __alignof__(_Fp);
+
+ __atomic_ref() = delete;
+ __atomic_ref& operator=(const __atomic_ref&) = delete;
+
+ explicit
+ __atomic_ref(_Fp& __t) : _M_ptr(&__t)
+ { __glibcxx_assert(((uintptr_t)_M_ptr % required_alignment) == 0); }
+
+ __atomic_ref(const __atomic_ref&) noexcept = default;
+
+ _Fp
+ operator=(_Fp __t) const noexcept
+ {
+ this->store(__t);
+ return __t;
+ }
+
+ operator _Fp() const noexcept { return this->load(); }
+
+ bool
+ is_lock_free() const noexcept
+ {
+ return __atomic_impl::is_lock_free<sizeof(_Fp), required_alignment>();
+ }
+
+ void
+ store(_Fp __t, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::store(_M_ptr, __t, __m); }
+
+ _Fp
+ load(memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::load(_M_ptr, __m); }
+
+ _Fp
+ exchange(_Fp __desired,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::exchange(_M_ptr, __desired, __m); }
+
+ bool
+ compare_exchange_weak(_Fp& __expected, _Fp __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_weak(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_strong(_Fp& __expected, _Fp __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_strong(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_weak(_Fp& __expected, _Fp __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_weak(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ bool
+ compare_exchange_strong(_Fp& __expected, _Fp __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_strong(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ value_type
+ fetch_add(value_type __i,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::__fetch_add_flt(_M_ptr, __i, __m); }
+
+ value_type
+ fetch_sub(value_type __i,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::__fetch_sub_flt(_M_ptr, __i, __m); }
+
+ value_type
+ operator+=(value_type __i) const noexcept
+ { return __atomic_impl::__add_fetch_flt(_M_ptr, __i); }
+
+ value_type
+ operator-=(value_type __i) const noexcept
+ { return __atomic_impl::__sub_fetch_flt(_M_ptr, __i); }
+
+ private:
+ _Fp* _M_ptr;
+ };
+
+ // base class for atomic_ref<pointer-type>
+ template<typename _Tp>
+ struct __atomic_ref<_Tp*, false, false>
+ {
+ public:
+ using value_type = _Tp*;
+ using difference_type = ptrdiff_t;
+
+ static constexpr bool is_always_lock_free = ATOMIC_POINTER_LOCK_FREE == 2;
+
+ static constexpr size_t required_alignment = __alignof__(_Tp*);
+
+ __atomic_ref() = delete;
+ __atomic_ref& operator=(const __atomic_ref&) = delete;
+
+ explicit
+ __atomic_ref(_Tp*& __t) : _M_ptr(std::__addressof(__t))
+ { __glibcxx_assert(((uintptr_t)_M_ptr % required_alignment) == 0); }
+
+ __atomic_ref(const __atomic_ref&) noexcept = default;
+
+ _Tp*
+ operator=(_Tp* __t) const noexcept
+ {
+ this->store(__t);
+ return __t;
+ }
+
+ operator _Tp*() const noexcept { return this->load(); }
+
+ bool
+ is_lock_free() const noexcept
+ {
+ return __atomic_impl::is_lock_free<sizeof(_Tp*), required_alignment>();
+ }
+
+ void
+ store(_Tp* __t, memory_order __m = memory_order_seq_cst) const noexcept
+ { __atomic_impl::store(_M_ptr, __t, __m); }
+
+ _Tp*
+ load(memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::load(_M_ptr, __m); }
+
+ _Tp*
+ exchange(_Tp* __desired,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::exchange(_M_ptr, __desired, __m); }
+
+ bool
+ compare_exchange_weak(_Tp*& __expected, _Tp* __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_weak(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_strong(_Tp*& __expected, _Tp* __desired,
+ memory_order __success,
+ memory_order __failure) const noexcept
+ {
+ return __atomic_impl::compare_exchange_strong(_M_ptr,
+ __expected, __desired,
+ __success, __failure);
+ }
+
+ bool
+ compare_exchange_weak(_Tp*& __expected, _Tp* __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_weak(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ bool
+ compare_exchange_strong(_Tp*& __expected, _Tp* __desired,
+ memory_order __order = memory_order_seq_cst)
+ const noexcept
+ {
+ return compare_exchange_strong(__expected, __desired, __order,
+ __cmpexch_failure_order(__order));
+ }
+
+ _GLIBCXX_ALWAYS_INLINE value_type
+ fetch_add(difference_type __d,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::fetch_add(_M_ptr, _S_type_size(__d), __m); }
+
+ _GLIBCXX_ALWAYS_INLINE value_type
+ fetch_sub(difference_type __d,
+ memory_order __m = memory_order_seq_cst) const noexcept
+ { return __atomic_impl::fetch_sub(_M_ptr, _S_type_size(__d), __m); }
+
+ value_type
+ operator++(int) const noexcept
+ { return fetch_add(1); }
+
+ value_type
+ operator--(int) const noexcept
+ { return fetch_sub(1); }
+
+ value_type
+ operator++() const noexcept
+ {
+ return __atomic_impl::__add_fetch(_M_ptr, _S_type_size(1));
+ }
+
+ value_type
+ operator--() const noexcept
+ {
+ return __atomic_impl::__sub_fetch(_M_ptr, _S_type_size(1));
+ }
+
+ value_type
+ operator+=(difference_type __d) const noexcept
+ {
+ return __atomic_impl::__add_fetch(_M_ptr, _S_type_size(__d));
+ }
+
+ value_type
+ operator-=(difference_type __d) const noexcept
+ {
+ return __atomic_impl::__sub_fetch(_M_ptr, _S_type_size(__d));
+ }
+
+ private:
+ static constexpr ptrdiff_t
+ _S_type_size(ptrdiff_t __d) noexcept
+ {
+ static_assert(is_object_v<_Tp>);
+ return __d * sizeof(_Tp);
+ }
+
+ _Tp** _M_ptr;
+ };
+
+#endif // C++2a
+
// @} group atomics
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/bits/stl_tempbuf.h b/libstdc++-v3/include/bits/stl_tempbuf.h
index fa78ee5..c7d58a1 100644
--- a/libstdc++-v3/include/bits/stl_tempbuf.h
+++ b/libstdc++-v3/include/bits/stl_tempbuf.h
@@ -63,6 +63,21 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ namespace __detail
+ {
+ template<typename _Tp>
+ inline void
+ __return_temporary_buffer(_Tp* __p,
+ size_t __len __attribute__((__unused__)))
+ {
+#if __cpp_sized_deallocation
+ ::operator delete(__p, __len * sizeof(_Tp));
+#else
+ ::operator delete(__p);
+#endif
+ }
+ }
+
/**
* @brief Allocates a temporary buffer.
* @param __len The number of objects of type Tp.
@@ -112,7 +127,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return_temporary_buffer(_Tp* __p)
{ ::operator delete(__p); }
-
/**
* This class is used in two places: stl_algo.h and ext/memory,
* where it is wrapped as the temporary_buffer class. See
@@ -165,7 +179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
~_Temporary_buffer()
{
std::_Destroy(_M_buffer, _M_buffer + _M_len);
- std::return_temporary_buffer(_M_buffer);
+ std::__detail::__return_temporary_buffer(_M_buffer, _M_len);
}
private:
@@ -185,7 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__ucr(_Pointer __first, _Pointer __last,
_ForwardIterator __seed)
{
- if(__first == __last)
+ if (__first == __last)
return;
_Pointer __cur = __first;
@@ -244,22 +258,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Temporary_buffer(_ForwardIterator __seed, size_type __original_len)
: _M_original_len(__original_len), _M_len(0), _M_buffer(0)
{
- __try
- {
- std::pair<pointer, size_type> __p(std::get_temporary_buffer<
- value_type>(_M_original_len));
- _M_buffer = __p.first;
- _M_len = __p.second;
- if (_M_buffer)
- std::__uninitialized_construct_buf(_M_buffer, _M_buffer + _M_len,
- __seed);
- }
- __catch(...)
+ std::pair<pointer, size_type> __p(
+ std::get_temporary_buffer<value_type>(_M_original_len));
+
+ if (__p.first)
{
- std::return_temporary_buffer(_M_buffer);
- _M_buffer = 0;
- _M_len = 0;
- __throw_exception_again;
+ __try
+ {
+ std::__uninitialized_construct_buf(__p.first, __p.first + __p.second,
+ __seed);
+ _M_buffer = __p.first;
+ _M_len = __p.second;
+ }
+ __catch(...)
+ {
+ std::__detail::__return_temporary_buffer(__p.first, __p.second);
+ __throw_exception_again;
+ }
}
}
diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view
index 9449869..84b2a3e 100644
--- a/libstdc++-v3/include/experimental/string_view
+++ b/libstdc++-v3/include/experimental/string_view
@@ -436,14 +436,10 @@ inline namespace fundamentals_v1
// [string.view.comparison], non-member basic_string_view comparison functions
- namespace __detail
- {
- // Identity transform to create a non-deduced context, so that only one
- // argument participates in template argument deduction and the other
- // argument gets implicitly converted to the deduced type. See n3766.html.
- template<typename _Tp>
- using __idt = common_type_t<_Tp>;
- }
+ // Several of these functions use type_identity_t to create a non-deduced
+ // context, so that only one argument participates in template argument
+ // deduction and the other argument gets implicitly converted to the deduced
+ // type (see N3766).
template<typename _CharT, typename _Traits>
constexpr bool
@@ -454,12 +450,13 @@ inline namespace fundamentals_v1
template<typename _CharT, typename _Traits>
constexpr bool
operator==(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
@@ -472,12 +469,13 @@ inline namespace fundamentals_v1
template<typename _CharT, typename _Traits>
constexpr bool
operator!=(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return !(__x == __y); }
template<typename _CharT, typename _Traits>
constexpr bool
- operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return !(__x == __y); }
@@ -490,12 +488,13 @@ inline namespace fundamentals_v1
template<typename _CharT, typename _Traits>
constexpr bool
operator< (basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) < 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) < 0; }
@@ -508,12 +507,13 @@ inline namespace fundamentals_v1
template<typename _CharT, typename _Traits>
constexpr bool
operator> (basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) > 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) > 0; }
@@ -526,12 +526,13 @@ inline namespace fundamentals_v1
template<typename _CharT, typename _Traits>
constexpr bool
operator<=(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) <= 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) <= 0; }
@@ -544,12 +545,13 @@ inline namespace fundamentals_v1
template<typename _CharT, typename _Traits>
constexpr bool
operator>=(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) >= 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) >= 0; }
diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h
index 0783a58..333c8843 100644
--- a/libstdc++-v3/include/ext/atomicity.h
+++ b/libstdc++-v3/include/ext/atomicity.h
@@ -44,24 +44,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __exchange_and_add_dispatch
// __atomic_add_dispatch
#ifdef _GLIBCXX_ATOMIC_BUILTINS
- static inline _Atomic_word
+ inline _Atomic_word
+ __attribute__((__always_inline__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{ return __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
- static inline void
+ inline void
+ __attribute__((__always_inline__))
__atomic_add(volatile _Atomic_word* __mem, int __val)
{ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
#else
_Atomic_word
- __attribute__ ((__unused__))
- __exchange_and_add(volatile _Atomic_word*, int) throw ();
+ __exchange_and_add(volatile _Atomic_word*, int) _GLIBCXX_NOTHROW;
void
- __attribute__ ((__unused__))
- __atomic_add(volatile _Atomic_word*, int) throw ();
+ __atomic_add(volatile _Atomic_word*, int) _GLIBCXX_NOTHROW;
#endif
- static inline _Atomic_word
+ inline _Atomic_word
+ __attribute__((__always_inline__))
__exchange_and_add_single(_Atomic_word* __mem, int __val)
{
_Atomic_word __result = *__mem;
@@ -69,36 +70,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __result;
}
- static inline void
+ inline void
+ __attribute__((__always_inline__))
__atomic_add_single(_Atomic_word* __mem, int __val)
{ *__mem += __val; }
- static inline _Atomic_word
- __attribute__ ((__unused__))
+ inline _Atomic_word
+ __attribute__ ((__always_inline__))
__exchange_and_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
return __exchange_and_add(__mem, __val);
- else
- return __exchange_and_add_single(__mem, __val);
-#else
- return __exchange_and_add_single(__mem, __val);
#endif
+ return __exchange_and_add_single(__mem, __val);
}
- static inline void
- __attribute__ ((__unused__))
+ inline void
+ __attribute__ ((__always_inline__))
__atomic_add_dispatch(_Atomic_word* __mem, int __val)
{
#ifdef __GTHREADS
if (__gthread_active_p())
- __atomic_add(__mem, __val);
- else
- __atomic_add_single(__mem, __val);
-#else
- __atomic_add_single(__mem, __val);
+ {
+ __atomic_add(__mem, __val);
+ return;
+ }
#endif
+ __atomic_add_single(__mem, __val);
}
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 699431e..26d8d39 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -39,7 +39,6 @@
#else
#include <bits/atomic_base.h>
-#include <bits/move.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -1472,6 +1471,71 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__atomic_val_t<_ITp> __i) noexcept
{ return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
+#if __cplusplus > 201703L
+ template<>
+ struct atomic<float> : __atomic_float<float>
+ {
+ atomic() noexcept = default;
+
+ constexpr
+ atomic(float __fp) noexcept : __atomic_float<float>(__fp)
+ { }
+
+ atomic& operator=(const atomic&) volatile = delete;
+ atomic& operator=(const atomic&) = delete;
+
+ using __atomic_float<float>::operator=;
+ };
+
+ template<>
+ struct atomic<double> : __atomic_float<double>
+ {
+ atomic() noexcept = default;
+
+ constexpr
+ atomic(double __fp) noexcept : __atomic_float<double>(__fp)
+ { }
+
+ atomic& operator=(const atomic&) volatile = delete;
+ atomic& operator=(const atomic&) = delete;
+
+ using __atomic_float<double>::operator=;
+ };
+
+ template<>
+ struct atomic<long double> : __atomic_float<long double>
+ {
+ atomic() noexcept = default;
+
+ constexpr
+ atomic(long double __fp) noexcept : __atomic_float<long double>(__fp)
+ { }
+
+ atomic& operator=(const atomic&) volatile = delete;
+ atomic& operator=(const atomic&) = delete;
+
+ using __atomic_float<long double>::operator=;
+ };
+
+#define __cpp_lib_atomic_ref 201806L
+
+ /// Class template to provide atomic operations on a non-atomic variable.
+ template<typename _Tp>
+ struct atomic_ref : __atomic_ref<_Tp>
+ {
+ explicit
+ atomic_ref(_Tp& __t) noexcept : __atomic_ref<_Tp>(__t)
+ { }
+
+ atomic_ref& operator=(const atomic_ref&) = delete;
+
+ atomic_ref(const atomic_ref&) = default;
+
+ using __atomic_ref<_Tp>::operator=;
+ };
+
+#endif // C++2a
+
// @} group atomics
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index dd33dcf..f17d2f1 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -42,20 +42,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
constexpr _Tp
- __rotl(_Tp __x, unsigned int __s) noexcept
+ __rotl(_Tp __x, int __s) noexcept
{
constexpr auto _Nd = numeric_limits<_Tp>::digits;
- const unsigned __sN = __s % _Nd;
- return (__x << __sN) | (__x >> ((_Nd - __sN) % _Nd));
+ const int __r = __s % _Nd;
+ if (__r == 0)
+ return __x;
+ else if (__r > 0)
+ return (__x << __r) | (__x >> ((_Nd - __r) % _Nd));
+ else
+ return (__x >> -__r) | (__x << ((_Nd + __r) % _Nd)); // rotr(x, -r)
}
template<typename _Tp>
constexpr _Tp
- __rotr(_Tp __x, unsigned int __s) noexcept
+ __rotr(_Tp __x, int __s) noexcept
{
constexpr auto _Nd = numeric_limits<_Tp>::digits;
- const unsigned __sN = __s % _Nd;
- return (__x >> __sN) | (__x << ((_Nd - __sN) % _Nd));
+ const int __r = __s % _Nd;
+ if (__r == 0)
+ return __x;
+ else if (__r > 0)
+ return (__x >> __r) | (__x << ((_Nd - __r) % _Nd));
+ else
+ return (__x << -__r) | (__x >> ((_Nd + __r) % _Nd)); // rotl(x, -r)
}
template<typename _Tp>
@@ -197,9 +207,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr auto _Nd = numeric_limits<_Tp>::digits;
if (__x == 0 || __x == 1)
return 1;
- const unsigned __n = _Nd - std::__countl_zero((_Tp)(__x - 1u));
- const _Tp __y_2 = (_Tp)1u << (__n - 1u);
- return __y_2 << 1u;
+ auto __shift_exponent = _Nd - std::__countl_zero((_Tp)(__x - 1u));
+ // If the shift exponent equals _Nd then the correct result is not
+ // representable as a value of _Tp, and so the result is undefined.
+ // Want that undefined behaviour to be detected in constant expressions,
+ // by UBSan, and by debug assertions.
+#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+ if (!__builtin_is_constant_evaluated())
+ __glibcxx_assert( __shift_exponent != numeric_limits<_Tp>::digits );
+#endif
+ using __promoted_type = decltype(__x << 1);
+ if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value)
+ {
+ // If __x undergoes integral promotion then shifting by _Nd is
+ // not undefined. In order to make the shift undefined, so that
+ // it is diagnosed in constant expressions and by UBsan, we also
+ // need to "promote" the shift exponent to be too large for the
+ // promoted type.
+ const int __extra_exp = sizeof(__promoted_type) / sizeof(_Tp) / 2;
+ __shift_exponent |= (__shift_exponent & _Nd) << __extra_exp;
+ }
+ return (_Tp)1u << __shift_exponent;
}
template<typename _Tp>
@@ -226,20 +254,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using _If_is_unsigned_integer
= enable_if_t<__is_unsigned_integer<_Tp>::value, _Up>;
-#if ! __STRICT_ANSI__
- // [bitops.rot], rotating
+ // [bit.rot], rotating
template<typename _Tp>
- constexpr _If_is_unsigned_integer<_Tp>
- rotl(_Tp __x, unsigned int __s) noexcept
+ [[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
+ rotl(_Tp __x, int __s) noexcept
{ return std::__rotl(__x, __s); }
template<typename _Tp>
- constexpr _If_is_unsigned_integer<_Tp>
- rotr(_Tp __x, unsigned int __s) noexcept
+ [[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
+ rotr(_Tp __x, int __s) noexcept
{ return std::__rotr(__x, __s); }
- // [bitops.count], counting
+ // [bit.count], counting
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
@@ -265,9 +292,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr _If_is_unsigned_integer<_Tp, int>
popcount(_Tp __x) noexcept
{ return std::__popcount(__x); }
-#endif
- // Integral power-of-two operations
+ // [bit.pow.two], integral powers of 2
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, bool>
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 3660f4d..3036802 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -261,7 +261,7 @@ get_pointer_safety() noexcept { return pointer_safety::relaxed; }
uses_allocator_construction_args(const _Alloc& __a,
_Args&&... __args) noexcept
#if __cpp_concepts
- requires ! _Std_pair<_Tp>
+ requires (! _Std_pair<_Tp>)
#endif
{
return std::__uses_alloc_args<_Tp>(__a, std::forward<_Args>(__args)...);
diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view
index 42822cc..e8b6ed3 100644
--- a/libstdc++-v3/include/std/string_view
+++ b/libstdc++-v3/include/std/string_view
@@ -459,14 +459,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [string.view.comparison], non-member basic_string_view comparison function
- namespace __detail
- {
- // Identity transform to create a non-deduced context, so that only one
- // argument participates in template argument deduction and the other
- // argument gets implicitly converted to the deduced type. See n3766.html.
- template<typename _Tp>
- using __idt = common_type_t<_Tp>;
- }
+ // Several of these functions use type_identity_t to create a non-deduced
+ // context, so that only one argument participates in template argument
+ // deduction and the other argument gets implicitly converted to the deduced
+ // type (see N3766).
template<typename _CharT, typename _Traits>
constexpr bool
@@ -477,12 +473,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr bool
operator==(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator==(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator==(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.size() == __y.size() && __x.compare(__y) == 0; }
@@ -495,12 +492,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr bool
operator!=(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return !(__x == __y); }
template<typename _CharT, typename _Traits>
constexpr bool
- operator!=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator!=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return !(__x == __y); }
@@ -513,12 +511,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr bool
operator< (basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) < 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator< (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator< (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) < 0; }
@@ -531,12 +530,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr bool
operator> (basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) > 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator> (__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator> (__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) > 0; }
@@ -549,12 +549,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr bool
operator<=(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) <= 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator<=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator<=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) <= 0; }
@@ -567,12 +568,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
constexpr bool
operator>=(basic_string_view<_CharT, _Traits> __x,
- __detail::__idt<basic_string_view<_CharT, _Traits>> __y) noexcept
+ __type_identity_t<basic_string_view<_CharT, _Traits>> __y)
+ noexcept
{ return __x.compare(__y) >= 0; }
template<typename _CharT, typename _Traits>
constexpr bool
- operator>=(__detail::__idt<basic_string_view<_CharT, _Traits>> __x,
+ operator>=(__type_identity_t<basic_string_view<_CharT, _Traits>> __x,
basic_string_view<_CharT, _Traits> __y) noexcept
{ return __x.compare(__y) >= 0; }
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index b072917..d8ed1ce 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -92,9 +92,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct conditional;
template <typename _Type>
- struct __type_identity {
- using type = _Type;
- };
+ struct __type_identity
+ { using type = _Type; };
+
+ template<typename _Tp>
+ using __type_identity_t = typename __type_identity<_Tp>::type;
template<typename...>
struct __or_;
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index e300fc3..d134f7f 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -150,6 +150,7 @@
#if __cplusplus > 201703L
// c++2a
+#define __cpp_lib_atomic_ref 201806L
#define __cpp_lib_bind_front 201902L
#define __cpp_lib_bounded_array_traits 201902L
#if __cpp_impl_destroying_delete
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countl_one.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_one.cc
index 50b681c..50b681c 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countl_one.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_one.cc
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countl_zero.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_zero.cc
index 8c8a13f..8c8a13f 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countl_zero.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countl_zero.cc
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countr_one.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_one.cc
index 16c9857..16c9857 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countr_one.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_one.cc
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countr_zero.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_zero.cc
index 0e1970b2..0e1970b2 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/countr_zero.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/countr_zero.cc
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/popcount.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/popcount.cc
index 07b8c6a..07b8c6a 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bitops.count/popcount.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.count/popcount.cc
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc
index 84f3ac1..f870d4d 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2.cc
@@ -20,6 +20,21 @@
#include <bit>
+template<typename T>
+ constexpr T max = std::numeric_limits<T>::max();
+// Largest representable power of two (i.e. has most significant bit set)
+template<typename T>
+ constexpr T maxpow2 = T(1) << (std::numeric_limits<T>::digits - 1);
+
+// Detect whether std::ceil2(N) is a constant expression.
+template<auto N, typename = void>
+ struct ceil2_valid
+ : std::false_type { };
+
+template<auto N>
+ struct ceil2_valid<N, std::void_t<char[(std::ceil2(N), 1)]>>
+ : std::true_type { };
+
template<typename UInt>
constexpr auto
test(UInt x)
@@ -55,13 +70,18 @@ test(UInt x)
static_assert( std::ceil2(UInt(3) << 64) == (UInt(4) << 64) );
}
- constexpr UInt msb = UInt(1) << (std::numeric_limits<UInt>::digits - 1);
+ constexpr UInt msb = maxpow2<UInt>;
+ static_assert( ceil2_valid<msb>() );
static_assert( std::ceil2( msb ) == msb );
- // Larger values cannot be represented so the return value is unspecified,
- // but must still be valid in constant expressions, i.e. not undefined.
- static_assert( std::ceil2( UInt(msb + 1) ) != 77 );
- static_assert( std::ceil2( UInt(msb + 2) ) != 77 );
- static_assert( std::ceil2( UInt(msb + 77) ) != 77 );
+ static_assert( std::ceil2( UInt(msb - 1) ) == msb );
+ static_assert( std::ceil2( UInt(msb - 2) ) == msb );
+ static_assert( std::ceil2( UInt(msb - 3) ) == msb );
+
+ // P1355R2: not a constant expression if the result is not representable
+ static_assert( !ceil2_valid<UInt(msb + 1)>() );
+ static_assert( !ceil2_valid<max<UInt>>() );
+ static_assert( !ceil2_valid<UInt(max<UInt> - 1)>() );
+ static_assert( !ceil2_valid<UInt(max<UInt> - 2)>() );
return true;
}
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc
new file mode 100644
index 0000000..8e10706
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.pow.two/ceil2_neg.cc
@@ -0,0 +1,74 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a -D_GLIBCXX_ASSERTIONS" }
+// { dg-do run { target c++2a } }
+// { dg-xfail-run-if "__glibcxx_assert in ceil2 should fail" { *-*-* } }
+
+#include <bit>
+
+// P1355R2: not a constant expression if the result is not representable
+
+template<auto N, typename = void>
+ struct ceil2_valid
+ : std::false_type { };
+
+template<auto N>
+ struct ceil2_valid<N, std::void_t<char[(std::ceil2(N), 1)]>>
+ : std::true_type { };
+
+template<typename T>
+ constexpr T max = std::numeric_limits<T>::max();
+template<typename T>
+ constexpr T maxpow2 = T(1) << (std::numeric_limits<T>::digits - 1);
+
+static_assert( ceil2_valid<maxpow2<unsigned char>>() );
+static_assert( !ceil2_valid<maxpow2<unsigned char> + (unsigned char)1>() );
+
+static_assert( !ceil2_valid<max<unsigned char>>() );
+static_assert( !ceil2_valid<max<unsigned char> - (unsigned char)1>() );
+
+static_assert( ceil2_valid<maxpow2<unsigned short>>() );
+static_assert( !ceil2_valid<maxpow2<unsigned short> + (unsigned short)1>() );
+static_assert( !ceil2_valid<max<unsigned short>>() );
+static_assert( !ceil2_valid<max<unsigned short> - (unsigned short)1>() );
+
+static_assert( ceil2_valid<maxpow2<unsigned int>>() );
+static_assert( !ceil2_valid<maxpow2<unsigned int> + 1u>() );
+static_assert( !ceil2_valid<max<unsigned int>>() );
+static_assert( !ceil2_valid<max<unsigned int> - 1u>() );
+
+static_assert( ceil2_valid<maxpow2<unsigned long>>() );
+static_assert( !ceil2_valid<maxpow2<unsigned long> + 1ul>() );
+static_assert( !ceil2_valid<max<unsigned long>>() );
+static_assert( !ceil2_valid<max<unsigned long> - 1ul>() );
+
+static_assert( ceil2_valid<maxpow2<unsigned long long>>() );
+static_assert( !ceil2_valid<maxpow2<unsigned long long> + 1ull>() );
+static_assert( !ceil2_valid<max<unsigned long long>>() );
+static_assert( !ceil2_valid<max<unsigned long long> - 1ull>() );
+
+void
+test01()
+{
+ std::ceil2( maxpow2<unsigned> + 1u ); // should fail __glibcxx_assert
+}
+
+int main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.rot/rotl.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotl.cc
index 2d97ae8..dfceca0 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bitops.rot/rotl.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotl.cc
@@ -21,11 +21,26 @@
#include <bit>
template<typename UInt>
+constexpr bool
+test_negative_shifts()
+{
+ constexpr unsigned digits = std::numeric_limits<UInt>::digits;
+
+ UInt xarr[] = { (UInt)-1, 0, 1, 3, 6, 7, 0x10, 0x11, 0x22, 0x44, 0x80 };
+ int sarr[] = { 1, 4, 5, digits - 1, digits };
+ for (UInt x : xarr)
+ for (int s : sarr)
+ if (std::rotl(x, -s) != std::rotr(x, s))
+ return false;
+ return true;
+}
+
+template<typename UInt>
constexpr auto
test(UInt x)
--> decltype(std::rotl(x, 0u))
+-> decltype(std::rotl(x, 0))
{
- static_assert( noexcept(std::rotl(x, 0u)) );
+ static_assert( noexcept(std::rotl(x, 0)) );
constexpr unsigned digits = std::numeric_limits<UInt>::digits;
@@ -63,6 +78,8 @@ test(UInt x)
static_assert( std::rotl((UInt)0b1010'0101, 4) == 0b1010'0101'0000 );
}
+ static_assert( test_negative_shifts<UInt>() );
+
return true;
}
diff --git a/libstdc++-v3/testsuite/26_numerics/bit/bitops.rot/rotr.cc b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotr.cc
index c41c24d..f3bb94b 100644
--- a/libstdc++-v3/testsuite/26_numerics/bit/bitops.rot/rotr.cc
+++ b/libstdc++-v3/testsuite/26_numerics/bit/bit.rotate/rotr.cc
@@ -21,11 +21,26 @@
#include <bit>
template<typename UInt>
+constexpr bool
+test_negative_shifts()
+{
+ constexpr unsigned digits = std::numeric_limits<UInt>::digits;
+
+ UInt xarr[] = { (UInt)-1, 0, 1, 3, 6, 7, 0x10, 0x11, 0x22, 0x44, 0x80 };
+ int sarr[] = { 1, 4, 5, digits - 1, digits };
+ for (UInt x : xarr)
+ for (int s : sarr)
+ if (std::rotr(x, -s) != std::rotl(x, s))
+ return false;
+ return true;
+}
+
+template<typename UInt>
constexpr auto
test(UInt x)
--> decltype(std::rotr(x, 0u))
+-> decltype(std::rotr(x, 0))
{
- static_assert( noexcept(std::rotr(x, 0u)) );
+ static_assert( noexcept(std::rotr(x, 0)) );
constexpr unsigned digits = std::numeric_limits<UInt>::digits;
@@ -65,6 +80,8 @@ test(UInt x)
== (0b1010 | ((UInt)0b0101 << digits - 4)) );
}
+ static_assert( test_negative_shifts<UInt>() );
+
return true;
}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc b/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc
index 58d554c..5065730 100644
--- a/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/60695.cc
@@ -27,4 +27,4 @@ struct X {
char stuff[0]; // GNU extension, type has zero size
};
-std::atomic<X> a; // { dg-error "not supported" "" { target *-*-* } 194 }
+std::atomic<X> a; // { dg-error "zero-sized types" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_float/1.cc b/libstdc++-v3/testsuite/29_atomics/atomic_float/1.cc
new file mode 100644
index 0000000..b56c026
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_float/1.cc
@@ -0,0 +1,573 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ const auto mo = std::memory_order_relaxed;
+ bool ok;
+ float expected;
+
+ if constexpr (std::atomic<float>::is_always_lock_free)
+ {
+ std::atomic<float> a0;
+ std::atomic<float> a1(1.0f);
+ ok = a0.is_lock_free();
+ a0 = a1.load();
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( a0.load(mo) == a0.load() );
+ a0.store(0.5f);
+ a1.store(0.5f, mo);
+ VERIFY( a0.load() == a1.load() );
+ auto f0 = a0.exchange(12.5f);
+ auto f1 = a1.exchange(12.5f, mo);
+ VERIFY( a0 == 12.5f );
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( f0 == 0.5f );
+ VERIFY( f0 == f1 );
+
+ expected = 12.5f;
+ while (!a0.compare_exchange_weak(expected, 1.6f, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == 1.6f );
+ VERIFY( expected == 12.5f );
+ expected = 1.5f;
+ ok = a1.compare_exchange_weak(expected, 1.6f, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5f && expected == 12.5f );
+ VERIFY( expected == 12.5f );
+ expected = 1.6f;
+ ok = a0.compare_exchange_strong(expected, 3.2f, mo, mo);
+ VERIFY( ok && a0.load() == 3.2f );
+ VERIFY( expected == 1.6f );
+ expected = 1.5f;
+ ok = a1.compare_exchange_strong(expected, 3.2f, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5f && expected == 12.5f );
+
+ expected = 3.2f;
+ while (!a0.compare_exchange_weak(expected, .64f))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == .64f );
+ expected = 12.5f;
+ while (!a1.compare_exchange_weak(expected, 1.6f, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a1.load() == 1.6f );
+ expected = 0.5f;
+ ok = a0.compare_exchange_weak(expected, 3.2f);
+ VERIFY( !ok && a0.load() == .64f && expected == .64f );
+ expected = 0.5f;
+ ok = a1.compare_exchange_weak(expected, 3.2f, mo);
+ VERIFY( !ok && a1.load() == 1.6f && expected == 1.6f );
+
+ expected = .64f;
+ ok = a0.compare_exchange_strong(expected, 12.8f);
+ VERIFY( ok && a0.load() == 12.8f );
+ expected = 1.6f;
+ ok = a1.compare_exchange_strong(expected, 2.56f, mo);
+ VERIFY( ok && a1.load() == 2.56f );
+ expected = 0.5f;
+ ok = a0.compare_exchange_strong(expected, 3.2f);
+ VERIFY( !ok && a0.load() == 12.8f && expected == 12.8f );
+ expected = 0.5f;
+ ok = a1.compare_exchange_strong(expected, 3.2f, mo);
+ VERIFY( !ok && a1.load() == 2.56f && expected == 2.56f );
+
+ f0 = a0.fetch_add(1.2f);
+ VERIFY( f0 == 12.8f );
+ VERIFY( a0 == 14.0f );
+ f1 = a1.fetch_add(2.4f, mo);
+ VERIFY( f1 == 2.56f );
+ VERIFY( a1 == 4.96f );
+
+ f0 = a0.fetch_sub(1.2f);
+ VERIFY( f0 == 14.0f );
+ VERIFY( a0 == 12.8f );
+ f1 = a1.fetch_sub(3.5f, mo);
+ VERIFY( f1 == 4.96f );
+ VERIFY( a1 == 1.46f );
+
+ f0 = a0 += 1.2f;
+ VERIFY( f0 == 14.0f );
+ VERIFY( a0 == 14.0f );
+
+ f0 = a0 -= 0.8f;
+ VERIFY( f0 == 13.2f );
+ VERIFY( a0 == 13.2f );
+ }
+
+ // Repeat for volatile std::atomic<float>
+ if constexpr (std::atomic<float>::is_always_lock_free)
+ {
+ volatile std::atomic<float> a0;
+ volatile std::atomic<float> a1(1.0f);
+ ok = a0.is_lock_free();
+ a0 = a1.load();
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( a0.load(mo) == a0.load() );
+ a0.store(0.5f);
+ a1.store(0.5f, mo);
+ VERIFY( a0.load() == a1.load() );
+ auto f0 = a0.exchange(12.5f);
+ auto f1 = a1.exchange(12.5f, mo);
+ VERIFY( a0 == 12.5f );
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( f0 == 0.5f );
+ VERIFY( f0 == f1 );
+
+ expected = 12.5f;
+ while (!a0.compare_exchange_weak(expected, 1.6f, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == 1.6f );
+ VERIFY( expected == 12.5f );
+ expected = 1.5f;
+ ok = a1.compare_exchange_weak(expected, 1.6f, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5f && expected == 12.5f );
+ VERIFY( expected == 12.5f );
+ expected = 1.6f;
+ ok = a0.compare_exchange_strong(expected, 3.2f, mo, mo);
+ VERIFY( ok && a0.load() == 3.2f );
+ VERIFY( expected == 1.6f );
+ expected = 1.5f;
+ ok = a1.compare_exchange_strong(expected, 3.2f, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5f && expected == 12.5f );
+
+ expected = 3.2f;
+ while (!a0.compare_exchange_weak(expected, .64f))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == .64f );
+ expected = 12.5f;
+ while (!a1.compare_exchange_weak(expected, 1.6f, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a1.load() == 1.6f );
+ expected = 0.5f;
+ ok = a0.compare_exchange_weak(expected, 3.2f);
+ VERIFY( !ok && a0.load() == .64f && expected == .64f );
+ expected = 0.5f;
+ ok = a1.compare_exchange_weak(expected, 3.2f, mo);
+ VERIFY( !ok && a1.load() == 1.6f && expected == 1.6f );
+
+ expected = .64f;
+ ok = a0.compare_exchange_strong(expected, 12.8f);
+ VERIFY( ok && a0.load() == 12.8f );
+ expected = 1.6f;
+ ok = a1.compare_exchange_strong(expected, 2.56f, mo);
+ VERIFY( ok && a1.load() == 2.56f );
+ expected = 0.5f;
+ ok = a0.compare_exchange_strong(expected, 3.2f);
+ VERIFY( !ok && a0.load() == 12.8f && expected == 12.8f );
+ expected = 0.5f;
+ ok = a1.compare_exchange_strong(expected, 3.2f, mo);
+ VERIFY( !ok && a1.load() == 2.56f && expected == 2.56f );
+
+ f0 = a0.fetch_add(1.2f);
+ VERIFY( f0 == 12.8f );
+ VERIFY( a0 == 14.0f );
+ f1 = a1.fetch_add(2.4f, mo);
+ VERIFY( f1 == 2.56f );
+ VERIFY( a1 == 4.96f );
+
+ f0 = a0.fetch_sub(1.2f);
+ VERIFY( f0 == 14.0f );
+ VERIFY( a0 == 12.8f );
+ f1 = a1.fetch_sub(3.5f, mo);
+ VERIFY( f1 == 4.96f );
+ VERIFY( a1 == 1.46f );
+
+ f0 = a0 += 1.2f;
+ VERIFY( f0 == 14.0f );
+ VERIFY( a0 == 14.0f );
+
+ f0 = a0 -= 0.8f;
+ VERIFY( f0 == 13.2f );
+ VERIFY( a0 == 13.2f );
+ }
+}
+
+void
+test02()
+{
+ const auto mo = std::memory_order_relaxed;
+ bool ok;
+ double expected;
+
+ if constexpr (std::atomic<double>::is_always_lock_free)
+ {
+ std::atomic<double> a0;
+ std::atomic<double> a1(1.0);
+ ok = a0.is_lock_free();
+ a0 = a1.load();
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( a0.load(mo) == a0.load() );
+ a0.store(0.5);
+ a1.store(0.5, mo);
+ VERIFY( a0.load() == a1.load() );
+ auto f0 = a0.exchange(12.5);
+ auto f1 = a1.exchange(12.5, mo);
+ VERIFY( a0 == 12.5 );
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( f0 == 0.5 );
+ VERIFY( f0 == f1 );
+
+ expected = 12.5;
+ while (!a0.compare_exchange_weak(expected, 1.6, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == 1.6 );
+ VERIFY( expected == 12.5 );
+ expected = 1.5;
+ ok = a1.compare_exchange_weak(expected, 1.6, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5 && expected == 12.5 );
+ VERIFY( expected == 12.5 );
+ expected = 1.6;
+ ok = a0.compare_exchange_strong(expected, 3.2, mo, mo);
+ VERIFY( ok && a0.load() == 3.2 );
+ VERIFY( expected == 1.6 );
+ expected = 1.5;
+ ok = a1.compare_exchange_strong(expected, 3.2, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5 && expected == 12.5 );
+
+ expected = 3.2;
+ while (!a0.compare_exchange_weak(expected, .64))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == .64 );
+ expected = 12.5;
+ while (!a1.compare_exchange_weak(expected, 1.6, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a1.load() == 1.6 );
+ expected = 0.5;
+ ok = a0.compare_exchange_weak(expected, 3.2);
+ VERIFY( !ok && a0.load() == .64 && expected == .64 );
+ expected = 0.5;
+ ok = a1.compare_exchange_weak(expected, 3.2, mo);
+ VERIFY( !ok && a1.load() == 1.6 && expected == 1.6 );
+
+ expected = .64;
+ ok = a0.compare_exchange_strong(expected, 12.8);
+ VERIFY( ok && a0.load() == 12.8 );
+ expected = 1.6;
+ ok = a1.compare_exchange_strong(expected, 2.56, mo);
+ VERIFY( ok && a1.load() == 2.56 );
+ expected = 0.5;
+ ok = a0.compare_exchange_strong(expected, 3.2);
+ VERIFY( !ok && a0.load() == 12.8 && expected == 12.8 );
+ expected = 0.5;
+ ok = a1.compare_exchange_strong(expected, 3.2, mo);
+ VERIFY( !ok && a1.load() == 2.56 && expected == 2.56 );
+
+ f0 = a0.fetch_add(1.2);
+ VERIFY( f0 == 12.8 );
+ VERIFY( a0 == 14.0 );
+ f1 = a1.fetch_add(2.4, mo);
+ VERIFY( f1 == 2.56 );
+ VERIFY( a1 == 4.96 );
+
+ f0 = a0.fetch_sub(1.2);
+ VERIFY( f0 == 14.0 );
+ VERIFY( a0 == 12.8 );
+ f1 = a1.fetch_sub(3.5, mo);
+ VERIFY( f1 == 4.96 );
+ VERIFY( a1 == 1.46 );
+
+ f0 = a0 += 1.2;
+ VERIFY( f0 == 14.0 );
+ VERIFY( a0 == 14.0 );
+
+ f0 = a0 -= 0.8;
+ VERIFY( f0 == 13.2 );
+ VERIFY( a0 == 13.2 );
+ }
+
+ // Repeat for volatile std::atomic<double>
+ if constexpr (std::atomic<double>::is_always_lock_free)
+ {
+ volatile std::atomic<double> a0;
+ volatile std::atomic<double> a1(1.0);
+ ok = a0.is_lock_free();
+ a0 = a1.load();
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( a0.load(mo) == a0.load() );
+ a0.store(0.5);
+ a1.store(0.5, mo);
+ VERIFY( a0.load() == a1.load() );
+ auto f0 = a0.exchange(12.5);
+ auto f1 = a1.exchange(12.5, mo);
+ VERIFY( a0 == 12.5 );
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( f0 == 0.5 );
+ VERIFY( f0 == f1 );
+
+ expected = 12.5;
+ while (!a0.compare_exchange_weak(expected, 1.6, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == 1.6 );
+ VERIFY( expected == 12.5 );
+ expected = 1.5;
+ ok = a1.compare_exchange_weak(expected, 1.6, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5 && expected == 12.5 );
+ VERIFY( expected == 12.5 );
+ expected = 1.6;
+ ok = a0.compare_exchange_strong(expected, 3.2, mo, mo);
+ VERIFY( ok && a0.load() == 3.2 );
+ VERIFY( expected == 1.6 );
+ expected = 1.5;
+ ok = a1.compare_exchange_strong(expected, 3.2, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5 && expected == 12.5 );
+
+ expected = 3.2;
+ while (!a0.compare_exchange_weak(expected, .64))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == .64 );
+ expected = 12.5;
+ while (!a1.compare_exchange_weak(expected, 1.6, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a1.load() == 1.6 );
+ expected = 0.5;
+ ok = a0.compare_exchange_weak(expected, 3.2);
+ VERIFY( !ok && a0.load() == .64 && expected == .64 );
+ expected = 0.5;
+ ok = a1.compare_exchange_weak(expected, 3.2, mo);
+ VERIFY( !ok && a1.load() == 1.6 && expected == 1.6 );
+
+ expected = .64;
+ ok = a0.compare_exchange_strong(expected, 12.8);
+ VERIFY( ok && a0.load() == 12.8 );
+ expected = 1.6;
+ ok = a1.compare_exchange_strong(expected, 2.56, mo);
+ VERIFY( ok && a1.load() == 2.56 );
+ expected = 0.5;
+ ok = a0.compare_exchange_strong(expected, 3.2);
+ VERIFY( !ok && a0.load() == 12.8 && expected == 12.8 );
+ expected = 0.5;
+ ok = a1.compare_exchange_strong(expected, 3.2, mo);
+ VERIFY( !ok && a1.load() == 2.56 && expected == 2.56 );
+
+ f0 = a0.fetch_add(1.2);
+ VERIFY( f0 == 12.8 );
+ VERIFY( a0 == 14.0 );
+ f1 = a1.fetch_add(2.4, mo);
+ VERIFY( f1 == 2.56 );
+ VERIFY( a1 == 4.96 );
+
+ f0 = a0.fetch_sub(1.2);
+ VERIFY( f0 == 14.0 );
+ VERIFY( a0 == 12.8 );
+ f1 = a1.fetch_sub(3.5, mo);
+ VERIFY( f1 == 4.96 );
+ VERIFY( a1 == 1.46 );
+
+ f0 = a0 += 1.2;
+ VERIFY( f0 == 14.0 );
+ VERIFY( a0 == 14.0 );
+
+ f0 = a0 -= 0.8;
+ VERIFY( f0 == 13.2 );
+ VERIFY( a0 == 13.2 );
+ }
+}
+
+void
+test03()
+{
+ const auto mo = std::memory_order_relaxed;
+ bool ok;
+ long double expected;
+
+ if constexpr (std::atomic<long double>::is_always_lock_free)
+ {
+ std::atomic<long double> a0;
+ std::atomic<long double> a1(1.0l);
+ ok = a0.is_lock_free();
+ a0 = a1.load();
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( a0.load(mo) == a0.load() );
+ a0.store(0.5l);
+ a1.store(0.5l, mo);
+ VERIFY( a0.load() == a1.load() );
+ auto f0 = a0.exchange(12.5l);
+ auto f1 = a1.exchange(12.5l, mo);
+ VERIFY( a0 == 12.5l );
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( f0 == 0.5l );
+ VERIFY( f0 == f1 );
+
+ expected = 12.5l;
+ while (!a0.compare_exchange_weak(expected, 1.6l, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == 1.6l );
+ VERIFY( expected == 12.5l );
+ expected = 1.5l;
+ ok = a1.compare_exchange_weak(expected, 1.6l, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5l && expected == 12.5l );
+ VERIFY( expected == 12.5l );
+ expected = 1.6l;
+ ok = a0.compare_exchange_strong(expected, 3.2l, mo, mo);
+ VERIFY( ok && a0.load() == 3.2l );
+ VERIFY( expected == 1.6l );
+ expected = 1.5l;
+ ok = a1.compare_exchange_strong(expected, 3.2l, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5l && expected == 12.5l );
+
+ expected = 3.2l;
+ while (!a0.compare_exchange_weak(expected, .64l))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == .64l );
+ expected = 12.5l;
+ while (!a1.compare_exchange_weak(expected, 1.6l, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a1.load() == 1.6l );
+ expected = 0.5l;
+ ok = a0.compare_exchange_weak(expected, 3.2l);
+ VERIFY( !ok && a0.load() == .64l && expected == .64l );
+ expected = 0.5l;
+ ok = a1.compare_exchange_weak(expected, 3.2l, mo);
+ VERIFY( !ok && a1.load() == 1.6l && expected == 1.6l );
+
+ expected = .64l;
+ ok = a0.compare_exchange_strong(expected, 12.8l);
+ VERIFY( ok && a0.load() == 12.8l );
+ expected = 1.6l;
+ ok = a1.compare_exchange_strong(expected, 2.56l, mo);
+ VERIFY( ok && a1.load() == 2.56l );
+ expected = 0.5l;
+ ok = a0.compare_exchange_strong(expected, 3.2l);
+ VERIFY( !ok && a0.load() == 12.8l && expected == 12.8l );
+ expected = 0.5l;
+ ok = a1.compare_exchange_strong(expected, 3.2l, mo);
+ VERIFY( !ok && a1.load() == 2.56l && expected == 2.56l );
+
+ f0 = a0.fetch_add(1.2l);
+ VERIFY( f0 == 12.8l );
+ VERIFY( a0 == 14.0l );
+ f1 = a1.fetch_add(2.4l, mo);
+ VERIFY( f1 == 2.56l );
+ VERIFY( a1 == 4.96l );
+
+ f0 = a0.fetch_sub(1.2l);
+ VERIFY( f0 == 14.0l );
+ VERIFY( a0 == 12.8l );
+ f1 = a1.fetch_sub(3.5l, mo);
+ VERIFY( f1 == 4.96l );
+ VERIFY( a1 == 1.46l );
+
+ f0 = a0 += 1.2l;
+ VERIFY( f0 == 14.0l );
+ VERIFY( a0 == 14.0l );
+
+ f0 = a0 -= 0.8l;
+ VERIFY( f0 == 13.2l );
+ VERIFY( a0 == 13.2l );
+ }
+
+ // Repeat for volatile std::atomic<long double>
+ if constexpr (std::atomic<long double>::is_always_lock_free)
+ {
+ volatile std::atomic<long double> a0;
+ volatile std::atomic<long double> a1(1.0l);
+ ok = a0.is_lock_free();
+ a0 = a1.load();
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( a0.load(mo) == a0.load() );
+ a0.store(0.5l);
+ a1.store(0.5l, mo);
+ VERIFY( a0.load() == a1.load() );
+ auto f0 = a0.exchange(12.5l);
+ auto f1 = a1.exchange(12.5l, mo);
+ VERIFY( a0 == 12.5l );
+ VERIFY( a0.load() == a1.load() );
+ VERIFY( f0 == 0.5l );
+ VERIFY( f0 == f1 );
+
+ expected = 12.5l;
+ while (!a0.compare_exchange_weak(expected, 1.6l, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == 1.6l );
+ VERIFY( expected == 12.5l );
+ expected = 1.5l;
+ ok = a1.compare_exchange_weak(expected, 1.6l, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5l && expected == 12.5l );
+ VERIFY( expected == 12.5l );
+ expected = 1.6l;
+ ok = a0.compare_exchange_strong(expected, 3.2l, mo, mo);
+ VERIFY( ok && a0.load() == 3.2l );
+ VERIFY( expected == 1.6l );
+ expected = 1.5l;
+ ok = a1.compare_exchange_strong(expected, 3.2l, mo, mo);
+ VERIFY( !ok && a1.load() == 12.5l && expected == 12.5l );
+
+ expected = 3.2l;
+ while (!a0.compare_exchange_weak(expected, .64l))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a0.load() == .64l );
+ expected = 12.5l;
+ while (!a1.compare_exchange_weak(expected, 1.6l, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a1.load() == 1.6l );
+ expected = 0.5l;
+ ok = a0.compare_exchange_weak(expected, 3.2l);
+ VERIFY( !ok && a0.load() == .64l && expected == .64l );
+ expected = 0.5l;
+ ok = a1.compare_exchange_weak(expected, 3.2l, mo);
+ VERIFY( !ok && a1.load() == 1.6l && expected == 1.6l );
+
+ expected = .64l;
+ ok = a0.compare_exchange_strong(expected, 12.8l);
+ VERIFY( ok && a0.load() == 12.8l );
+ expected = 1.6l;
+ ok = a1.compare_exchange_strong(expected, 2.56l, mo);
+ VERIFY( ok && a1.load() == 2.56l );
+ expected = 0.5l;
+ ok = a0.compare_exchange_strong(expected, 3.2l);
+ VERIFY( !ok && a0.load() == 12.8l && expected == 12.8l );
+ expected = 0.5l;
+ ok = a1.compare_exchange_strong(expected, 3.2l, mo);
+ VERIFY( !ok && a1.load() == 2.56l && expected == 2.56l );
+
+ f0 = a0.fetch_add(1.2l);
+ VERIFY( f0 == 12.8l );
+ VERIFY( a0 == 14.0l );
+ f1 = a1.fetch_add(2.4l, mo);
+ VERIFY( f1 == 2.56l );
+ VERIFY( a1 == 4.96l );
+
+ f0 = a0.fetch_sub(1.2l);
+ VERIFY( f0 == 14.0l );
+ VERIFY( a0 == 12.8l );
+ f1 = a1.fetch_sub(3.5l, mo);
+ VERIFY( f1 == 4.96l );
+ VERIFY( a1 == 1.46l );
+
+ f0 = a0 += 1.2l;
+ VERIFY( f0 == 14.0l );
+ VERIFY( a0 == 14.0l );
+
+ f0 = a0 -= 0.8l;
+ VERIFY( f0 == 13.2l );
+ VERIFY( a0 == 13.2l );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_float/requirements.cc b/libstdc++-v3/testsuite/29_atomics/atomic_float/requirements.cc
new file mode 100644
index 0000000..e52608c
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_float/requirements.cc
@@ -0,0 +1,69 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <atomic>
+
+void
+test01()
+{
+ using A = std::atomic<float>;
+ static_assert( std::is_standard_layout_v<A> );
+ static_assert( std::is_trivially_default_constructible_v<A> );
+ static_assert( std::is_trivially_destructible_v<A> );
+ static_assert( std::is_same_v<A::value_type, float> );
+ static_assert( std::is_same_v<A::difference_type, A::value_type> );
+ static_assert( !std::is_copy_constructible_v<A> );
+ static_assert( !std::is_move_constructible_v<A> );
+ static_assert( !std::is_copy_assignable_v<A> );
+ static_assert( !std::is_move_assignable_v<A> );
+ static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+
+void
+test02()
+{
+ using A = std::atomic<double>;
+ static_assert( std::is_standard_layout_v<A> );
+ static_assert( std::is_trivially_default_constructible_v<A> );
+ static_assert( std::is_trivially_destructible_v<A> );
+ static_assert( std::is_same_v<A::value_type, double> );
+ static_assert( std::is_same_v<A::difference_type, A::value_type> );
+ static_assert( !std::is_copy_constructible_v<A> );
+ static_assert( !std::is_move_constructible_v<A> );
+ static_assert( !std::is_copy_assignable_v<A> );
+ static_assert( !std::is_move_assignable_v<A> );
+ static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
+
+void
+test03()
+{
+ using A = std::atomic<long double>;
+ static_assert( std::is_standard_layout_v<A> );
+ static_assert( std::is_trivially_default_constructible_v<A> );
+ static_assert( std::is_trivially_destructible_v<A> );
+ static_assert( std::is_same_v<A::value_type, long double> );
+ static_assert( std::is_same_v<A::difference_type, A::value_type> );
+ static_assert( !std::is_copy_constructible_v<A> );
+ static_assert( !std::is_move_constructible_v<A> );
+ static_assert( !std::is_copy_assignable_v<A> );
+ static_assert( !std::is_move_assignable_v<A> );
+ static_assert( !std::is_assignable_v<volatile A&, const A&> );
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc
new file mode 100644
index 0000000..231901c
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/deduction.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <atomic>
+
+void
+test01()
+{
+ int i = 0;
+ std::atomic_ref a0(i);
+ static_assert(std::is_same_v<decltype(a0), std::atomic_ref<int>>);
+
+ float f = 1.0f;
+ std::atomic_ref a1(f);
+ static_assert(std::is_same_v<decltype(a1), std::atomic_ref<float>>);
+
+ int* p = &i;
+ std::atomic_ref a2(p);
+ static_assert(std::is_same_v<decltype(a2), std::atomic_ref<int*>>);
+
+ struct X { } x;
+ std::atomic_ref a3(x);
+ static_assert(std::is_same_v<decltype(a3), std::atomic_ref<X>>);
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/float.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/float.cc
new file mode 100644
index 0000000..0633f28
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/float.cc
@@ -0,0 +1,320 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ float value;
+ if constexpr (std::atomic_ref<float>::is_always_lock_free)
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<float> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<float>::is_always_lock_free)
+ VERIFY( ok );
+ a = 1.6f;
+ VERIFY( a.load() == 1.6f );
+ a.store(0.8f);
+ VERIFY( a.load(mo) == 0.8f );
+ a.store(3.2f, mo);
+ VERIFY( a.load() == 3.2f );
+ auto v = a.exchange(6.4f);
+ VERIFY( a == 6.4f );
+ VERIFY( v == 3.2f );
+ v = a.exchange(1.28f, mo);
+ VERIFY( a == 1.28f );
+ VERIFY( v == 6.4f );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, 25.6f, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 25.6f );
+ VERIFY( expected == 1.28f );
+ expected = 3.2f;
+ ok = a.compare_exchange_weak(expected, 51.2f, mo, mo);
+ VERIFY( !ok && a.load() == 25.6f && expected == 25.6f );
+ ok = a.compare_exchange_strong(expected, 51.2f, mo, mo);
+ VERIFY( ok && a.load() == 51.2f && expected == 25.6f );
+ expected = 0.0f;
+ ok = a.compare_exchange_strong(expected, 1.28f, mo, mo);
+ VERIFY( !ok && a.load() == 51.2f && expected == 51.2f );
+
+ while (!a.compare_exchange_weak(expected, 25.6f))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 25.6f && expected == 51.2f );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, 10.24f, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 10.24f && expected == 25.6f );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 40.96f);
+ VERIFY( !ok && a.load() == 10.24f && expected == 10.24f );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 40.96f, mo);
+ VERIFY( !ok && a.load() == 10.24f && expected == 10.24f );
+
+ ok = a.compare_exchange_strong(expected, 1.024f);
+ VERIFY( ok && a.load() == 1.024f && expected == 10.24f );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, 204.8f, mo);
+ VERIFY( ok && a.load() == 204.8f && expected == 1.024f );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 6.4f);
+ VERIFY( !ok && a.load() == 204.8f && expected == 204.8f );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 6.4f, mo);
+ VERIFY( !ok && a.load() == 204.8f && expected == 204.8f );
+
+ v = a.fetch_add(3.2f);
+ VERIFY( v == 204.8f );
+ VERIFY( a == 208.0f );
+ v = a.fetch_add(-8.5f, mo);
+ VERIFY( v == 208.0f );
+ VERIFY( a == 199.5f );
+
+ v = a.fetch_sub(109.5f);
+ VERIFY( v == 199.5f );
+ VERIFY( a == 90.0f );
+ v = a.fetch_sub(2, mo);
+ VERIFY( v == 90.0f );
+ VERIFY( a == 88.0f );
+
+ v = a += 5.0f;
+ VERIFY( v == 93.0f );
+ VERIFY( a == 93.0f );
+
+ v = a -= 6.5f;
+ VERIFY( v == 86.5f );
+ VERIFY( a == 86.5f );
+ }
+
+ if constexpr (std::atomic_ref<float>::is_always_lock_free)
+ VERIFY( value == 86.5f );
+}
+
+void
+test02()
+{
+ double value;
+ if constexpr (std::atomic_ref<double>::is_always_lock_free)
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<double> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<double>::is_always_lock_free)
+ VERIFY( ok );
+ a = 1.6;
+ VERIFY( a.load() == 1.6 );
+ a.store(0.8);
+ VERIFY( a.load(mo) == 0.8 );
+ a.store(3.2, mo);
+ VERIFY( a.load() == 3.2 );
+ auto v = a.exchange(6.4);
+ VERIFY( a == 6.4 );
+ VERIFY( v == 3.2 );
+ v = a.exchange(1.28, mo);
+ VERIFY( a == 1.28 );
+ VERIFY( v == 6.4 );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, 25.6, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 25.6 );
+ VERIFY( expected == 1.28 );
+ expected = 3.2;
+ ok = a.compare_exchange_weak(expected, 51.2, mo, mo);
+ VERIFY( !ok && a.load() == 25.6 && expected == 25.6 );
+ ok = a.compare_exchange_strong(expected, 51.2, mo, mo);
+ VERIFY( ok && a.load() == 51.2 && expected == 25.6 );
+ expected = 0.0;
+ ok = a.compare_exchange_strong(expected, 1.28, mo, mo);
+ VERIFY( !ok && a.load() == 51.2 && expected == 51.2 );
+
+ while (!a.compare_exchange_weak(expected, 25.6))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 25.6 && expected == 51.2 );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, 10.24, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 10.24 && expected == 25.6 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 40.96);
+ VERIFY( !ok && a.load() == 10.24 && expected == 10.24 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 40.96, mo);
+ VERIFY( !ok && a.load() == 10.24 && expected == 10.24 );
+
+ ok = a.compare_exchange_strong(expected, 1.024);
+ VERIFY( ok && a.load() == 1.024 && expected == 10.24 );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, 204.8, mo);
+ VERIFY( ok && a.load() == 204.8 && expected == 1.024 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 6.4);
+ VERIFY( !ok && a.load() == 204.8 && expected == 204.8 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 6.4, mo);
+ VERIFY( !ok && a.load() == 204.8 && expected == 204.8 );
+
+ v = a.fetch_add(3.2);
+ VERIFY( v == 204.8 );
+ VERIFY( a == 208.0 );
+ v = a.fetch_add(-8.5, mo);
+ VERIFY( v == 208.0 );
+ VERIFY( a == 199.5 );
+
+ v = a.fetch_sub(109.5);
+ VERIFY( v == 199.5 );
+ VERIFY( a == 90.0 );
+ v = a.fetch_sub(2, mo);
+ VERIFY( v == 90.0 );
+ VERIFY( a == 88.0 );
+
+ v = a += 5.0;
+ VERIFY( v == 93.0 );
+ VERIFY( a == 93.0 );
+
+ v = a -= 6.5;
+ VERIFY( v == 86.5 );
+ VERIFY( a == 86.5 );
+ }
+
+ if constexpr (std::atomic_ref<double>::is_always_lock_free)
+ VERIFY( value == 86.5 );
+}
+
+void
+test03()
+{
+ long double value;
+ if constexpr (std::atomic_ref<long double>::is_always_lock_free)
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<long double> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<long double>::is_always_lock_free)
+ VERIFY( ok );
+ a = 1.6l;
+ VERIFY( a.load() == 1.6l );
+ a.store(0.8l);
+ VERIFY( a.load(mo) == 0.8l );
+ a.store(3.2l, mo);
+ VERIFY( a.load() == 3.2l );
+ auto v = a.exchange(6.4l);
+ VERIFY( a == 6.4l );
+ VERIFY( v == 3.2l );
+ v = a.exchange(1.28l, mo);
+ VERIFY( a == 1.28l );
+ VERIFY( v == 6.4l );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, 25.6l, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 25.6l );
+ VERIFY( expected == 1.28l );
+ expected = 3.2l;
+ ok = a.compare_exchange_weak(expected, 51.2l, mo, mo);
+ VERIFY( !ok && a.load() == 25.6l && expected == 25.6l );
+ ok = a.compare_exchange_strong(expected, 51.2l, mo, mo);
+ VERIFY( ok && a.load() == 51.2l && expected == 25.6l );
+ expected = 0.0l;
+ ok = a.compare_exchange_strong(expected, 1.28l, mo, mo);
+ VERIFY( !ok && a.load() == 51.2l && expected == 51.2l );
+
+ while (!a.compare_exchange_weak(expected, 25.6l))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 25.6l && expected == 51.2l );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, 10.24l, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 10.24l && expected == 25.6l );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 40.96l);
+ VERIFY( !ok && a.load() == 10.24l && expected == 10.24l );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 40.96l, mo);
+ VERIFY( !ok && a.load() == 10.24l && expected == 10.24l );
+
+ ok = a.compare_exchange_strong(expected, 1.024l);
+ VERIFY( ok && a.load() == 1.024l && expected == 10.24l );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, 204.8l, mo);
+ VERIFY( ok && a.load() == 204.8l && expected == 1.024l );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 6.4l);
+ VERIFY( !ok && a.load() == 204.8l && expected == 204.8l );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 6.4l, mo);
+ VERIFY( !ok && a.load() == 204.8l && expected == 204.8l );
+
+ v = a.fetch_add(3.2l);
+ VERIFY( v == 204.8l );
+ VERIFY( a == 208.0l );
+ v = a.fetch_add(-8.5l, mo);
+ VERIFY( v == 208.0l );
+ VERIFY( a == 199.5l );
+
+ v = a.fetch_sub(109.5l);
+ VERIFY( v == 199.5l );
+ VERIFY( a == 90.0l );
+ v = a.fetch_sub(2, mo);
+ VERIFY( v == 90.0l );
+ VERIFY( a == 88.0l );
+
+ v = a += 5.0l;
+ VERIFY( v == 93.0l );
+ VERIFY( a == 93.0l );
+
+ v = a -= 6.5l;
+ VERIFY( v == 86.5l );
+ VERIFY( a == 86.5l );
+ }
+
+ if constexpr (std::atomic_ref<long double>::is_always_lock_free)
+ VERIFY( value == 86.5l );
+}
+
+void
+test04()
+{
+ if constexpr (std::atomic_ref<float>::is_always_lock_free)
+ {
+ float i = 0;
+ float* ptr = 0;
+ std::atomic_ref<float*> a0(ptr);
+ std::atomic_ref<float*> a1(ptr);
+ std::atomic_ref<float*> a2(a0);
+ a0 = &i;
+ VERIFY( a1 == &i );
+ VERIFY( a2 == &i );
+ }
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/generic.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/generic.cc
new file mode 100644
index 0000000..61ae61b
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/generic.cc
@@ -0,0 +1,122 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-add-options libatomic }
+
+#include <atomic>
+#include <limits.h>
+#include <testsuite_hooks.h>
+
+struct X
+{
+ X() = default;
+ X(int i) : i(i) { }
+ bool operator==(int rhs) const { return i == rhs; }
+ int i;
+};
+
+void
+test01()
+{
+ X value;
+
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<X> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<X>::is_always_lock_free)
+ VERIFY( ok );
+ a = X{};
+ VERIFY( a.load() == 0 );
+ VERIFY( a.load(mo) == 0 );
+ a.store(1);
+ VERIFY( a.load() == 1 );
+ auto v = a.exchange(2);
+ VERIFY( a.load() == 2 );
+ VERIFY( v == 1 );
+ v = a.exchange(3, mo);
+ VERIFY( a.load() == 3 );
+ VERIFY( v == 2 );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, 4, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 4 );
+ VERIFY( expected == 3 );
+ expected = 1;
+ ok = a.compare_exchange_weak(expected, 5, mo, mo);
+ VERIFY( !ok && a.load() == 4 && expected == 4 );
+ ok = a.compare_exchange_strong(expected, 5, mo, mo);
+ VERIFY( ok && a.load() == 5 && expected == 4 );
+ expected = 0;
+ ok = a.compare_exchange_strong(expected, 3, mo, mo);
+ VERIFY( !ok && a.load() == 5 && expected == 5 );
+
+ while (!a.compare_exchange_weak(expected, 4))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 4 && expected == 5 );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, 6, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 6 && expected == 4 );
+ expected = a.load();
+ expected.i += 1;
+ ok = a.compare_exchange_weak(expected, -8);
+ VERIFY( !ok && a.load() == 6 && expected == 6 );
+ expected = a.load();
+ expected.i += 1;
+ ok = a.compare_exchange_weak(expected, 8, mo);
+ VERIFY( !ok && a.load() == 6 && expected == 6 );
+
+ ok = a.compare_exchange_strong(expected, -6);
+ VERIFY( ok && a.load() == -6 && expected == 6 );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, 7, mo);
+ VERIFY( ok && a.load() == 7 && expected == -6 );
+ expected = a.load();
+ expected.i += 1;
+ ok = a.compare_exchange_strong(expected, 2);
+ VERIFY( !ok && a.load() == 7 && expected == 7 );
+ expected = a.load();
+ expected.i += 1;
+ ok = a.compare_exchange_strong(expected, 2, mo);
+ VERIFY( !ok && a.load() == 7 && expected == 7 );
+ }
+
+ VERIFY( value == 7 );
+}
+
+void
+test02()
+{
+ X i;
+ std::atomic_ref<X> a0(i);
+ std::atomic_ref<X> a1(i);
+ std::atomic_ref<X> a2(a0);
+ a0 = 42;
+ VERIFY( a1.load() == 42 );
+ VERIFY( a2.load() == 42 );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/integral.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/integral.cc
new file mode 100644
index 0000000..4b5b4d1
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/integral.cc
@@ -0,0 +1,331 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-add-options libatomic }
+
+#include <atomic>
+#include <limits.h>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ int value;
+
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<int> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<int>::is_always_lock_free)
+ VERIFY( ok );
+ a = 0;
+ VERIFY( a.load() == 0 );
+ VERIFY( a.load(mo) == 0 );
+ a.store(1);
+ VERIFY( a.load() == 1 );
+ auto v = a.exchange(2);
+ VERIFY( a == 2 );
+ VERIFY( v == 1 );
+ v = a.exchange(3, mo);
+ VERIFY( a == 3 );
+ VERIFY( v == 2 );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, 4, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 4 );
+ VERIFY( expected == 3 );
+ expected = 1;
+ ok = a.compare_exchange_weak(expected, 5, mo, mo);
+ VERIFY( !ok && a.load() == 4 && expected == 4 );
+ ok = a.compare_exchange_strong(expected, 5, mo, mo);
+ VERIFY( ok && a.load() == 5 && expected == 4 );
+ expected = 0;
+ ok = a.compare_exchange_strong(expected, 3, mo, mo);
+ VERIFY( !ok && a.load() == 5 && expected == 5 );
+
+ while (!a.compare_exchange_weak(expected, 4))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 4 && expected == 5 );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, 6, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 6 && expected == 4 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, -8);
+ VERIFY( !ok && a.load() == 6 && expected == 6 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 8, mo);
+ VERIFY( !ok && a.load() == 6 && expected == 6 );
+
+ ok = a.compare_exchange_strong(expected, -6);
+ VERIFY( ok && a.load() == -6 && expected == 6 );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, 7, mo);
+ VERIFY( ok && a.load() == 7 && expected == -6 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 2);
+ VERIFY( !ok && a.load() == 7 && expected == 7 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 2, mo);
+ VERIFY( !ok && a.load() == 7 && expected == 7 );
+
+ v = a.fetch_add(2);
+ VERIFY( v == 7 );
+ VERIFY( a == 9 );
+ v = a.fetch_add(-30, mo);
+ VERIFY( v == 9 );
+ VERIFY( a == -21 );
+
+ v = a.fetch_sub(3);
+ VERIFY( v == -21 );
+ VERIFY( a == -24 );
+ v = a.fetch_sub(-41, mo);
+ VERIFY( v == -24 );
+ VERIFY( a == 17 );
+
+ v = a.fetch_and(0x101);
+ VERIFY( v == 17 );
+ VERIFY( a == 1 );
+ a = 0x17;
+ v = a.fetch_and(0x23, mo);
+ VERIFY( v == 0x17 );
+ VERIFY( a == 3 );
+
+ v = a.fetch_or(0x101);
+ VERIFY( v == 3 );
+ VERIFY( a == 0x103 );
+ v = a.fetch_or(0x23, mo);
+ VERIFY( v == 0x103 );
+ VERIFY( a == 0x123 );
+
+ v = a.fetch_xor(0x101);
+ VERIFY( v == 0x123 );
+ VERIFY( a == 0x022 );
+ v = a.fetch_xor(0x123, mo);
+ VERIFY( v == 0x022 );
+ VERIFY( a == 0x101 );
+
+ v = a++;
+ VERIFY( v == 0x101 );
+ VERIFY( a == 0x102 );
+ v = a--;
+ VERIFY( v == 0x102 );
+ VERIFY( a == 0x101 );
+ v = ++a;
+ VERIFY( v == 0x102 );
+ VERIFY( a == 0x102 );
+ v = --a;
+ VERIFY( v == 0x101 );
+ VERIFY( a == 0x101 );
+
+ v = a += -10;
+ VERIFY( v == 247 );
+ VERIFY( a == 247 );
+
+ v = a -= 250;
+ VERIFY( v == -3 );
+ VERIFY( a == -3 );
+
+ a = 0x17;
+ v = a &= 0x102;
+ VERIFY( v == 2 );
+ VERIFY( a == 2 );
+
+ v = a |= 0x101;
+ VERIFY( v == 0x103 );
+ VERIFY( a == 0x103 );
+
+ v = a ^= 0x121;
+ VERIFY( v == 0x022 );
+ VERIFY( a == 0x022 );
+ }
+
+ VERIFY( value == 0x022 );
+}
+
+void
+test02()
+{
+ unsigned short value;
+
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<unsigned short> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<unsigned short>::is_always_lock_free)
+ VERIFY( ok );
+ a = 0;
+ VERIFY( a.load() == 0 );
+ VERIFY( a.load(mo) == 0 );
+ a.store(1);
+ VERIFY( a.load() == 1 );
+ auto v = a.exchange(2);
+ VERIFY( a == 2 );
+ VERIFY( v == 1 );
+ v = a.exchange(3, mo);
+ VERIFY( a == 3 );
+ VERIFY( v == 2 );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, 4, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 4 );
+ VERIFY( expected == 3 );
+ expected = 1;
+ ok = a.compare_exchange_weak(expected, 5, mo, mo);
+ VERIFY( !ok && a.load() == 4 && expected == 4 );
+ ok = a.compare_exchange_strong(expected, 5, mo, mo);
+ VERIFY( ok && a.load() == 5 && expected == 4 );
+ expected = 0;
+ ok = a.compare_exchange_strong(expected, 3, mo, mo);
+ VERIFY( !ok && a.load() == 5 && expected == 5 );
+
+ while (!a.compare_exchange_weak(expected, 4))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 4 && expected == 5 );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, 6, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == 6 && expected == 4 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, -8);
+ VERIFY( !ok && a.load() == 6 && expected == 6 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, 8, mo);
+ VERIFY( !ok && a.load() == 6 && expected == 6 );
+
+ ok = a.compare_exchange_strong(expected, -6);
+ VERIFY( ok && a.load() == (unsigned short)-6 && expected == 6 );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, 7, mo);
+ VERIFY( ok && a.load() == 7 && expected == (unsigned short)-6 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 2);
+ VERIFY( !ok && a.load() == 7 && expected == 7 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, 2, mo);
+ VERIFY( !ok && a.load() == 7 && expected == 7 );
+
+ v = a.fetch_add(2);
+ VERIFY( v == 7 );
+ VERIFY( a == 9 );
+ v = a.fetch_add(-30, mo);
+ VERIFY( v == 9 );
+ VERIFY( a == (unsigned short)-21 );
+
+ v = a.fetch_sub(3);
+ VERIFY( v == (unsigned short)-21 );
+ VERIFY( a == (unsigned short)-24 );
+ v = a.fetch_sub((unsigned short)-41, mo);
+ VERIFY( v == (unsigned short)-24 );
+ VERIFY( a == 17 );
+
+ v = a.fetch_and(0x21);
+ VERIFY( v == 17 );
+ VERIFY( a == 1 );
+ a = 0x17;
+ v = a.fetch_and(0x23, mo);
+ VERIFY( v == 0x17 );
+ VERIFY( a == 3 );
+
+ v = a.fetch_or(0x21);
+ VERIFY( v == 3 );
+ VERIFY( a == 0x23 );
+ v = a.fetch_or(0x44, mo);
+ VERIFY( v == 0x23 );
+ VERIFY( a == 0x67 );
+
+ v = a.fetch_xor(0x21);
+ VERIFY( v == 0x67 );
+ VERIFY( a == 0x46 );
+ v = a.fetch_xor(0x12, mo);
+ VERIFY( v == 0x46 );
+ VERIFY( a == 0x54 );
+
+ v = a++;
+ VERIFY( v == 0x54 );
+ VERIFY( a == 0x55 );
+ v = a--;
+ VERIFY( v == 0x55 );
+ VERIFY( a == 0x54 );
+ v = ++a;
+ VERIFY( v == 0x55 );
+ VERIFY( a == 0x55 );
+ v = --a;
+ VERIFY( v == 0x54 );
+ VERIFY( a == 0x54 );
+
+ v = a += -10;
+ VERIFY( v == 0x4a );
+ VERIFY( a == 0x4a );
+
+ v = a -= 15;
+ VERIFY( v == 0x3b );
+ VERIFY( a == 0x3b );
+
+ a = 0x17;
+ v = a &= 0x12;
+ VERIFY( v == 0x12 );
+ VERIFY( a == 0x12 );
+
+ v = a |= 0x34;
+ VERIFY( v == 0x36 );
+ VERIFY( a == 0x36 );
+
+ v = a ^= 0x12;
+ VERIFY( v == 0x24 );
+ VERIFY( a == 0x24 );
+ }
+
+ VERIFY( value == 0x24 );
+}
+void
+test03()
+{
+ int i = 0;
+ std::atomic_ref<int> a0(i);
+ std::atomic_ref<int> a1(i);
+ std::atomic_ref<int> a2(a0);
+ a0 = 42;
+ VERIFY( a1 == 42 );
+ VERIFY( a2 == 42 );
+}
+
+void
+test04()
+{
+ int i = INT_MIN;
+ std::atomic_ref<int> a(i);
+ --a;
+ VERIFY( a == INT_MAX );
+ ++a;
+ VERIFY( a == INT_MIN );
+ a |= INT_MAX;
+ VERIFY( a == -1 );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+ test04();
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/pointer.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/pointer.cc
new file mode 100644
index 0000000..d5256d6
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/pointer.cc
@@ -0,0 +1,225 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+// { dg-add-options libatomic }
+
+#include <atomic>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ long arr[10] = { };
+ long* value;
+
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<long*> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<long*>::is_always_lock_free)
+ VERIFY( ok );
+ a = arr;
+ VERIFY( a.load() == arr );
+ VERIFY( a.load(mo) == arr );
+ a.store(arr+1);
+ VERIFY( a.load() == arr+1 );
+ auto v = a.exchange(arr+2);
+ VERIFY( a == arr+2 );
+ VERIFY( v == arr+1 );
+ v = a.exchange(arr+3, mo);
+ VERIFY( a == arr+3 );
+ VERIFY( v == arr+2 );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, arr+4, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == arr+4 );
+ VERIFY( expected == arr+3 );
+ expected = arr+1;
+ ok = a.compare_exchange_weak(expected, arr+5, mo, mo);
+ VERIFY( !ok && a.load() == arr+4 && expected == arr+4 );
+ ok = a.compare_exchange_strong(expected, arr+5, mo, mo);
+ VERIFY( ok && a.load() == arr+5 && expected == arr+4 );
+ expected = nullptr;
+ ok = a.compare_exchange_strong(expected, arr+3, mo, mo);
+ VERIFY( !ok && a.load() == arr+5 && expected == arr+5 );
+
+ while (!a.compare_exchange_weak(expected, arr+4))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == arr+4 && expected == arr+5 );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, arr+6, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == arr+6 && expected == arr+4 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, arr+8);
+ VERIFY( !ok && a.load() == arr+6 && expected == arr+6 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, arr+8, mo);
+ VERIFY( !ok && a.load() == arr+6 && expected == arr+6 );
+
+ ok = a.compare_exchange_strong(expected, arr+5);
+ VERIFY( ok && a.load() == arr+5 && expected == arr+6 );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, arr+7, mo);
+ VERIFY( ok && a.load() == arr+7 && expected == arr+5 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, arr+2);
+ VERIFY( !ok && a.load() == arr+7 && expected == arr+7 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, arr+2, mo);
+ VERIFY( !ok && a.load() == arr+7 && expected == arr+7 );
+
+ v = a.fetch_add(2);
+ VERIFY( v == arr+7 );
+ VERIFY( a == arr+9 );
+ v = a.fetch_add(-3, mo);
+ VERIFY( v == arr+9 );
+ VERIFY( a == arr+6 );
+
+ v = a.fetch_sub(3);
+ VERIFY( v == arr+6 );
+ VERIFY( a == arr+3 );
+ v = a.fetch_sub(2, mo);
+ VERIFY( v == arr+3 );
+ VERIFY( a == arr+1 );
+
+ v = a += 5;
+ VERIFY( v == arr+6 );
+ VERIFY( a == arr+6 );
+
+ v = a -= 5;
+ VERIFY( v == arr+1 );
+ VERIFY( a == arr+1 );
+ }
+
+ VERIFY( value == arr+1 );
+}
+
+void
+test02()
+{
+ char arr[10] = { };
+ char* value;
+
+ {
+ const auto mo = std::memory_order_relaxed;
+ std::atomic_ref<char*> a(value);
+ bool ok = a.is_lock_free();
+ if constexpr (std::atomic_ref<char*>::is_always_lock_free)
+ VERIFY( ok );
+ a = arr;
+ VERIFY( a.load() == arr );
+ a.store(arr+3);
+ VERIFY( a.load(mo) == arr+3 );
+ a.store(arr+1, mo);
+ VERIFY( a.load() == arr+1 );
+ auto v = a.exchange(arr+2);
+ VERIFY( a == arr+2 );
+ VERIFY( v == arr+1 );
+ v = a.exchange(arr+3, mo);
+ VERIFY( a == arr+3 );
+ VERIFY( v == arr+2 );
+
+ auto expected = a.load();
+ while (!a.compare_exchange_weak(expected, arr+4, mo, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == arr+4 );
+ VERIFY( expected == arr+3 );
+ expected = arr+1;
+ ok = a.compare_exchange_weak(expected, arr+5, mo, mo);
+ VERIFY( !ok && a.load() == arr+4 && expected == arr+4 );
+ ok = a.compare_exchange_strong(expected, arr+5, mo, mo);
+ VERIFY( ok && a.load() == arr+5 && expected == arr+4 );
+ expected = nullptr;
+ ok = a.compare_exchange_strong(expected, arr+3, mo, mo);
+ VERIFY( !ok && a.load() == arr+5 && expected == arr+5 );
+
+ while (!a.compare_exchange_weak(expected, arr+4))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == arr+4 && expected == arr+5 );
+ expected = a.load();
+ while (!a.compare_exchange_weak(expected, arr+6, mo))
+ { /* weak form can fail spuriously */ }
+ VERIFY( a.load() == arr+6 && expected == arr+4 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, arr+8);
+ VERIFY( !ok && a.load() == arr+6 && expected == arr+6 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_weak(expected, arr+8, mo);
+ VERIFY( !ok && a.load() == arr+6 && expected == arr+6 );
+
+ ok = a.compare_exchange_strong(expected, arr+5);
+ VERIFY( ok && a.load() == arr+5 && expected == arr+6 );
+ expected = a.load();
+ ok = a.compare_exchange_strong(expected, arr+7, mo);
+ VERIFY( ok && a.load() == arr+7 && expected == arr+5 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, arr+2);
+ VERIFY( !ok && a.load() == arr+7 && expected == arr+7 );
+ expected = a.load() + 1;
+ ok = a.compare_exchange_strong(expected, arr+2, mo);
+ VERIFY( !ok && a.load() == arr+7 && expected == arr+7 );
+
+ v = a.fetch_add(2);
+ VERIFY( v == arr+7 );
+ VERIFY( a == arr+9 );
+ v = a.fetch_add(-3, mo);
+ VERIFY( v == arr+9 );
+ VERIFY( a == arr+6 );
+
+ v = a.fetch_sub(3);
+ VERIFY( v == arr+6 );
+ VERIFY( a == arr+3 );
+ v = a.fetch_sub(2, mo);
+ VERIFY( v == arr+3 );
+ VERIFY( a == arr+1 );
+
+ v = a += 5;
+ VERIFY( v == arr+6 );
+ VERIFY( a == arr+6 );
+
+ v = a -= 5;
+ VERIFY( v == arr+1 );
+ VERIFY( a == arr+1 );
+ }
+
+ VERIFY( value == arr+1 );
+}
+
+void
+test03()
+{
+ int i = 0;
+ int* ptr = 0;
+ std::atomic_ref<int*> a0(ptr);
+ std::atomic_ref<int*> a1(ptr);
+ std::atomic_ref<int*> a2(a0);
+ a0 = &i;
+ VERIFY( a1 == &i );
+ VERIFY( a2 == &i );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic_ref/requirements.cc b/libstdc++-v3/testsuite/29_atomics/atomic_ref/requirements.cc
new file mode 100644
index 0000000..a3fd450
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic_ref/requirements.cc
@@ -0,0 +1,74 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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.
+
+// This library 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 this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <atomic>
+
+void
+test01()
+{
+ struct X { int c; };
+ using A = std::atomic_ref<X>;
+ static_assert( std::is_standard_layout_v<A> );
+ static_assert( std::is_nothrow_copy_constructible_v<A> );
+ static_assert( std::is_trivially_destructible_v<A> );
+ static_assert( std::is_same_v<A::value_type, X> );
+ static_assert( !std::is_copy_assignable_v<A> );
+ static_assert( !std::is_move_assignable_v<A> );
+}
+
+void
+test02()
+{
+ using A = std::atomic_ref<int>;
+ static_assert( std::is_standard_layout_v<A> );
+ static_assert( std::is_nothrow_copy_constructible_v<A> );
+ static_assert( std::is_trivially_destructible_v<A> );
+ static_assert( std::is_same_v<A::value_type, int> );
+ static_assert( std::is_same_v<A::difference_type, A::value_type> );
+ static_assert( !std::is_copy_assignable_v<A> );
+ static_assert( !std::is_move_assignable_v<A> );
+}
+
+void
+test03()
+{
+ using A = std::atomic_ref<double>;
+ static_assert( std::is_standard_layout_v<A> );
+ static_assert( std::is_nothrow_copy_constructible_v<A> );
+ static_assert( std::is_trivially_destructible_v<A> );
+ static_assert( std::is_same_v<A::value_type, double> );
+ static_assert( std::is_same_v<A::difference_type, A::value_type> );
+ static_assert( !std::is_copy_assignable_v<A> );
+ static_assert( !std::is_move_assignable_v<A> );
+}
+
+void
+test04()
+{
+ using A = std::atomic_ref<int*>;
+ static_assert( std::is_standard_layout_v<A> );
+ static_assert( std::is_nothrow_copy_constructible_v<A> );
+ static_assert( std::is_trivially_destructible_v<A> );
+ static_assert( std::is_same_v<A::value_type, int*> );
+ static_assert( std::is_same_v<A::difference_type, std::ptrdiff_t> );
+ static_assert( std::is_nothrow_copy_constructible_v<A> );
+ static_assert( !std::is_copy_assignable_v<A> );
+ static_assert( !std::is_move_assignable_v<A> );
+}